【二进制文件】MRC stack文件 转成 多个独立的MRC文件

mrc stack文件 转成 独立的mrc文件

MRC文件 和 MRC Stack文件 简介

MRC文件 是冷冻电镜电子显微图像中常用于数据处理的一种图像文件(二进制文件)可以存储二维和三维的图像。需要特殊的解码软件可以显示,如chimera,EMAN等软件。

MRC文件一般用.mrc.mrcs后缀表示,其中.mrcs代表MRC Stack文件。

MRC stack文件 和MRC文件的唯一区别就是文件名的后缀不一样,实际上就是MRC文件。
后缀名加S的原因是为了将一系列的二维的MRC文件 集合存成一个MRC文件时,区别一般的MRC文件。
如此我们就知道mrcs文件里存的是一系列二维图像的集合而不是一个三维图像。

MRC文件/未经过motion correction的文件,在文献中也常用movie来表述,因为逻辑上很类似,movie本身也是一系列二维图片的集合,frames 多帧图像。

MRC的数据块逻辑:其实就是三维数组(x,y,z),对应三维图像;二维数组(x,y),对应二维图像。而MRCs文件就是把多个二维图像(二维数组X,Y)集合写成三维图像(三维数组X,Y,Z 其中Z就对应二维图像的序号)。所以文件头和数据块都可以是一样的。

.mrcs文件转多个独立的.mrc文件

由于没有找的已有的程序可以处理我的需求,所以自己基于MRC文件的MRC/CCP4 2014 file format文档,解析二进制文件进行重写。

代码块

# -*- coding: utf-8 -*-
"""
Created on Tue Dec  6 21:06:55 2022

@author: anis
"""

import struct
import os

dir = cur_path = os.getcwd()
#=====================获取mrc文件的主头数据 头部固定1024字节或256个4字节===============
def getHeader(mrcFile):
    with open(mrcFile,"rb", ) as mrc:
         word1=mrc.read(96)
         value1=struct.unpack("24i",word1)
         ["NX","NY","NZ","MODE","NXSTART","NYSTART","NZSTART","MX","MY","MZ","CELLA1","CELLA2","CELLA3","CELLB1","CELLB2","CELLB3", \
          "MAPC","MAPR","MAPS","DMIN","DMAX","DMEAN","ISPG","NSYMBT"]
         
         mrc.seek(96)
         word2=mrc.read(100)
         value2=struct.unpack("25i",word2)
         ["EXTRA"]
         
         mrc.seek(196)
         word3=mrc.read(28)
         value3=struct.unpack("7i",word3)                  
         ["ORIGIN1","ORIGIN2","ORIGIN3","MAP","MACHST","RMS","NLABL"]
         
         mrc.seek(224)
         word4=mrc.read(800)
         value4=struct.unpack("200i",word4)        
    
    return value1+value2+value3+value4
       
#===================================获取data块数据================================ 
def getData(mrcFile,fmt,NZ):
    with open(mrcFile,"rb", ) as mrc:
        mrc.seek(1024)
        data=mrc.read(4*fmt*NZ)
        value=struct.unpack("f"*fmt*NZ, data)    
    return value

#============================将一个mrcs文件data数据写入多个mrc文件================================ 
def mrcs2mrc(originFile):
    header=getHeader(originFile)
    NX=header[0]
    NY=header[1]
    NZ=header[2]
    li=list(header)
    li[2]=1
    header=tuple(li)
    
    fmt=NX*NY   
    data=getData(originFile,fmt,NZ)       
    for Z in range(NZ):
        data_block=data[fmt*(Z):fmt*(Z+1)]
        with open("MRCdir/"+str(Z+1).rjust(2,'0')+"_"+originFile.split(".")[0]+".mrc","wb", ) as mrc:         
            header_packed=struct.pack("i"*256,*header)
            mrc.write(header_packed)
            data_packed=struct.pack("f"*fmt,*data_block)            
            mrc.write(data_packed)
            print(str(Z+1).rjust(2,'0')+"_"+originFile.split(".")[0]+".mrc  已写入")
    print("done!")        
    return 0
    
if not os.path.exists("MRCdir"):
    os.makedirs("MRCdir")
for root, dirs, files in os.walk(dir):                         
    for file in files:                                         
        (fileName, extension) = os.path.splitext(file)      
        if (extension == '.mrcs'):                    
            mrcs2mrc(file)
                  

MRC文件格式:

在这里插入图片描述

struct函数 unpack和pack(二进制数据转元组,元组转二进制数据)

用于处理二进制数据的struct函数, 数据格式的定义

  • 示例
  • 打印unpack的数据 控制台结果:
    (320, 320, 1, 2, -512, -512, -512, 1023, 1023, 1023, 1152248054)
  • 打印pack的数据 控制台结果:
    b'@\x01\x00\x00@\x01\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x00\xfe\xff\xff\x00\xfe\xff\xff\x00\xfe\xff\xff\xff\x03\x00\x00\xff\x03\x00\x00\xff\x03\x00\x00\xf6\xe8\xadD\xf6\xe8\xadD\xf6\xe8\xadD\x00\x00\xb4

mrc文件中的数据块的数据类型是float32,4个字节,对应下表中的“f
在这里插入图片描述

note

由于没有对文件头进行过多操作,所以getHeader中贪便宜,unpack的时候没有考虑数据类型,所有的都按照 “i” 类型unpack,后又按“i” 又原封不动的pack回去了。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值