- relion subtomo的基本流程
- Main Step 1:数据输入(import tomograms and import coordinates)
- Main step 2:Make pseudo-subtomograms
Cryo-ET subtomo averaging是冷冻电镜解出高分辨率生物结构的重要过程,本文是对relion subtomo部分主要程序功能的代码阅读,对relion的解读以及部分数据示例主要来自源码阅读以及relion教程。
relion subtomo的基本流程
- 数据输入:
- Make pseudo-subtomograms:根据每个particle位置使用FBP重建出每个particle的3D volume。第一步先以bin4分辨率重建。
- De novo 3D model generation:随机挑选bin4的particle volume average出一个初始的initial model。
- Initial 3D refinement:以上一步的model为reference,计算FSC并使用SGD优化每一个particle的坐标与欧拉角直到收敛。
- Reconstruct particle:使用优化好的particle的所有2D crop image,使用FBP重建出bin2分辨率的reference map。与第2步不同的是,这一步不是每个particle单独重建自己的volume,而是所有particle一起重建一个reference map。
- 重复第2步,用第4步的优化结果以bin2分辨率重建每个particle。
- 3D auto refine:以第五步结果为reference map,优化bin2 particle。
- 重复5、6、7步,在bin1分辨率上重建与优化,得到最终高分辨率reference map。
接下来会详细介绍上述的具体步骤,每个步骤可大致分为数据输入、数据输出以及代码解析三部分,代码解析中会有用中文写的注释进行说明。
注:由于3D initial model与refine部分的内容非常重要,需要进一步的阅读与考证,因此本文的解析只限于前两个步骤,之后会持续更新。
Main Step 1:数据输入(import tomograms and import coordinates)
在这一步,relion会把ET tomogram与对应particle信息全部输入进来,对于tomogram,需要原始tilt series、align参数文件(imod)、ctf参数(ctffind或ctfplotter);对于particles,需要每个particle的3D坐标与欧拉旋转角。
源码位置:source/jaz/tomography/apps/import_tomograms.cpp
source/jaz/tomography/apps/import_particles.cpp
- Import Tomograms:输入tilt series与对应信息,.star文件如下。
data_ loop_ _rlnTomoName _rlnTomoTiltSeriesName _rlnTomoImportCtfFindFile _rlnTomoImportImodDir _rlnTomoImportFractionalDose _rlnTomoImportOrderList TS_01 tomograms/TS_01/01.mrc tomograms/TS_01/01_output.txt tomograms/TS_01 3.0 input/order_list.csv TS_03 tomograms/TS_03/03.mrc tomograms/TS_03/03_output.txt tomograms/TS_03 3.0 input/order_list.csv TS_43 tomograms/TS_43/43.mrc tomograms/TS_43/43_output.txt tomograms/TS_43 3.1 input/order_list.csv TS_45 tomograms/TS_45/45.mrc tomograms/TS_45/45_output.txt tomograms/TS_45 3.1 input/order_list.csv TS_54 tomograms/TS_54/54.mrc tomograms/TS_54/54_output.txt tomograms/TS_54 3.0 input/order_list.csv
几乎所有relion的输入都可以被描述成.star文件。
- rlnTomoName: tomogram的名字
- rlnTomoTiltSeriesName: tomogram raw stack mrc路径
- rlnTomoImportCtfFindFile: 对应的ctf参数文件(如果是ctfplotter的结果就是rlnTomoImportCtfPlotterFile)
- rlnTomoImportImodDir: tomogram对应IMOD文件夹路径(用来获得align参数)
- rlnTomoImportFractionalDose: 数据拍摄用的电子剂量
- rlnTomoImportOrderList: 标注数据拍摄顺序,表格里每行有两个数(i,j),意味着第i个被拍的角度是j。
- Import coordinates:输入particle坐标、欧拉角与对应的tomograms名字。
data_particles loop_ _rlnTomoName #1 _rlnTomoParticleId #2 _rlnTomoManifoldIndex #3 _rlnCoordinateX #4 _rlnCoordinateY #5 _rlnCoordinateZ #6 _rlnOriginXAngst #7 _rlnOriginYAngst #8 _rlnOriginZAngst #9 _rlnAngleRot #10 _rlnAngleTilt #11 _rlnAnglePsi #12 _rlnClassNumber #13 _rlnRandomSubset #14 TS_01 1 1 644 1164 72 -0.000 -0.000 -0.000 -8.72 167.29 87.57 -1 2 TS_01 2 1 624 1112 64 -0.000 -0.000 -0.000 -130.65 175.35 84.29 -1 1 TS_01 3 1 676 1120 68 -0.000 -0.000 -0.000 -117.88 170.53 95.89 -1 2 TS_01 4 1 696 1168 84 -0.000 -0.000 -0.000 53.64 158.62 86.53 -1 1 TS_01 5 1 592 1156 72 -0.000 -0.000 -0.000 -78.74 169.66 78.39 -1 2 TS_01 6 1 659 1071 67 0.026 -0.088 0.012 54.34 178.38 -31.41 1 1 TS_01 7 1 712 1076 64 -0.000 -0.000 -0.000 61.58 177.85 156.65 -1 2 TS_01 8 1 660 1200 100 -0.000 -0.000 -0.000 106.21 148.26 74.99 -1 1 ...
数据里的3D坐标应该与IMOD文件夹内
tilt.com
文件对应。$tilt -StandardInput InputProjections 01_dose-filt.ali OutputFile 01_dose-filt_full.rec IMAGEBINNED 1 TILTFILE 01_dose-filt.tlt THICKNESS 1360 RADIAL 0.35 0.05 XAXISTILT 0.0 LOG 0.0 SCALE 0.0 330.0 PERPENDICULAR MODE 2 FULLIMAGE 3710 3710 SUBSETSTART 0 1825 AdjustOrigin ActionIfGPUFails 1,2 XTILTFILE 01_dose-filt.xtilt OFFSET 0.0 SHIFT 0.0 300.0 UseGPU 0 $if (-e ./savework) ./savework
THICHNESS
与FULLIMAGE
就是3D volume的维度。
Main step 2:Make pseudo-subtomograms
数据输入后,relion通过particle坐标投影回2D图片进行FBP重建。
源码位置: source/jaz/tomography/programs/subtomo.cpp
- 数据输入:
- tomograms.star:
data_global loop_ _rlnTomoName #1 _rlnTomoTiltSeriesName #2 _rlnTomoFrameCount #3 _rlnTomoSizeX #4 _rlnTomoSizeY #5 _rlnTomoSizeZ #6 _rlnTomoHand #7 _rlnOpticsGroupName #8 _rlnTomoTiltSeriesPixelSize #9 _rlnVoltage #10 _rlnSphericalAberration #11 _rlnAmplitudeContrast #12 _rlnTomoImportFractionalDose #13 TS_01 tomograms/TS_01/01.mrc 40 3710 3710 1360 -1.00000 opticsGroup1 1.350000 300.000000 2.700000 0.070000 3.000000 TS_03 tomograms/TS_03/03.mrc 40 3710 3710 1120 -1.00000 opticsGroup1 1.350000 300.000000 2.700000 0.070000 3.000000 TS_43 tomograms/TS_43/43.mrc 41 3710 3710 1200 -1.00000 opticsGroup1 1.350000 300.000000 2.700000 0.070000 3.100000 TS_45 tomograms/TS_45/45.mrc 41 3710 3710 1200 -1.00000 opticsGroup1 1.350000 300.000000 2.700000 0.070000 3.100000 TS_54 tomograms/TS_54/54.mrc 41 3710 3710 1200 -1.00000 opticsGroup1 1.350000 300.000000 2.700000 0.070000 3.000000 # version 30001 data_TS_01 loop_ _rlnTomoProjX #1 _rlnTomoProjY #2 _rlnTomoProjZ #3 _rlnTomoProjW #4 _rlnDefocusU #5 _rlnDefocusV #6 _rlnDefocusAngle #7 _rlnCtfScalefactor #8 _rlnMicrographPreExposure #9 [0.0446311671183,-0.996636282201,-0.0687259705396,3671.47512481] [0.542807022999,0.0819463245359,-0.835849516828,1134.92684561] [0.838670567945,0,0.544639035015,-1762.57143309] [0,0,0,1] 36642.020000 36513.230000 -21.44723 1.000000 114.000000 [0.0481668410418,-0.996636282201,-0.0662959691761,3652.3982384] [0.585808108577,0.0819463245359,-0.806295689511,1032.33863359] [0.809016994375,0,0.587785252292,-1723.90164368] [0,0,0,1] 40659.750000 40045.230000 -0.91484 1.000000 105.000000 [0.051570493002,-0.996636282201,-0.0636842551693,3652.69289457] [0.627203534849,0.0819463245359,-0.774531861754,962.935527375] [0.777145961457,0,0.62932039105,-1680.50675969] [0,0,0,1] 40413.310000 40192.590000 -9.89749 1.000000 102.000000 [0.0548327828959,-0.996636183544,-0.0608979749071,3639.0873037] [0.666879773814,0.0819463082018,-0.740645022684,862.386149688] [0.743144825477,0,0.669130606359,-1632.50572348] [0,0,0,1] 39817.330000 38824.790000 22.175120 1.000000 93.000000 [0.0579448017726,-0.996636282201,-0.0579448017726,3637.20509583] [0.704728273521,0.0819463245359,-0.704728273521,794.060306913] [0.707106781187,0,0.707106781187,-1580.03010256] [0,0,0,1] 39895.570000 39376.050000 -59.23525 1.000000 90.000000 [0.0608979870457,-0.996636282201,-0.0548327938256,3623.02400791] [0.740645096001,0.0819463245359,-0.666879839828,697.175028762] [0.669130606359,0,0.743144825477,-1523.22372895] [0,0,0,1] 40997.750000 40550.260000 41.593690 1.000000 81.000000 [0.0636842551693,-0.996636282201,-0.051570493002,3620.16706308] [0.774531861754,0.0819463245359,-0.627203534849,636.106604797] [0.62932039105,0,0.777145961457,-1462.24230499] [0,0,0,1] 40370.910000 39761.240000 8.227517 1.000000 78.000000 [0.0662959691761,-0.996636282201,-0.0481668410418,3607.70796738] [0.806295689511,0.0819463245359,-0.585808108577,543.250808196] [0.587785252292,0,0.809016994375,-1397.2529765] [0,0,0,1] 39999.480000 39411.810000 70.785380 1.000000 69.000000 [0.0687259705396,-0.996636282201,-0.0446311671183,3605.5238664] [0.835849516828,0.0819463245359,-0.542807022999,488.766946972] [0.544639035015,0,0.838670567945,-1328.43387472] [0,0,0,1] 40137.500000 39760.600000 -58.24971 1.000000 66.000000 [0.0709675987948,-0.996636282201,-0.0409731622679,3592.33824821] [0.863112338719,0.0819463245359,-0.4983181411,401.401576476] [0.5,0,0.866025403784,-1255.97362803] [0,0,0,1] 39349.730000 38793.070000 88.441160 1.000000 57.000000 [0.0730147097947,-0.996636282201,-0.0372028528279,3588.68703015] [0.888009429684,0.0819463245359,-0.452463403815,355.726113698] [0.45399049974,0,0.891006524188,-1180.07084493] [0,0,0,1] 39822.450000 39138.010000 -88.34856 1.000000 54.000000 [0.0748616925503,-0.996636282201,-0.0333305729541,3578.55399784] [0.910472548526,0.0819463245359,-0.40536849579,274.52722088] [0.406736643076,0,0.913545457643,-1100.93356967] [0,0,0,1] 39827.790000 38858.570000 37.508620 1.000000 45.000000 [0.0765034846101,-0.996636282201,-0.0293669362967,3580.20836769] [0.9304401254,0.0819463245359,-0.357162500895,241.405650451] [0.358367949545,0,0.933580426497,-1018.77871202] [0,0,0,1] 39505.590000 38739.020000 72.908280 1.000000 42.000000 [0.0779355859363,-0.996636282201,-0.0253228069082,3571.11169502] [0.947857430563,0.0819463245359,-0.307977548411,168.405709197] [0.309016994375,0,0.951056516295,-933.831452739] [0,0,0,1] 39406.160000 38893.030000 52.051360 1.000000 33.000000 [0.0791540712387,-0.996636282201,-0.021209269466,3570.27766288] [0.962676724395,0.0819463245359,-0.257948450874,128.42558249] [0.258819045103,0,0.965925826289,-846.324626351] [0,0,0,1] 39531.560000 39091.820000 58.772460 1.000000 30.000000 [0.0801556007337,-0.996636282201,-0.0170375988906,3564.42952706] [0.974857388239,0.0819463245359,-0.207212334563,83.6588849601] [0.207911690818,0,0.978147600734,-756.49808299] [0,0,0,1] 39427.630000 39046.290000 59.961690 1.000000 21.000000 [0.0809374292987,-0.996636282201,-0.0128192294408,3562.97333088] [0.984366035744,0.0819463245359,-0.155908263646,29.0829757451] [0.15643446504,0,0.987688340595,-664.598030968] [0,0,0,1] 39532.620000 38599.300000 52.084560 1.000000 18.000000 [0.0814974139959,-0.996636282201,-0.00856572337417,3558.53487849] [0.991176604367,0.0819463245359,-0.104176859015,-1.18713694823] [0.104528463268,0,0.994521895368,-570.876361938] [0,0,0,1] 39014.650000 38968.380000 -63.00058 1.000000 9.000000 [0.0818340199461,-0.996636282201,-0.00428873925518,3553.4951174] [0.995270426814,0.0819463245359,-0.0521599128554,-51.6324692773] [0.0523359562429,0,0.998629534755,-475.589960481] [0,0,0,1] 39227.170000 38871.850000 12.309220 1.000000 6.000000 [0.0819463245359,-0.996636282201,0,3552.56073262] [0.996636282201,0.0819463245359,0,-90.8439859756] [0,0,1,-379] [0,0,0,1] 39068.530000 38951.920000 78.665920 1.000000 0.000000 [0.0818340199461,-0.996636282201,0.00428873925518,3546.95381987] [0.995270426814,0.0819463245359,0.0521599128554,-131.676259583] [-0.0523359562429,0,0.998629534755,-281.371226863] [0,0,0,1] 39057.400000 38974.840000 8.182144 1.000000 3.000000 [0.0814974139959,-0.996636282201,0.00856572337417,3544.15688517] [0.991176604367,0.0819463245359,0.104176859015,-160.567451435] [-0.104528463268,0,0.994521895368,-182.971234751] [0,0,0,1] 39035.180000 38782.230000 32.230680 1.000000 12.000000 [0.0809374292987,-0.996636282201,0.0128192294408,3543.84477494] [0.984366035744,0.0819463245359,0.155908263646,-161.275971526] [-0.15643446504,0,0.987688340595,-84.0697312034] [0,0,0,1] 39043.290000 38865.190000 42.476760 1.000000 15.000000 [0.0801556007337,-0.996636282201,0.0170375988906,3542.63972101] [0.974857388239,0.0819463245359,0.207212334563,-182.680225678] [-0.207911690818,0,0.978147600734,15.0622016342] [0,0,0,1] 38972.400000 38458.930000 54.047440 1.000000 24.000000 [0.0791540712387,-0.996636282201,0.021209269466,3540.90314453] [0.962676724395,0.0819463245359,0.257948450874,-168.240747201] [-0.258819045103,0,0.965925826289,114.152850024] [0,0,0,1] 39261.530000 38814.960000 43.824540 1.000000 27.000000 [0.0779355859363,-0.996636282201,0.0253228069082,3539.20343897] [0.947857430563,0.0819463245359,0.307977548411,-182.310795287] [-0.309016994375,0,0.951056516295,212.930613387] [0,0,0,1] 39145.120000 38548.910000 85.985650 1.000000 36.000000 [0.0765034846101,-0.996636282201,0.0293669362967,3540.28693794] [0.9304401254,0.0819463245359,0.357162500895,-166.436328861] [-0.358367949545,0,0.933580426497,311.124748739] [0,0,0,1] 39068.230000 38945.820000 -20.39378 1.000000 39.000000 [0.0748616925503,-0.996636282201,0.0333305729541,3539.16020523] [0.910472548526,0.0819463245359,0.40536849579,-161.481184149] [-0.406736643076,0,0.913545457643,408.466112781] [0,0,0,1] 38644.770000 38312.490000 28.723170 1.000000 48.000000 [0.0730147097947,-0.996636282201,0.0372028528279,3542.74050015] [0.888009429684,0.0819463245359,0.452463403815,-140.14705467] [-0.45399049974,0,0.891006524188,504.687899599] [0,0,0,1] 38551.200000 38377.930000 -32.28560 1.000000 51.000000 [0.0709675987948,-0.996636282201,0.0409731622679,3538.60222138] [0.863112338719,0.0819463245359,0.4983181411,-119.113337126] [-0.5,0,0.866025403784,599.526371966] [0,0,0,1] 38648.360000 38014.520000 -86.12270 1.000000 60.000000 [0.0687259705396,-0.996636282201,0.0446311671183,3546.16627805] [0.835849516828,0.0819463245359,0.542807022999,-74.8817386918] [-0.544639035015,0,0.838670567945,692.721584219] [0,0,0,1] 39392.190000 39280.810000 79.419320 1.000000 63.000000 [0.0662959691761,-0.996636282201,0.0481668410418,3546.93628163] [0.806295689511,0.0819463245359,0.585808108577,-52.3131546671] [-0.587785252292,0,0.809016994375,784.018094761] [0,0,0,1] 38233.800000 38121.190000 28.456480 1.000000 72.000000 [0.0636842551693,-0.996636282201,0.051570493002,3560.33286861] [0.774531861754,0.0819463245359,0.627203534849,2.32667005088] [-0.62932039105,0,0.777145961457,873.165666201] [0,0,0,1] 38817.150000 37993.650000 65.808050 1.000000 75.000000 [0.0608979870457,-0.996636282201,0.0548327938256,3551.50050725] [0.740645096001,0.0819463245359,0.666879839828,31.4474137123] [-0.669130606359,0,0.743144825477,959.919951243] [0,0,0,1] 38704.830000 38435.350000 43.695990 1.000000 84.000000 [0.0579448017726,-0.996636282201,0.0579448017726,3566.87644746] [0.704728273521,0.0819463245359,0.704728273521,98.7503580288] [-0.707106781187,0,0.707106781187,1044.04316242] [0,0,0,1] 38836.910000 38042.740000 30.870360 1.000000 87.000000 [0.0548327828959,-0.996636183544,0.0608979749071,3558.7445638] [0.666879773814,0.0819463082018,0.740645022684,139.21135038] [-0.743144825477,0,0.669130606359,1125.30472386] [0,0,0,1] 38737.180000 37888.440000 -65.01125 1.000000 96.000000 [0.051570493002,-0.996636282201,0.0636842551693,3577.08153097] [0.627203534849,0.0819463245359,0.774531861754,220.985939563] [-0.777145961457,0,0.62932039105,1203.48190328] [0,0,0,1] 38045.040000 37368.970000 1.267321 1.000000 99.000000 [0.0481668410418,-0.996636282201,0.0662959691761,3567.41008641] [0.585808108577,0.0819463245359,0.806295689511,271.129430647] [-0.809016994375,0,0.587785252292,1278.36042244] [0,0,0,1] 37602.840000 37077.300000 -52.20618 1.000000 108.000000 [0.0446311671183,-0.996636282201,0.0687259705396,3586.40901829] [0.542807022999,0.0819463245359,0.835849516828,361.164407973] [-0.838670567945,0,0.544639035015,1349.73504455] [0,0,0,1] 39523.340000 38642.250000 -20.61330 1.000000 111.000000 [0.0409731622679,-0.996636282201,0.0709675987948,3579.85223744] [0.4983181411,0.0819463245359,0.863112338719,418.265980414] [-0.866025403784,0,0.5,1417.41013672] [0,0,0,1] 36923.730000 36471.380000 84.331470 1.000000 120.000000 ...
- particles.star:
# version 30001 data_optics loop_ _rlnOpticsGroup #1 _rlnOpticsGroupName #2 _rlnSphericalAberration #3 _rlnVoltage #4 _rlnTomoTiltSeriesPixelSize #5 1 opticsGroup1 2.700000 300.000000 1.350000 # version 30001 data_particles loop_ _rlnTomoName #1 _rlnTomoParticleId #2 _rlnTomoManifoldIndex #3 _rlnCoordinateX #4 _rlnCoordinateY #5 _rlnCoordinateZ #6 _rlnOriginXAngst #7 _rlnOriginYAngst #8 _rlnOriginZAngst #9 _rlnAngleRot #10 _rlnAngleTilt #11 _rlnAnglePsi #12 _rlnClassNumber #13 _rlnRandomSubset #14 _rlnTomoParticleName #15 _rlnOpticsGroup #16 TS_01 1 1 644.000000 1164.000000 72.000000 0.000000 0.000000 0.000000 -8.72000 167.290000 87.570000 -1 2 TS_01/1 1 TS_01 2 1 624.000000 1112.000000 64.000000 0.000000 0.000000 0.000000 -130.65000 175.350000 84.290000 -1 1 TS_01/2 1 TS_01 3 1 676.000000 1120.000000 68.000000 0.000000 0.000000 0.000000 -117.88000 170.530000 95.890000 -1 2 TS_01/3 1 TS_01 4 1 696.000000 1168.000000 84.000000 0.000000 0.000000 0.000000 53.640000 158.620000 86.530000 -1 1 TS_01/4 1 TS_01 5 1 592.000000 1156.000000 72.000000 0.000000 0.000000 0.000000 -78.74000 169.660000 78.390000 -1 2 TS_01/5 1 TS_01 6 1 659.000000 1071.000000 67.000000 0.000000 0.000000 0.000000 54.340000 178.380000 -31.41000 1 1 TS_01/6 1 TS_01 7 1 712.000000 1076.000000 64.000000 0.000000 0.000000 0.000000 61.580000 177.850000 156.650000 -1 2 TS_01/7 1 TS_01 8 1 660.000000 1200.000000 100.000000 0.000000 0.000000 0.000000 106.210000 148.260000 74.990000 -1 1 TS_01/8 1 TS_01 9 1 612.000000 1204.000000 80.000000 0.000000 0.000000 0.000000 -118.20000 169.440000 98.700000 -1 2 TS_01/9 1 TS_01 10 1 570.000000 1106.000000 64.000000 0.000000 0.000000 0.000000 -19.63000 173.260000 16.530000 1 1 TS_01/10 1 ...
-
数据输出:输出每个particle的FBP重建结果以及对应的CTF weight volume。
|-Subtomograms |-1_data.mrc |-1_weight.mrc |-2_data.mrc |-2_weight.mrc |-......
-
Program detail:
void SubtomoProgram::run() { //输入参数 if (cropSize < 0) cropSize = boxSize; //默认需要ctf bool do_ctf = true; //s2D是指每个particle对应的2D crop image的size const long int s2D = boxSize; //s3D是指最后输出的particle volume boxsize const long int s3D = cropSize; //sh3D是ctf weight volume的x轴长度,因为relion的fft是rfft,x轴只有正半轴 const long int sh3D = s3D / 2 + 1; //s02D指的是在bin1rawdata上s2D size对应的大小 const long int s02D = (int)(binning * s2D + 0.5); const double relative_box_scale = cropSize / (double) boxSize; const double binned_pixel_size = binning * particleSet.getOriginalPixelSize(0); ... }
遍历particles,投影到各个view上crop出
boxSize
大小的2D image。void SubtomoProgram::processTomograms( const std::vector<int>& tomoIndices, const TomogramSet& tomogramSet, const ParticleSet& particleSet, const std::vector<std::vector<ParticleIndex>>& particles, const AberrationsCache& aberrationsCache, long int s02D, long int s2D, long int s3D, double relative_box_scale, bool do_ctf, int verbosity, BufferedImage<float>& sum_data, BufferedImage<float>& sum_weights ) { ... #pragma omp parallel for num_threads(outer_thread_num) for (int p = 0; p < pc; p++){ //particle对应3D坐标 const std::vector<d3Vector> traj = particleSet.getTrajectoryInPixels( part_id, fc, tomogram.optics.pixelSize, !apply_offsets); if (!tomogram.isVisibleAtAll(traj, s2D / 2.0)) { continue; } //判断particle可不可以被每个view看到,每个view判断一次 const std::vector<bool> isVisible = tomogram.determineVisiblity(traj, s2D / 2.0); std::vector<d4Matrix> projCut(fc), projPart(fc); //2D图片数据(用于FBP) BufferedImage<fComplex> particleStack = BufferedImage<fComplex>(sh2D,s2D,fc); //CTF volume BufferedImage<float> weightStack(sh2D,s2D,fc); //crop 2D image的函数 TomoExtraction::extractAt3D_Fourier( tomogram.stack, s02D, binning, tomogram, traj, isVisible, particleStack, projCut, inner_thread_num, do_circle_precrop); ... } ... }
下方函数源码位置:
src/jaz/tomography/extraction.h
template <typename T> void TomoExtraction::extractAt3D_Fourier( const RawImage<T>& stack, int s, double bin, const Tomogram& tomogram, const std::vector<gravis::d3Vector>& trajectory, const std::vector<bool>& isVisible, RawImage<tComplex<T>>& out, std::vector<gravis::d4Matrix>& projOut, int num_threads, bool circle_crop) { const int fc = tomogram.frameCount; std::vector<gravis::d2Vector> centers(fc); for (int f = 0; f < fc; f++) { //Apply投影矩阵获得3D坐标到图片上的像素位置 centers[f] = tomogram.projectPoint(trajectory[f], f); } //根据2Dcenter crop image extractAt2D_Fourier( stack, s, bin, tomogram.projectionMatrices, centers, isVisible, out, projOut, num_threads, circle_crop); } template <typename T> void TomoExtraction::extractAt2D_Fourier( const RawImage<T>& stack, int s, double bin, const std::vector<gravis::d4Matrix>& projIn, const std::vector<gravis::d2Vector>& centers, const std::vector<bool>& isVisible, RawImage<tComplex<T>>& out, std::vector<gravis::d4Matrix>& projOut, int num_threads, bool circle_crop) { const int sh = s/2 + 1; const int fc = stack.zdim; //如果有bin的需求,那么会在这里bin数据 const int sb = (int)(s / bin + 0.5); const int sbh = sb/2 + 1; BufferedImage<T> smallStack(s,s,fc); projOut.resize(fc); std::vector<gravis::d2Vector> integralShift(fc); for (int f = 0; f < fc; f++) { integralShift[f] = gravis::d2Vector( round(centers[f].x) - s/2, round(centers[f].y) - s/2); } //简单的crop,如果 not visible,就全填0 extractSquares(stack, s, s, integralShift, isVisible, smallStack, false, num_threads); if (circle_crop) //默认关闭 { //在ctf前提前在原数据上crop circle cropCircle(smallStack, 0, EDGE_FALLOFF, num_threads); } std::vector<gravis::d2Vector> posInNewImg(fc); //根据crop位置调整每张图的投影矩阵 for (int f = 0; f < fc; f++) { projOut[f] = projIn[f]; projOut[f](0,3) += sb/2 - centers[f].x; projOut[f](1,3) += sb/2 - centers[f].y; posInNewImg[f] = (centers[f] - integralShift[f]) / bin; } BufferedImage<tComplex<T>> smallStackFS(sh,s,fc); NewStackHelper::FourierTransformStack_fast(smallStack, smallStackFS, true, num_threads); if (bin != 1.0) { //频域apply binning smallStackFS = Resampling::FourierCrop_fftwHalfStack( smallStackFS, bin, num_threads); //对应的数据scale smallStackFS /= (T) bin; } //返回频域数据 NewStackHelper::shiftStack(smallStackFS, posInNewImg, out, true, num_threads); }
回到
subtomo.cpp
for (int f = 0; f < fc; f++) { //看不见的view全是0,不用管 if (!isVisible[f]) continue; d3Matrix A; //计算particle自带的旋转(如果需要的话),默认不需要,即A是Identity矩阵 if (apply_orientations)//是否要在重建的particle上apply欧拉角旋转,默认关闭 { A = particleSet.getMatrix3x3(part_id); } else { A = particleSet.getSubtomogramMatrix(part_id); } projPart[f] = projCut[f] * d4Matrix(A); if (do_ctf)//默认开启 { const d3Vector pos = (apply_offsets) ? particleSet.getPosition(part_id) : particleSet.getParticleCoord(part_id); //根据输入的ctf参数计算每个2Dcropimage对应的频域ctf image CTF ctf = tomogram.getCtf(f, pos); BufferedImage<float> ctfImg(sh2D, s2D); ctf.draw(s2D, s2D, binnedPixelSize, gammaOffset, &ctfImg(0,0,0)); //默认开启,即把particle从黑的变成白的 const float sign = flip_value? -1.f : 1.f; for (int y = 0; y < s2D; y++) for (int x = 0; x < xRanges(y,f); x++) { const double c = ctfImg(x,y) * doseWeights(x,y,f); particleStack(x,y,f) *= sign * c; weightStack(x,y,f) = c * c; } } } ... //根据boxsize与cropsize做circle crop const int boundary = (boxSize - cropSize) / 2; if (do_gridding_precorrection || do_circle_crop) { BufferedImage<float> particlesRS; //在时域上做 particlesRS = NewStackHelper::inverseFourierTransformStack(particleStack); if (do_circle_crop)//默认开启 { const double crop_boundary = do_narrow_circle_crop? boundary : 0.0; TomoExtraction::cropCircle(particlesRS, crop_boundary, 5, num_threads);//在boundary边缘5个pixel进行平滑处理,再外面全设为0 } if (do_gridding_precorrection)//默认关闭 { TomoExtraction::griddingPreCorrect(particlesRS, boundary, num_threads); } particleStack = NewStackHelper::FourierTransformStack(particlesRS); } //开始做FBP BufferedImage<fComplex> dataImgFS(sh3D,s3D,s3D); dataImgFS.fill(fComplex(0.0, 0.0)); BufferedImage<float> ctfImgFS(sh3D,s3D,s3D), dataImgRS(s3D,s3D,s3D), dataImgDivRS(s3D,s3D,s3D), multiImageFS(sh3D,s3D,s3D); ctfImgFS.fill(0.0); dataImgRS.fill(0.0); dataImgDivRS.fill(0.0); for (int f = 0; f < fc; f++) { if (isVisible[f]) { //FBP时会将旋转后超过cropsize的部分扔掉,即在3D频域crop volume FourierBackprojection::backprojectSlice_forward_with_multiplicity( &xRanges(0,f), particleStack.getSliceRef(f), weightStack.getSliceRef(f), projPart[f] * relative_box_scale,//投影矩阵根据cropsize与boxsize做scale,relative_box_scale = crop_size/bos_size. dataImgFS, ctfImgFS, multiImageFS); } } Centering::shiftInSitu(dataImgFS); //因为有频域crop,需要调整数据scale if (s3D != s2D) { dataImgFS *= (float) sqrt(s2D / (double) s3D); } FFT::inverseFourierTransform(dataImgFS, dataImgRS, FFT::Both); //保存结果 dataImgRS.write(outData, binnedPixelSize, write_float16); if (write_ctf) { Centering::fftwHalfToHumanFull(ctfImgFS).write(outCTF, 1.0 / binnedPixelSize, write_float16); } ...
重建完后下一步就是3D initial model与autorefine。