C#-读取测序数据的ABI文件并绘制svg格式峰图

本地环境:win10,visual studio 2022 community


目录

  • 前言
  • 问题描述
  • 实现效果
  • 解决思路
  • 实现要点
    • ABI文件的组织方式
    • svg绘制问题
      • 变色碱基值
    • 动态设置svg图像宽度

前言

本文是在已有的代码基础上进行的开发,前期已经实现:

  1. ABI文件的解析
  2. 峰图的简单绘制
  3. svg绘图
  4. svg图像导出

对于1,主要用到之前重写的struct包,另外加一些适应ABI格式的修改,c#重写的struct参见:
c#-用c#重写python的struct包-简化版_c# struct pack-CSDN博客
https://blog.csdn.net/pxy7896/article/details/120055568

对于2,之前也写过一个很粗糙的python版,没什么用,后面会着重写绘制思路:
python-读取abi文件并绘制峰图_python abi如何获取-CSDN博客
https://blog.csdn.net/pxy7896/article/details/120562689

对于3和4,参考:
SVG 教程 | 菜鸟教程
https://www.runoob.com/svg/svg-tutorial.html
Blazor入门-简单svg绘制+导出图像_blazor 画图-CSDN博客
https://blog.csdn.net/pxy7896/article/details/139003443

问题描述

在生物学和测序领域中,ABI文件(ABI format)通常指的是Applied Biosystems(ABI)公司开发的测序数据文件格式,通常的文件扩展名为.ab1。这是一种用于存储DNA序列或蛋白质序列测序结果的标准格式。

ABI文件包含了测序仪器产生的原始测序数据,包括碱基序列、测序质量值、电泳图谱等信息。这些数据对于进行基因组测序、DNA序列分析以及生物信息学研究非常重要。通常,科研人员会使用特定的软件或工具来处理和分析ABI文件,以获取目标DNA或蛋白质序列的信息。

(以上来自AI问答)

我现在接到的任务就是开发一个可以解析abi文件后绘制峰图的小工具。绘制效果应如下图所示:(其中,字体、字号、颜色、间距、峰的宽度和高度等可以定制)
在这里插入图片描述
此外,还有如下要求:

  1. 上方箭头处是目标点,这个位置是由客户指定的,此处需要绘制一个向下的箭头;
  2. 不需要展示全部序列,只需要截取目标点周围的一段序列,因此序列的start和end也是由客户指定的。

实现效果

只截取了一部分,如下图所示:
在这里插入图片描述
如果想更像上面的图,那对于比较“矮”的点可以用更小的缩放系数。目前我用的是同一个缩放系数,因为客户要的精度不高。

解决思路

目前我是用blazor写的,所以可以分为三个部分:

  1. 前台获取目标点数值和上传.ab1文件,传递给后台解析数据和计算路径,然后回传结果并在前台显示出来
  2. 解析ABI格式。这里需要了解这种文件的组织方式,以及byte到字符串、数值的转化方法
  3. 计算路径。这里计算的是<svg>对象中各种子对象的路径数值,比如<path>d<text>xy

这里我们先从最终结果入手,思考:如果我们要画出这样的图,需要哪些信息?

我是这样拆解的:

  1. 顶端的彩色字符序列:这个可以用<text>实现,需要计算xy相对来说是固定的,给一个固定值即可)。对于x,它应该是每个波峰顶点的横坐标再减去字符宽度的一半,这样才能保持居中。

  2. 一个红色的指示箭头:这个可以用<path>实现,需要计算d。因为是箭头,只需要计算箭头的几个顶点,用简单的直线(Line,L)首尾连接即可。我这里用的方法是先确认顶边中心的坐标,然后按逆时针方向计算其他的点,连接起来。如下图所示:
    在这里插入图片描述

  3. 四条彩色曲线,代表不同碱基的测序数值。这个可以用Line或者贝塞尔曲线实现,也是要计算d

    我本来是考虑用贝塞尔曲线的,因为波峰的值很好取得(后面解析ABI文件会说),那么我可以将每个波峰的值看作Q点,Q和baseline的中点看作M点,如下图所示:
    在这里插入图片描述

    那么整个曲线的d属性的格式就是:M 起点x 起点y Q Qx0 Qy0 Mx0 My0 Qx1 Qy2 Mx1 My1…比如

    <path d="M 40 100 Q 50 52 60 100 Q 70 50 80 100 Q 90 20 100 100" fill="none" stroke="blue" />
    

    绘制的效果是:
    在这里插入图片描述
    但是我很快发现这样不行。。因为就算我在波峰两侧多取了两个样点,画出来的图还是假假的。。实验部门说不行,看起来太假了,像是这样:
    在这里插入图片描述
    幸运的是,我发现客户要求的范围其实相当窄,所以完全可以不取样,就用原始数据画,所以最终选择了用直线L,连接所有数据点。

实现要点

ABI文件的组织方式

参见:
https://projects.nfstc.org/workshops/resources/articles/ABIF_File_Format.pdf

只要用我之前写过的struct包解析,注意对应的tag就没啥问题。这里不再展开。

svg绘制问题

变色碱基值

这个比较简单,给前端传递对象时,带一个List<Ab1Char>,这个Ab1Char包含字符和x坐标,在前端循环时,根据字符判断颜色:

@foreach (Ab1Char a in ab1.xxx)
{@if (a.ch == "A") {color = "green";}...// 一些判断
}<g><text x="@a.x" y="30" fill="@color">@a.ch</text>
</g>

动态设置svg图像宽度

这个问题主要出现在导出svg图像时,发现图像右侧有一些空白:
在这里插入图片描述
造成这个现象的原因是,我的<path>啥的都是放在一个白色的<rect>上面的(为了实现白底效果),所以,需要动态地设置<rect><svg>的宽度,或者在导出图像时,将一个宽度变量传入函数。

目前我的解法是在计算<path>的d属性时,同步计算最大宽度值,这个值是要带给前端的,在导出操作时也要带这个值,并且修改导出图像的js函数:

export function exportSvgToImage2(svgElement, format, width) {if (format == null)return;var svgXml = new XMLSerializer().serializeToString(svgElement);var utf8 = unescape(encodeURIComponent(svgXml));var imageUrl = "data:image/svg+xml;base64," + btoa(utf8);var canvas = document.createElement("canvas");canvas.width = width; // 修改这一句,不再用clientWidth,改用指定值canvas.height = svgElement.clientHeight;var ctx = canvas.getContext("2d");var img = new Image();img.onload = function () {ctx.drawImage(img, 0, 0);var a = document.createElement("a");a.download = "exported_image." + format;a.href = canvas.toDataURL("image/" + format);a.click();};img.src = imageUrl;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/391226.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【从零搭建SpringBoot3.x 项目脚手架】- 1. 工程初始化

为什么会有这个系列文章 在项目开发中&#xff0c;大多项目依旧沿用的是 JDK 8 Spring Boot 2.x 系列的技术栈&#xff0c;没有Spring Boot 3.x 的上手实践机会。在个人学习探索 Spring Boot 3.x 的过程中&#xff0c;遇到多数第三方框架集成和问题排查的技术问题&#xff0c…

[极客大挑战 2019]Secret File-web

打开题目 查看源码 直接访问Archive_room.php 第二个页面是个点击框&#xff0c;这里bp抓包确认&#xff1b;若是直接SECRET&#xff0c;会跳到end.php 直接访问secr3t.php 代码审计一下 playload&#xff1a;secr3t.php?fileflag.php 改为php协议读取权限 secr3t.php?f…

[图解]SysML建模电磁轨道炮-01块定义图

1 00:00:00,490 --> 00:00:04,000 我们是用EA复刻一个网络上的案例 2 00:00:06,370 --> 00:00:09,240 电磁轨道炮&#xff0c;它的原理很简单 3 00:00:09,490 --> 00:00:10,960 初中物理就可以理解 4 00:00:11,670 --> 00:00:14,010 首先&#xff0c;电流形成磁…

polyfit曲线拟合

一、简介 polyfit函数是matlab中用于进行曲线拟合的一个函数。其数学基础是最小二乘法曲线拟合原理。曲线拟合&#xff1a;已知离散点上的数据集&#xff0c;即已知在点集上的函数值&#xff0c;构造一个解析函数&#xff08;其图形为一曲线&#xff09;使在原离散点上尽可能接…

快讯 | 苹果携手OpenAI,ChatGPT即将登陆iOS 18

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…

【反序列化漏洞】serial靶机详解

一、安装靶机 首先创建新的虚拟机。 然后选择客户机版本为Ubuntu 64位。 然后选择使用现有磁盘&#xff0c;选择下载的vmdk磁盘文件即可。剩下的都是默认 二、信息收集 发现主机192.168.204.143 访问 扫描端口nmap -A 192.168.204.143 -p-&#xff0c;发现只有ssh:22和http:8…

Java:线程安全

引子 首先来看一段代码: private static int count 0;public static void main(String[] args) throws InterruptedException {Thread t1 new Thread(()->{for (int i 0; i < 50000; i) {count;}});Thread t2 new Thread(()->{for (int i 0; i < 50000; i) {…

如何解决C#字典的线程安全问题

前言 我们在上位机软件开发过程中经常需要使用字典这个数据结构&#xff0c;并且经常会在多线程环境中使用字典&#xff0c;如果使用常规的Dictionary就会出现各种异常&#xff0c;本文就是详细介绍如何在多线程环境中使用字典来解决线程安全问题。 1、非线程安全举例 Dictio…

Vue+live2d实现虚拟人物互动(一次体验叙述)

目录 故事的开头&#xff1a; 最终的实现效果&#xff1a; 实现步骤&#xff1a; 第一步&#xff1a;下载重要文件 第二步&#xff1a;创建vue项目文件&#xff0c;将刚下载文件拷贝到public目录下 第三步&#xff1a;在index.html文件中引入js 第四步&#xff1a;使用&…

【数据结构算法经典题目刨析(c语言)】顺序表和链表的区别(图文详解)

&#x1f493; 博客主页&#xff1a;C-SDN花园GGbond ⏩ 文章专栏&#xff1a;数据结构经典题目刨析(c语言) 目录 顺序表和链表的区别 一、底层存储空间 二、插入和删除操作 三、随机访问 四、空间利用率 五、应用场景 六、高速缓存 为什么顺序表的缓存利用率高于链表呢…

设计界的新宠:5款热门UI在线设计软件评测

随着用户界面设计行业的蓬勃发展&#xff0c;越来越多的设计师进入用户界面设计。选择一个方便的用户界面设计工具尤为重要&#xff01;除了传统的用户界面设计工具&#xff0c;在线用户界面设计工具也受到越来越多设计师的青睐。这种不受时间、地点、计算机配置限制的工作方法…

OpenCV||超详细的图像边缘检测

一、基本概念 1.图像边缘检测目的 特征提取&#xff1a;边缘是图像中亮度变化最显著的部分&#xff0c;它们通常对应于物体的轮廓、不同区域的边界等。通过边缘检测&#xff0c;可以从图像中提取出这些重要的特征信息&#xff0c;为后续处理如图像分割、目标识别等提供基础。 …

webfunny埋点系统如何进行部署?

hello 大家webfunny埋点系统做了不少功能更新&#xff0c;平常给大家分享比较多的是**webfunny前端监控系统**&#xff0c;最近有不少技术同学来了解webfunny埋点系统&#xff0c;今天主要给大家分享下webfunny埋点系统部署&#xff0c;分为本地部署和线上部署。 还没有试用和…

字节一面面经

1.redis了解吗&#xff0c;是解决什么问题的&#xff0c;redis的应用&#xff1f; Redis 是一种基于内存的数据库&#xff0c;常用的数据结构有string、hash、list、set、zset这五种&#xff0c;对数据的读写操作都是在内存中完成。因此读写速度非常快&#xff0c;常用于缓存&…

第三期书生大模型实战营之XTuner微调个人小助手认知

基础任务 使用 XTuner 微调 InternLM2-Chat-1.8B 实现自己的小助手认知&#xff0c;记录复现过程并截图。 任务结果截图 1. 创建虚拟环境 # 安装一些必要的库 conda install pytorch2.1.2 torchvision0.16.2 torchaudio2.1.2 pytorch-cuda12.1 -c pytorch -c nvidia -y # 安…

2024华数杯数学建模竞赛选题建议+初步分析

提示&#xff1a;DS C君认为的难度&#xff1a;C<A<B&#xff0c;开放度&#xff1a;A<B<C。 综合评价来看 A题适合对机械臂和机器人运动学感兴趣的同学&#xff0c;尤其是有一定编程和优化算法基础的同学。不建议非相关专业同学选择。 B题挑战较大&#xff0…

Go语言实现多协程文件下载器

文章目录 前言流程图主函数下载文件初始化分片下载worker分发下载任务获取下载文件的大小下载文件分片错误重试项目演示最后 前言 你好&#xff0c;我是醉墨居士&#xff0c;最近在开发文件传输相关的项目&#xff0c;然后顺手写了一个多协程文件下载器&#xff0c;代码非常精…

用于遥感数据处理的python脚本

编辑&#xff1a;我不爱机器学习 今天给大家分享一组用于遥感处理的 python 脚本。 作者使用基于无人机的智利中南部泥炭地的高光谱图像。该图像有 41 个波段&#xff08;10 nm 宽&#xff09;&#xff0c;范围为 480-880 nm&#xff0c;像素大小为 10 cm。绿点对应于测量生物…

【Python系列】Python 协程:并发编程的新篇章

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

万物分割(Segment Anything Model)C++模型推理部署

概述 SAM 是一种先进的人工智能模型&#xff0c;已经证明了在分割复杂和多样化图像方面具有优异的表现。该模型是计算机视觉和图像分割领域的一个重大突破。 SAM 的架构旨在处理各种图像分割任务&#xff0c;包括对象检测、实例分割和全景分割。这意味着该模型可以应用于各种用…