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

news2025/1/28 1:05:25

本地环境: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.coloradmin.cn/o/1977626.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

8090怀旧视频素材去哪里找?怀旧童年的素材库分享给你

在这个充满活力的现代社会中&#xff0c;对80和90年代的复古风情的怀旧情感愈加浓厚。那些年的音乐、电影、日常生活乃至街头巷尾的景象&#xff0c;总能唤起人们的美好回忆。对于视频创作者而言&#xff0c;制作一部带有80和90年代怀旧风格的视频&#xff0c;不仅能触动观众的…

cgroup:Linux的资源控制机制

文章目录 1 cgroup 的主要功能1.1 资源限制1.2 优先级控制1.3 资源隔离1.4 资源监控 2 cgroup 的层次结构3 cgroup 子系统4 示例&#xff1a;使用 cgroup 控制 CPU 和内存4.1 创建 cgroup4.2 设置资源限制4.3 将进程添加到 cgroup 5 使用 systemd 管理 cgroup6 总结参考链接封面…

【人工智能】NLP入门指南:自然语言处理基础全解析

文章目录 前言一、NLPNLP&#xff08;自然语言处理&#xff09;NLU&#xff08;自然语言理解&#xff09;NLG&#xff08;自然语言生成&#xff09; 二、分词1.什么是分词2.常见的分词工具3.jieba分词 三、词向量1.什么是词向量2.文本张量表示方法3.常见的词向量模型3.1 ont-ho…

QT键盘和鼠标事件

这些事件都在QWidget 中的保护成员方法中 都是虚函数在头文件中声明了 需要类外重现实现 如果头文件中声明 类外无实现就会报错 void Widget::keyPressEvent(QKeyEvent *event) {switch (event->key()) {//获取按键case Qt::Key_W://按键wqDebug()<<"按下w"…

【Linux】网络基础_4

文章目录 十、网络基础5. socket编程网络翻译服务 未完待续 十、网络基础 5. socket编程 网络翻译服务 基于UDP&#xff0c;我们实现一个简单的翻译。 我们导入之前写的代码&#xff1a; InetAddr.hpp&#xff1a; #pragma once#include <iostream> #include <sys…

2000-2022年各地级市能源消费数据(夜间灯光ArcGIS计算)

2000-2022年各地级市能源消费数据&#xff08;夜间灯光ArcGIS计算&#xff09; 1、时间&#xff1a;2000-2022年 2、指标&#xff1a;城市、省份、年份、能源消费总量(百吨标准煤) 3、范围&#xff1a;337个地级市 4、计算方法&#xff1a; 利用ArcGIS计算各地级市的DN总和…

【python案例】基于Python 爬虫的房地产数据可视化分析设计与实现

引言 研究背景与意义 房地产行业在我国属于支柱性产业&#xff0c;在我国社会经济发展中一直扮演着重要角色。房价问题&#xff0c;尤其是大中城市的房价问题&#xff0c;一直是政府、大众和众多研究人员关注的热点。如何科学地预测房价是房价问题的研究方向之一。随着互联网…

[WUSTCTF2020]朴实无华1

打开题目 扫目录用dirsearch扫&#xff0c;为节省建议只扫常见的目录&#xff0c;配置是&#xff1a; ./dirsearch.py -e bak,zip,txt,tgz,php -u http:..... -s 3 -t 20 访问一下 根据提示&#xff0c;再访问一次 提示不在这&#xff0c;抓包看看 根据提示&#xff0c;改ge…

(免费领源码)java#springboot#mysql大学校园旧物捐赠网站 25109-计算机毕业设计项目选题推荐

摘 要 在网络信息的时代&#xff0c;众多的软件被开发出来&#xff0c;给用户带来了很大的选择余地&#xff0c;而且人们越来越追求更个性的需求。在这种时代背景下&#xff0c;企业只能以用户为导向&#xff0c;按品种分类规划&#xff0c;以产品的持续创新作为企业最重要的竞…

cocos creator绘制网格背景(基于矢量绘图)

在2D游戏开发中&#xff0c;设计2D地图的背景实现通常有以下几种方式&#xff1a; 静态背景图&#xff1a; 最简单的方式是使用静态背景图&#xff0c;即将整个背景作为一个静态图像加载到游戏中。这种方式适用于简单的游戏或者背景不需要变化的场景。 平铺背景图&#xff1a;…

Mathematica 矩阵基础操作指南

使用 Mathematica 进行矩阵操作的指南 目录 使用 Mathematica 进行矩阵操作的指南引言创建矩阵矩阵运算加法与减法 矩阵乘法矩阵转置逐元素运算 矩阵的行列式与逆行列式逆矩阵 矩阵分解LU 分解QR 分解特征值与特征向量 矩阵的可视化矩阵的热图矩阵的网格图 末 引言 最近笔者在…

分布式事务-使用队列实现最终一致性

分布式事务-扣减库存 一、最终一致性架构图 1、服务 左侧&#xff1a;创建订单服务Server1 右侧&#xff1a;扣减库存服务Server2 中间&#xff1a;独立消息服务Server3 2、中间件&#xff1a; Kafka-MQ、MySQL-db 二、步骤 0、定义MQ&#xff0c;三个状态 prepareconf…

spring原理(自学第八天)

aop的实现原理 AOP 底层实现方式之一是代理&#xff0c;由代理结合通知和目标&#xff0c;提供增强功能 除此以外&#xff0c;aspectj 提供了两种另外的 AOP 底层实现&#xff1a; 第一种是通过 ajc 编译器在编译 class 类文件时&#xff0c;就把通知的增强功能&#xff0c;织…

传输层_计算机网络

文章目录 运输层UDPTCPTCP连接管理TCP三次握手TCP四次挥手 可靠机制流量控制拥塞控制 QUIC 运输层 网络层提供了主机之间的逻辑通信 运输层为运行在不同主机上的进程之间提供了逻辑通信 UDP(用户数据报协议)提供一种不可靠、无连接的服务&#xff0c;数据报 TCP(传输控制协议)…

【Linux详解】基础IO:软硬连接 | 动静态库管理

目录 软硬链接 1. 介绍 2.理解 2.1 如何理解硬链接&#xff1f; 2.2 如何理解软连接&#xff1f; 动静态库 1.介绍 1.1 使用 1.2 什么是库&#xff1f; 2.生成 2.1 静态库 2.2 动态库&#xff1a; 软硬链接 1. 介绍 1.1 软连接 是一个独立文件&#xff0c;具有独…

Stable Diffusion绘画 | 文生图-高分辨率修复-Hires.fix

开启「高分辨率修复」的作用是&#xff0c;提高图片分辨率&#xff0c;增加细节&#xff0c;从而让画面变得更清晰。 之所以不采取直接通过调整宽高来提高分辨率&#xff0c; 是因为绝大多数模型在训练时&#xff0c;精度都是 512x512&#xff0c;如果生成图片时&#xff0c;直…

云仓酒庄新纪元:雷盛红酒LEESON 401澳洲赤霞珠盛大发布

云仓酒庄新纪元&#xff1a;雷盛红酒LEESON 401澳洲赤霞珠盛大发布 在全球酒业市场的激烈竞争中&#xff0c;云仓酒庄始终以其敏锐的市场洞察力和卓越的产品品质引领行业潮流。近日&#xff0c;云仓酒庄宣布其精心筹备的雷盛红酒LEESON 401系列——澳洲原瓶进口赤霞珠正式上线…

API 接口设计原则:RESTful 与 GraphQL

RESTful 接口 REST 的全称是 REpresentational State Transfer&#xff0c;是一种 Web API 的设计风格 RESTful API 设计 6 大原则 一个 RESTful 风格的接口应该满足如下的 6 点原则&#xff1a; 统一接口&#xff1a;For example, the HTTP-based REST APIs make use of th…

小巧免费的笔记本电池检测工具

BatteryInfoView是一款免费的笔记本电池检测软件&#xff0c;适用于笔记本电脑和上网本。该软件能够提供电池的详细信息&#xff0c;包括电池名称、制造商名称、序列号、制造日期、电源状态&#xff08;充电/放电&#xff09;、当前电池容量、完全充电容量、设计容量、充电放电…

区块链核心概念与技术架构简介

引言 区块链&#xff0c;一种分布式账本技术&#xff0c;不仅为数字货币提供了基础设施&#xff0c;更在金融、供应链、物联网等多个领域展现出广泛的应用前景。区块链技术被认为是继蒸汽机、电力、互联网之后&#xff0c;下一代颠覆性的核心技术。 如果说蒸汽机释放了人们的…