可能连CS专业的大一新生的期中作业的水准都达不到吧。

需求

将实验采集到的吸收光谱与发射光谱数据批量导入到预先制作好的Excel模板中。

背景介绍

最近在做一些荧光染料相关的课题。
在测量化合物的光谱信息时,仪器会输出格式如下的吸收光谱信息与发射光谱信息。
吸收光谱.png
发射光谱.png
其中Abs代表Absorption,即吸收光谱,Em代表Emission,即发射光谱;第1列信息为波长,第2列为对应波长的吸光度荧光强度

在实验过程中,首先在比色皿内加入空白溶剂,扫描其吸收谱与发射谱;然后加入感兴趣的荧光染料,混匀后再次扫描吸收谱与发射;后者与前者相减,即可得到染料在当前溶剂环境下的光谱;进一步地,通过测量染料在不同溶剂环境下的光谱,即可了解染料的溶致变色性质,温度敏感性质,粘度敏感性质等信息。

对于每个化合物,我最终会把实验上得到的数据汇总到两个格式如下的Excel文件中,一个文件存储吸收光谱,一个文件存储发射光谱。下面以发射光谱为例。
总表1.png
总表2.png
总表3.png
这份总表记录了化合物在实验室所有已有溶剂中的发射光谱。BG代表background,即溶剂的空白光谱;EM1EM2EM3代表3次平行实验所得发射光谱数据。通过Excel的公式功能,可以实现光谱背景的扣除、光谱数据的归一化,峰值及其位置的查询等基本操作。此外,通过Excel的绘图功能,可以得到一张足以应付组会的光谱汇总图。

已有的工作流程

0.在实验过程中,为了便于后续处理,我会将背景文件命名为化合物名称-Em-BG-溶剂.csv,例如New-2-Em-BG-DMSO.csv;将发射光谱文件命名为化合物名称-Em-浓度-溶剂数字.csv,例如New-2-Em-5uM-DMSO2.csv,其中2代表第2次平行实验;
1.将上述汇总表内的存放实验数据的列都清空,即可得到一份模板文件;
2.打开任意一份仪器输出的原始数据文件,将波长信息粘贴至模板的第一列;
3.依次将打开各个原始文件,将溶剂背景光谱和发射光谱粘贴至对应的位置;
4.对吸收光谱文件执行相同的操作。

痛点

手动将一个一个文件打开,然后复制、粘贴、关闭——这个过程机械重复且浪费时间
假定有3个待测化合物,需要测量它们在4种溶剂中的发射光谱,考虑到每组需要测量1次背景和3次平行,则最终需要处理3*4*(1+3)=48个光谱文件;再考虑测量吸收光谱,则还需要处理另外48个光谱文件。这是难以容忍的。
因此,考虑使用Python完成光谱数据的小批量处理。

关键需求分析

运行效率并不在考虑范围之内,因为顶多也就是几百个小文件的批量读写,对于现代计算机的性能来说绰绰有余。
关键在于,在处理过程中,需要维持模板内的公式与图表不被破坏,常用的pandasnumpy似乎并不支持这一点。
查询可知,openpyxl支持对.xslx文件的专门操作。

代码实现

from openpyxl import load_workbook
from csv import reader
from os import listdir

#读取空白模板
print("正在载入模板...")
workbook = load_workbook('./Template/EmissionSpectra_Blank.xlsx')
worksheet = workbook.active
print("载入完成")

#读取目录下的.csv格式的原始文件
print("正在检索待处理文件...")
csv_list=[]
for name in listdir(): #遍历当前目录下的文件名
    if name.split('.')[-1]=='csv': #用“.”作为分隔符,用-1来指向最后一个元素,以此判断文件类型
        csv_list.append(name)
print("检索完成")

#处理光谱文件
print("开始处理文件...")
loop = 1
for name in csv_list:
    #首先读取波长信息
    if loop == 1:
        print("正在读取波长范围...")
        with open(name) as raw_data:
            reader_obj = reader(raw_data)
            wavelength = [row[0] for row in reader_obj] #提取第一列的波长
        j = 2
        for value in wavelength:
            worksheet[ 'A' + str(j)] = float(value)
            j = j + 1
        loop = loop + 1
        print("读取完成,波长范围为"+str(wavelength[0])+"nm到"+str(wavelength[-1])+"nm")
    
    #判断是否为背景光谱
    if name.split('-')[-2]=='BG':
        solvent = ( name.split('-')[-1] ).split('.')[0] #提取溶剂类型
        print("正在读取"+solvent+"的背景光谱...")
        with open(name) as raw_data:
            reader_obj = reader(raw_data)
            column = [row[1] for row in reader_obj] #提取第二列的荧光强度
            
       
        for row in worksheet.iter_rows(min_row=1,max_row= 1): #提取第一行
            for cell in row: #在第一行内遍历
                if cell.value == solvent + "-BG":
                    cell_position = cell.coordinate #定位"solvent-BG"所在单元格位置
                    line_position = cell_position[0:-1] #提取列号
            
        i=2
        for value in column:
            worksheet[line_position + str(i)] = float(value)
            i = i + 1
        print(solvent+"的背景光谱读取完成")
            
    #如果不是背景光谱,则为发射光谱       
    if name.split('-')[-2]!='BG':
        solvent = ( name.split('-')[-1] ).split('.')[0] #提取溶剂类型以及平行测试序号
        print("正在读取"+solvent+"的发射光谱...")
        number = solvent[-1]
        solvent = solvent[0:-1]
        with open(name) as raw_data:
            reader_obj = reader(raw_data)
            column = [row[1] for row in reader_obj] #提取第二列的荧光强度
       
        for row in worksheet.iter_rows(min_row=1,max_row= 1): #提取第一行
            for cell in row: #在第一行内遍历
                if cell.value == solvent + "-EM" + str(number):
                    cell_position = cell.coordinate #定位"solvent-BG"所在单元格位置
                    line_position = cell_position[0:-1] #提取列号
            
        i=2
        for value in column:
            worksheet[line_position + str(i)] = float(value)
            i = i + 1
        print(solvent+number+"的发射光谱读取完成")

print("正在导出光谱处理数据EmissionSpectra_Completed.xlsx")
workbook.save("./Template/EmissionSpectra_Completed.xlsx")
print("导出完成 :)")

使用

把待处理的原始文件放在当前目录,然后运行程序,结果符合预期。
run1.png
run2.png

后记

这代码丑陋得一塌糊涂。

已有 2 条评论

  1. 92

    谢邀,CS大一新生的python课程在学期中后期才讲到文件(

  2. Sdawn

    我进的大类招生,大一一年甚至都不会选定专业

添加新评论