Xmipp  v3.23.11-Nereus
idr_xray_tomo.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Authors: Joaquin Oton (joton@cnb.csic.es)
3  *
4  *
5  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307 USA
21  *
22  * All comments concerning this program package may be sent to the
23  * e-mail address 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 
26 #include "idr_xray_tomo.h"
28 #include <data/filters.h>
29 #include "reconstruct_fourier.h"
30 #include "reconstruct_art.h"
31 
33 {
34  addUsageLine("Iterative Data Refinement applied to the reconstruction of X-ray tomography projections.");
35  //Params
36  // projParam.defineParams(this); // Projection parameters
37  addParamsLine("-i <md_file> : Metadata file with input projections");
38  addParamsLine("alias --input;");
39  addParamsLine(" [--oroot <rootname=\"idr_xray\">] : Rootname used for refined projections");
40  addParamsLine(" [-o <Vol_file=\"idr_recon_vol.mrc\">] : Filename for refined output volume");
41  addParamsLine("alias --output;");
42  addParamsLine(" [--start <start_vol_file=\"\">] : Start from this basis volume. The reconstruction is performed in the same grid as the one ");
43  addParamsLine(" [-s <Ts>] : Sampling rate (nm)");
44  addParamsLine("alias --sampling_rate;");
45  addParamsLine("[--thr <threads=1>] : Number of concurrent threads.");
46 
47  addParamsLine("== Iterations options == ");
48  addParamsLine(" [-l <...>] : Relaxation factor, by default 1.8 (recommended range 0.0 - 2.0). ");
49  addParamsLine(" : A list of lambda values is also accepted as \"-l lambda0 lambda1 ...\"");
50  addParamsLine(" [-n <noit=1>] : Number of iterations");
51 
52  addParamsLine("== Reconstruction options == ");
53  addParamsLine("[--recons <recons_type=ART>] : Reconstruction method to be used");
54  addParamsLine(" where <recons_type> ");
55  addParamsLine(" ART <params=\"\"> : wlsART parameters");
56  addParamsLine(" fourier <params=\"\"> : fourier parameters");
57  addParamsLine(" tomo3d <params=\"\"> : tomo3d parameters");
58 
59 
60  addParamsLine("== Xray options == ");
61  addParamsLine("[--psf <psf_param_file=\"\">] : XRay-Microscope parameters file. If not set, then default parameters are chosen.");
62  addParamsLine("[--threshold <thr=0.0>] :+ Normalized threshold relative to maximum of PSF to reduce the volume into slabs");
63  //Examples
64  //Example projection file
65  // addExampleLine("In the following link you can find an example of projection parameter file:",false);
66  // addExampleLine(" ",false);
67  // addExampleLine("http://newxmipp.svn.sourceforge.net/viewvc/newxmipp/trunk/testXmipp/input/tomoProjection.param",false);
68  // addExampleLine(" ",false);
69  // addExampleLine("In the following link you can find an example of X-ray microscope parameters file:",false);
70  // addExampleLine(" ",false);
71  // addExampleLine("http://newxmipp.svn.sourceforge.net/viewvc/newxmipp/trunk/testXmipp/input/xray_psf.xmd",false);
72 }
73 
74 /* Read from command line ================================================== */
76 {
77  fnInputProjMD = getParam("-i");
78  fnOutVol = getParam("-o");
79  fnRootInter = getParam("--oroot");
80  fnStart = getParam("--start");
81  // projParam.readParams(this);
82 
83  fnPSF = getParam("--psf");
84  sampling = (checkParam("-s"))? getDoubleParam("-s")*1e-9 : -1 ;
85  psfThr = getDoubleParam("--threshold");
86  nThr = getIntParam("--thr");
87 
88  // Iteration parameters
89  StringVector list;
90  getListParam("-l", list);
91  size_t listSize = list.size();
92 
93  if (listSize != 0)
94  {
95  lambda_list.resizeNoCopy(listSize);
96 
97  for (size_t k = 0; k < listSize; k++)
98  VEC_ELEM(lambda_list, k) = textToFloat(list[k]);
99  }
100  else
101  {
103  VEC_ELEM(lambda_list, 0) = 1.8;
104  }
105 
106  itNum = getIntParam("-n");
107 
108  // Reconstruction
109  if (STR_EQUAL(getParam("--recons"), "ART"))
111  else if (STR_EQUAL(getParam("--recons"), "fourier"))
113  else if (STR_EQUAL(getParam("--recons"), "tomo3d"))
115 
116 
117 
118 }//readParams
119 
120 
121 
123 {
124  psf.read(fnPSF);
125  psf.verbose = verbose;
126  psf.nThr = nThr;
127 
129 
130  // Threads stuff
131  barrier = new Barrier(nThr);
132  //Create threads to start working
133  thMgr = new ThreadManager(nThr);
134 
135  // Reading the input projections. Tilt angle values are needed
137 
138  // Setting the intermediate filenames
139  fnInterProjs = fnRootInter + "_inter_projs";
140  fnInterProjs += (reconsMethod == RECONS_TOMO3D)? ".mrc" : ".stk";
141 
143  fnInterAngles = fnRootInter + "_angles.txt";
144 
145  // We make sure to delete intermediate files
148 
149  FileName fnProjs;
151  // We generate the MD of temporary projections to be used for further reconstructions
155 
156  String arguments = formatString("-i %s -o %s -s",
157  fnInputProjMD.c_str(), fnInterProjs.c_str());
158  ProgConvImg conv;
159  conv.read(arguments);
160  conv.run();
161 
162  // Saving angles in plain text to pass to tomo3D
163  if ( reconsMethod == RECONS_TOMO3D )
164  {
165  std::vector<MDLabel> desiredLabels;
166  desiredLabels.push_back(MDL_ANGLE_TILT);
167  projMD.writeText(fnInterAngles, &desiredLabels);
168  }
169 
170  if (fnStart.empty()) // if initial volume is not passed,then we must calculate it
171  {
172  // Projections must be in an MRC stack to be passed
173  if ( reconsMethod == RECONS_TOMO3D )
175  else
176  {
179  }
180  }
181  else
183 }
184 
186 {
187  preRun();
188 
189  Projection proj, stdProj;
190  Image<double> fixedProj, prevFProj;
191  MultidimArray<double> mFixedProj, mPrevFProj;
192 
193 
194  double rot, tilt, psi;
195 
196  double lambda = VEC_ELEM(lambda_list, 0);
197 
198  FileName fnProj;
199 
200  for (int iter = 0; iter < itNum; iter++)
201  {
202  std::cout << "== Iteration " << iter << std::endl;
203  std::cout << "Projecting ..." <<std::endl;
204 
205  // Fix the reconstructed volume to physical density values
206  double factor = 1/sampling;
207  MULTIDIM_ARRAY(phantom.iniVol) *= factor;
208  // remove negative values
210 
212  size_t imgNo = 1; // Image number
213  double meanError = 0.;
214 
215  for (size_t objId : projMD.ids())
216  {
217  projMD.getValue(MDL_IMAGE , fnProj, objId);
218  projMD.getValue(MDL_ANGLE_ROT , rot, objId);
219  projMD.getValue(MDL_ANGLE_TILT, tilt, objId);
220  projMD.getValue(MDL_ANGLE_PSI , psi, objId);
221  proj.setAngles(rot, tilt, psi);
222 
225 
226  /* Image normalization to optimize for reconstruction.
227  * To correct for self-attenuation (without considering 3DPSF)
228  * I = -ln(Iab)
229  */
230 // FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(MULTIDIM_ARRAY(proj))
231 // dAi(MULTIDIM_ARRAY(proj),n) = -log(1. - dAi(MULTIDIM_ARRAY(proj),n));
232 
233 
234  fixedProj.read(fnProj);
235  mFixedProj.alias(MULTIDIM_ARRAY(fixedProj));
236 
238  dAi(mFixedProj, n) = (log(1. - dAi(MULTIDIM_ARRAY(proj),n)) - log(dAi(mFixedProj, n)))*lambda + dAi(MULTIDIM_ARRAY(stdProj),n);
239 
240  prevFProj.read(fnInterProjs, DATA, imgNo); // To calculate meanError
241  mPrevFProj.alias(MULTIDIM_ARRAY(prevFProj));
242 
243  // Write the refined projection
244  fixedProj.write(fnInterProjs, imgNo, true, WRITE_REPLACE);
245 
246  // debug stuff //
247  if (verbose > 5)
248  {
249  proj.write(fnRootInter + "_debug_proj.stk", imgNo , true, WRITE_REPLACE);
250  stdProj.write(fnRootInter + "_debug_std_proj.stk", imgNo , true, WRITE_REPLACE);
251 
253  dAi(mFixedProj, n) = dAi(MULTIDIM_ARRAY(stdProj),n) - dAi(MULTIDIM_ARRAY(proj),n)*lambda ;
254 
255  fixedProj.write(fnRootInter + "_debug_diff_proj.stk", imgNo , true, WRITE_REPLACE);
256  }
257 
259  meanError += fabs(dAi(mPrevFProj, n) - dAi(mFixedProj, n));
260 
261  ++imgNo;
262  // Update progress bar
263  setProgress();
264  }
265  // Once calculated all fixed projection, let reconstruct again
266  endProgress();
267 
268  meanError /= (NZYXSIZE(mFixedProj)*projMD.size());
269 
270  std::cout << "Mean error = " << meanError <<std::endl;
271 
272  std::cout << "Reconstructing ..." << std::endl;
274 
275  if ( (iter < itNum-1) && (reconsMethod != RECONS_TOMO3D) ) // Since we process the output of tomo3d, this is already read
277 
278  }
279 
280  // Finish progress bar
281 
282  if (reconsMethod == RECONS_TOMO3D) // Trick to save the processed output of tomo3d
284 
285 }
286 
287 void ProgIDRXrayTomo::reconstruct(const FileName &fnProjsMD, const FileName &fnVol)
288 {
290  {
291  MetaDataVec MD(fnProjsMD);
292  FileName fnProjs;
293  MD.getValue(MDL_IMAGE, fnProjs, MD.firstRowId());
294 
295  reconsTomo3D(fnInterAngles, fnProjs.removePrefixNumber(), fnVol);
296  phantom.read(fnVol);
297  MULTIDIM_ARRAY(phantom.iniVol).resetOrigin();
299  //FIXME: this is a temporary fixing to match the reconstructed volume with phantom
300  double factor = 1/13.734;
301  MULTIDIM_ARRAY(phantom.iniVol) *= factor;
302  }
303  else
304  {
305  reconsProgram = createReconsProgram(fnProjsMD, fnVol);
306  reconsProgram->run();
307  delete reconsProgram;
308  }
309 }
310 
311 int reconsTomo3D(const MetaData& MD, const FileName& fnOut, const String& params)
312 {
313  // Saving angles in plain text to pass to tomo3D
314  FileName fnAngles("idr_xray_tomo_to_tomo3d_angles.txt");
315  std::vector<MDLabel> desiredLabels;
316  desiredLabels.push_back(MDL_ANGLE_TILT);
317  MD.writeText(fnAngles, &desiredLabels);
318 
319  FileName fnProjs;
320 
321  MD.getValue(MDL_IMAGE, fnProjs, MD.firstRowId());
322 
323  // Projections must be in an MRC stack to be passed
324  if ( !(fnProjs.isInStack() && (fnProjs.contains("mrc") || fnProjs.contains("st"))))
325  {
326  //FIXME: To be implemented the conversion to an MRC stack
327 
328  REPORT_ERROR(ERR_IMG_NOREAD, "reconsTromo3D: Image format cannot be read by tomo3D.");
329  }
330 
331  return reconsTomo3D(fnAngles, fnProjs.removePrefixNumber(), fnOut, params);
332 }
333 
334 int reconsTomo3D(const FileName& fnAngles, const FileName& fnProjs,
335  const FileName& fnOut, const String& params)
336 {
337  String exec("tomo3d -n -f -v 0 -a "+fnAngles+" -i "+fnProjs.removeAllPrefixes()+" -o "+fnOut+" "+params);
338  return system(exec.c_str());
339 }
340 
341 
343 {
344  //get reconstruction extra params
345  String arguments = getParam("--recons", 1) +
346  formatString(" -v 0 --thr %d -i %s -o %s", nThr, input.c_str(), output.c_str());
347  ProgReconsBase * program;
348  // std::cerr << "DEBUG_JM: ProgMLRefine3D::createReconsProgram" <<std::endl;
349  // std::cerr << "DEBUG_JM: arguments: " << arguments << std::endl;
350  // std::cerr << "DEBUG_JM: input: " << input << std::endl;
351 
353  {
354  program = new ProgRecFourier();
355  //force use of weights and the verbosity will be the same of this program
356  //-i and -o options are passed for avoiding errors, this should be changed
357  //when reconstructing
358  // arguments += " --weight";
359  program->read(arguments);
360  return program;
361  }
362  else if (reconsMethod == RECONS_ART)//use of Art
363  {
364  //REPORT_ERROR(ERR_NOT_IMPLEMENTED,"not implemented reconstruction through wlsArt");
365  program = new ProgReconsART();
366  FileName fn_tmp(arguments);
367  // arguments += " --WLS";
368  // if (fn_symmask.empty() && checkParam("--sym"))
369  // arguments += " --sym " + fn_sym;
370  if (!fn_tmp.contains("-n "))
371  arguments += " -n 10";
372  if (!fn_tmp.contains("-l "))
373  arguments += " -l 0.2";
374  // if (!fn_tmp.contains("-k "))
375  // arguments += " -k 0.5";
376 
377  program->read(arguments);
378  return program;
379  }
380  return nullptr;
381 }
382 
383 
384 
#define dAi(v, i)
int nThr
Number of threads;.
Definition: idr_xray_tomo.h:64
Rotation angle of an image (double,degrees)
#define YSIZE(v)
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
FileName fnInterAngles
Definition: idr_xray_tomo.h:48
int itNum
Number of iterations.
Definition: idr_xray_tomo.h:68
double getDoubleParam(const char *param, int arg=0)
virtual void read(int argc, const char **argv, bool reportErrors=true)
void read(const FileName &inFile, const std::vector< MDLabel > *desiredLabels=nullptr, bool decomposeStack=true) override
void forcePositive(MultidimArray< double > &V)
Definition: filters.cpp:3506
FileName fnPSF
Xray Microscope PSF Parameters.
Definition: idr_xray_tomo.h:56
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
FileName replaceExtension(const String &newExt) const
ThreadManager * thMgr
void reconstruct(const FileName &fnProjs, const FileName &fnVol)
Tilting angle of an image (double,degrees)
virtual size_t firstRowId() const =0
FileName removePrefixNumber() const
void writeText(const FileName fn, const std::vector< MDLabel > *desiredLabels) const override
FileName fnRootInter
Rootname for intermediate/exchange projections metadatas and files.
Definition: idr_xray_tomo.h:45
void initProgress(size_t total, size_t stepBin=60)
void write(const FileName &name="", size_t select_img=ALL_IMAGES, bool isStack=false, int mode=WRITE_OVERWRITE, CastWriteMode castMode=CW_CAST, int _swapWrite=0)
void replace(const MDLabel label, const String &oldStr, const String &newStr)
#define MULTIDIM_ARRAY(v)
ProgReconsBase * createReconsProgram(const FileName &input, const FileName &output)
void XrayRotateAndProjectVolumeOffCentered(XrayProjPhantom &phantom, XRayPSF &psf, Projection &P, Projection &standardP, int Ydim, int Xdim)
Special label to be used when gathering MDs in MpiMetadataPrograms.
Image< double > iniVol
Phantom Xmipp volume.
Definition: project_xray.h:65
void write(const FileName &outFile, WriteModeMetaData mode=MD_OVERWRITE) const
Cannot read image from file.
Definition: xmipp_error.h:128
FileName fnInputProjMD
Metadafile with angles and projection file names.
Definition: idr_xray_tomo.h:43
glob_prnt iter
virtual void defineParams()
void getListParam(const char *param, StringVector &list)
virtual IdIteratorProxy< false > ids()
int nThr
Definition: psf_xr.h:215
XRayPSF psf
Xray PSF Object.
Definition: idr_xray_tomo.h:58
FileName fnOutVol
Reconstructed output volume file name.
Definition: idr_xray_tomo.h:50
std::vector< String > StringVector
Definition: xmipp_strings.h:35
virtual bool getValue(MDObject &mdValueOut, size_t id) const =0
size_t size() const override
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
XrayProjPhantom phantom
Definition: idr_xray_tomo.h:86
FileName removeAllPrefixes() const
virtual void writeText(const FileName fn, const std::vector< MDLabel > *desiredLabels) const =0
Barrier * barrier
ProgReconsBase * reconsProgram
Definition: idr_xray_tomo.h:81
void log(Image< double > &op)
const char * getParam(const char *param, int arg=0)
virtual void run()
double * lambda
virtual void readParams()
void read(const FileName &fn, bool readVolume=true)
Definition: psf_xr.cpp:82
FileName fnStart
Initial volume.
Definition: idr_xray_tomo.h:52
float textToFloat(const char *str)
MetaDataVec interProjMD
Definition: idr_xray_tomo.h:85
size_t firstRowId() const override
FileName fnOut
int reconsTomo3D(const MetaData &MD, const FileName &fnOut, const String &params)
#define XSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
int verbose
Switch to control verbose mode.
Definition: psf_xr.h:212
#define NZYXSIZE(v)
int verbose
Verbosity level.
bool contains(const String &str) const
void alias(const MultidimArray< T > &m)
#define STR_EQUAL(str1, str2)
Definition: xmipp_strings.h:42
virtual void run()
void calculateParams(double _dxo, double _dzo=-1, double threshold=0.)
Produce Side information.
Definition: psf_xr.cpp:279
void deleteFile() const
bool getValue(MDObject &mdValueOut, size_t id) const override
void setProgress(size_t value=0)
void read(const ParametersProjectionTomography &prm)
std::string String
Definition: xmipp_strings.h:34
double psi(const double x)
double psfThr
threshold for psfSlabs
Definition: idr_xray_tomo.h:60
Projection proj
Definition: idr_xray_tomo.h:87
String formatString(const char *format,...)
void resizeNoCopy(int Xdim)
Definition: matrix1d.h:458
bool checkParam(const char *param)
MetaDataVec projMD
Definition: idr_xray_tomo.h:84
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
FileName fnInterProjs
Definition: idr_xray_tomo.h:46
void addUsageLine(const char *line, bool verbatim=false)
void setAngles(double _rot, double _tilt, double _psi)
int getIntParam(const char *param, int arg=0)
FileName fnInterProjsMD
Definition: idr_xray_tomo.h:47
int * n
Name of an image (std::string)
void addParamsLine(const String &line)
bool isInStack() const
Matrix1D< double > lambda_list
Relaxation parameter.
Definition: idr_xray_tomo.h:70
enum ProgIDRXrayTomo::@5 reconsMethod