From 71d75ea43ec687100fbfa1f1e824b16c778332d6 Mon Sep 17 00:00:00 2001 From: Ricardo Righetto Date: Thu, 23 May 2024 16:03:35 +0200 Subject: [PATCH 1/3] Added option to provide AlignZ value per tilt-series via text file --- aretomo/protocols/protocol_aretomo.py | 46 +++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/aretomo/protocols/protocol_aretomo.py b/aretomo/protocols/protocol_aretomo.py index 74559df..3a061b9 100644 --- a/aretomo/protocols/protocol_aretomo.py +++ b/aretomo/protocols/protocol_aretomo.py @@ -133,7 +133,19 @@ def _defineParams(self, form): 'Z height should be always smaller than tomogram ' 'thickness and should be close to the sample ' 'thickness.') - + + form.addParam('alignZfile', params.FileParam, + expertLevel=params.LEVEL_ADVANCED, + condition='not skipAlign and not useInputProt', + important=True, + label='File with volume height for alignment per tilt-series', + help='Specifies a text file containing the Z height (*unbinned*) ' + 'to be used for alignment for individual tomograms. ' + 'The file should have two columns, the first ' + 'containing the tsId and the second containing the AlignZ value ' + 'for that tilt series. You can specify one tilt-series ' + 'per line.') + form.addParam('tomoThickness', params.IntParam, condition='makeTomo', important=True, default=1200, label='Tomogram thickness unbinned (voxels)', @@ -346,6 +358,12 @@ def convertInputStep(self, tsObjId: int, tsId: str, tsFn: str): angleFilePath = self.getFilePath(tsFn, tmpPrefix, ".tlt") self._generateTltFile(ts, angleFilePath) + if not self.skipAlign: + alignZfile = self.alignZfile.get() + if alignZfile: + self.perTsAlignZ = self.readThicknessFile(alignZfile) + print('HERE2!') + if self.useInputProt: # Find and copy aln file protExtra = self.inputProt.get()._getExtraPath(tsId) @@ -404,8 +422,16 @@ def runAreTomoStep(self, tsObjId: int, tsId: str, tsFn: str): args['-TiltAxis'] = f"{tiltAxisAngle} {self.refineTiltAxis.get() - 1}" args['-TiltCor'] = self.refineTiltAngles.get() - 1 - if not self.skipAlign: + if self.alignZfile.get(): + # Check if we have AlignZ information per tilt-series: + if tsId in self.perTsAlignZ: + args['-AlignZ'] = self.perTsAlignZ[tsId] + else: + # Maybe this one TS is not present in the file, so we use the default AlignZ: + args['-AlignZ'] = self.alignZ + else: args['-AlignZ'] = self.alignZ + if self.sampleType.get() == LOCAL_MOTION_COORDS: args['-RoiFile'] = self.coordsFn @@ -730,6 +756,22 @@ def readingOutput(self) -> None: except AttributeError: # There is no outputSetOfTiltSeries pass + def readThicknessFile( self, filePath ): + # Reads a text file with thickness information per tilt-series + # + # Example of how the file should look like: + # Position_112 700 + # Position_35 650 + # Position_18 500 + # Position_114 1000 + + thickPerTs = {} + with open(filePath) as file: + for line in file: + lineParsed = line.split() + thickPerTs[lineParsed[0]] = int(lineParsed[1]) + return thickPerTs + def getFilePath(self, tsFn: Union[str, os.PathLike], prefix: str, From b9b6d7c5856547e2a2cfadf158c629e20e1acc5f Mon Sep 17 00:00:00 2001 From: Grigory Sharov Date: Sun, 26 May 2024 11:24:22 +0100 Subject: [PATCH 2/3] minor corrections --- CHANGES.txt | 1 + aretomo/protocols/protocol_aretomo.py | 50 ++++++++++++--------------- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index dbf54d7..1ffc4e2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,6 +2,7 @@ Users: - Add aretomo2 1.1.2 - Fix backwards compatibility. + - Add an option to specify AlignZ per TS. Developers: - The tests now use the Test Centralization Layer update and expansion of the used test set definition from em-tomo v3.6.0. diff --git a/aretomo/protocols/protocol_aretomo.py b/aretomo/protocols/protocol_aretomo.py index 3a061b9..bd1625d 100644 --- a/aretomo/protocols/protocol_aretomo.py +++ b/aretomo/protocols/protocol_aretomo.py @@ -137,13 +137,12 @@ def _defineParams(self, form): form.addParam('alignZfile', params.FileParam, expertLevel=params.LEVEL_ADVANCED, condition='not skipAlign and not useInputProt', - important=True, label='File with volume height for alignment per tilt-series', help='Specifies a text file containing the Z height (*unbinned*) ' - 'to be used for alignment for individual tomograms. ' + 'to be used for alignment of individual tilt-series. ' 'The file should have two columns, the first ' 'containing the tsId and the second containing the AlignZ value ' - 'for that tilt series. You can specify one tilt-series ' + 'for that tilt-series. You can specify one tilt-series ' 'per line.') form.addParam('tomoThickness', params.IntParam, @@ -299,7 +298,7 @@ def _defineParams(self, form): form.addHidden(params.GPU_LIST, params.StringParam, default='0', label="Choose GPU IDs") - form.addParallelSection(threads=2) + form.addParallelSection(threads=2, mpi=0) # --------------------------- INSERT steps functions ---------------------- def stepsGeneratorStep(self) -> None: @@ -358,11 +357,10 @@ def convertInputStep(self, tsObjId: int, tsId: str, tsFn: str): angleFilePath = self.getFilePath(tsFn, tmpPrefix, ".tlt") self._generateTltFile(ts, angleFilePath) - if not self.skipAlign: + if not self.skipAlign and self.alignZfile.hasValue(): alignZfile = self.alignZfile.get() - if alignZfile: + if os.path.exists(alignZfile): self.perTsAlignZ = self.readThicknessFile(alignZfile) - print('HERE2!') if self.useInputProt: # Find and copy aln file @@ -423,15 +421,10 @@ def runAreTomoStep(self, tsObjId: int, tsId: str, tsFn: str): args['-TiltCor'] = self.refineTiltAngles.get() - 1 if self.alignZfile.get(): - # Check if we have AlignZ information per tilt-series: - if tsId in self.perTsAlignZ: - args['-AlignZ'] = self.perTsAlignZ[tsId] - else: - # Maybe this one TS is not present in the file, so we use the default AlignZ: - args['-AlignZ'] = self.alignZ + # Check if we have AlignZ information per tilt-series + args['-AlignZ'] = self.perTsAlignZ.get(tsId, self.alignZ) else: args['-AlignZ'] = self.alignZ - if self.sampleType.get() == LOCAL_MOTION_COORDS: args['-RoiFile'] = self.coordsFn @@ -756,20 +749,23 @@ def readingOutput(self) -> None: except AttributeError: # There is no outputSetOfTiltSeries pass - def readThicknessFile( self, filePath ): - # Reads a text file with thickness information per tilt-series - # - # Example of how the file should look like: - # Position_112 700 - # Position_35 650 - # Position_18 500 - # Position_114 1000 - + def readThicknessFile(self, filePath: os.PathLike): + """ Reads a text file with thickness information per tilt-series. + Example of how the file should look like: + Position_112 700 + Position_35 650 + Position_18 500 + Position_114 1000 + """ thickPerTs = {} - with open(filePath) as file: - for line in file: - lineParsed = line.split() - thickPerTs[lineParsed[0]] = int(lineParsed[1]) + with open(filePath, "r") as f: + lines = f.readlines() + lines = filter(lambda x: x.strip(), lines) + + for line in lines: + values = line.split() + thickPerTs[values[0]] = values[1] + return thickPerTs def getFilePath(self, From 5d51afe6fe66a852deb007b8635acc2876fe3f95 Mon Sep 17 00:00:00 2001 From: Grigory Sharov Date: Tue, 28 May 2024 18:08:51 +0100 Subject: [PATCH 3/3] bugfix #74 --- CHANGES.txt | 1 + aretomo/protocols/protocol_aretomo.py | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 1ffc4e2..8fe1c38 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -3,6 +3,7 @@ - Add aretomo2 1.1.2 - Fix backwards compatibility. - Add an option to specify AlignZ per TS. + - fix dose weighting bug related to the tilt angle file (aretomo2 only) Developers: - The tests now use the Test Centralization Layer update and expansion of the used test set definition from em-tomo v3.6.0. diff --git a/aretomo/protocols/protocol_aretomo.py b/aretomo/protocols/protocol_aretomo.py index bd1625d..a266041 100644 --- a/aretomo/protocols/protocol_aretomo.py +++ b/aretomo/protocols/protocol_aretomo.py @@ -400,6 +400,9 @@ def runAreTomoStep(self, tsObjId: int, tsId: str, tsFn: str): '-Gpu': '%(GPU)s' } + if Plugin.getActiveVersion() != V1_3_4 and self.doDW: + args['-ImgDose'] = tsSet.getAcquisition().getDosePerFrame() + if Plugin.getActiveVersion() != V1_3_4 and self.doEstimateCtf.get(): # Manage the CTF estimation: # In AreTomo2, parameters PixSize, Kv and Cs are required to estimate the CTF. Since the first two are @@ -854,15 +857,17 @@ def _generateTltFile(self, ts: TiltSeries, outputFn: os.PathLike) -> None: """ Generate .tlt file with tilt angles and accumulated dose. """ angleList = [] + aretomo2 = Plugin.getActiveVersion() != V1_3_4 for ti in ts.iterItems(orderBy="_index"): + acqOrder = ti.getAcquisitionOrder() accDose = ti.getAcquisition().getAccumDose() tAngle = ti.getTiltAngle() - angleList.append((tAngle, accDose)) + angleList.append((tAngle, acqOrder if aretomo2 else accDose)) with open(outputFn, 'w') as f: if self.doDW: - f.writelines(f"{i[0]:0.3f} {i[1]:0.3f}\n" for i in angleList) + f.writelines(f"{i[0]:0.3f} {i[1]}\n" for i in angleList) else: f.writelines(f"{i[0]:0.3f}\n" for i in angleList)