Xmipp  v3.23.11-Nereus
reconstruct_art_xray.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 "reconstruct_art_xray.h"
28 #include "core/transformations.h"
29 
30 //ProgReconsXrayART::ProgReconsXrayART()
31 //{
32 //
33 //}
34 //ProgReconsXrayART::~ProgReconsXrayART()
35 //{
36 //
37 //}
39 {
40  addUsageLine("Generate 3D reconstructions from projections using ART on x-ray tomograms.");
41  addUsageLine("+This program reconstructs based on irregular grids given by pseudo atomic structures. ");
42  addUsageLine("+In case of regular grids, please refer to other programs as reconstruct_art ");
43  addUsageLine("+or reconstruct_fourier. Optionally, a deformation file generated by Nodal Mode ");
44  addUsageLine("+Alignment (NMA) can be passed with --nma parameter.");
45 
46  // addSeeAlsoLine("volume_to_pseudoatoms, nma_alignment");
47 
48  addParamsLine(" -i <md_file> : Metadata file with input projections");
49  addParamsLine(" [-o <volume_file=\"rec_xray_art.vol\">] : Filename for output volume.");
50  addParamsLine(" --psf <psf_param_file> : XRay-Microscope parameters file");
51  addParamsLine(" [--start <basisvolume_file=\"\">] : Start from this basis volume. The reconstruction is performed in the same grid as the one ");
52  addParamsLine(" : in which the basis volume was stored (any -FCC or -CC or grid size value are useless)");
53  addParamsLine(" [--sampling_rate <Ts=1>] : Pixel size (Angstrom)");
54  addParamsLine(" alias -s;");
55  addParamsLine(" [--threshold <thr=0.05>] : Normalized Threshold relative to maximum of PSF to reduce the volume into slabs");
56  addParamsLine(" [-l <lambda=0.1>] : Relaxation factor");
57  addParamsLine(" [-n <N=1>] : Number of iterations");
58  addParamsLine(" [--thr <N=1>] : Number of threads to use. NOTE: Not available when using MPI.");
59 
61  // addParamsLine(" == Basis Parameters ==");
62  // Basis::defineParams(this);
63 
64 }
65 
66 
68 {
69  fnDoc = getParam("-i");
70  fnOut = getParam("-o");
71  fnPSF = getParam("--psf");
72  fnStart = getParam("--start");
73  sampling = getDoubleParam("--sampling_rate");
74  lambdaART = getDoubleParam("-l");
75  Nit = getIntParam("-n");
76  psfThr = getDoubleParam("--threshold");
77  nThreads = getIntParam("--thr");
78 
79  // Basis parameters
80  // basis.readParams(this);
81 
82  psf.read(fnPSF);
83 
84 }
85 
87 {
88  MDin.read(fnDoc);
89 
90  ImageInfo imgInfo;
91  getImageInfo(MDin,imgInfo);
92  projXdim = imgInfo.adim.xdim;
93  projYdim = imgInfo.adim.ydim;
94 
95  psf.calculateParams(sampling*1.e-9, -1, psfThr); // sampling is read in nm
96  psf.nThr = nThreads;
97 
99  if ( fnStart.empty() )
100  {
101  volVoxels().resize(1, projXdim, projYdim, projXdim, false);
102  volVoxels().initZeros();
103  }
104  else
105  volVoxels.read(fnStart);
106 
107  volVoxels().setXmippOrigin();
108 
109  //Create threads to start working
111 
112 }
113 
115  double rot, double tilt, double psi)
116 {
117  // muVol.setXmippOrigin();
118 
119  size_t iniXdim, iniYdim, iniZdim, newXdim, newYdim, newZdim;
120 
121  iniXdim = XSIZE(muVol);
122  iniYdim = YSIZE(muVol);
123  iniZdim = ZSIZE(muVol);
124 
125  Projection projTheo, projNorm;
126  MultidimArray<double> Idiff;
127  const MultidimArray<double> &mdaProjExp = projExp();
128  MultidimArray<double> &mdaProjTheo = projTheo();
129  MultidimArray<double> &mdaProjNorm = projNorm();
130 
131  mdaProjTheo.initZeros(mdaProjExp);
132  projTheo.setAngles(projExp.rot(), projExp.tilt(), projExp.psi());
133 
134  mdaProjNorm.initZeros(mdaProjExp);
135 
136  newXdim = iniXdim;
137  newYdim = iniYdim;
138  newZdim = iniZdim;
139 
140  MultidimArray<double> rotVol;
141 
142  rotVol.resizeNoCopy(newZdim, newYdim, newXdim);
143  rotVol.setXmippOrigin();
144 
145  // Rotate volume ....................................................
146 
148 
149  Euler_angles2matrix(projExp.rot(), projExp.tilt(), projExp.psi(), R, true);
150 
151  double outside = 0; //phantom.iniVol.getPixel(0,0,0,0);
152 
153  applyGeometry(xmipp_transformation::LINEAR, rotVol, muVol, R, xmipp_transformation::IS_NOT_INV, xmipp_transformation::DONT_WRAP, outside);
154 
155  psf.adjustParam(rotVol);
156 
158  MultidimArray<double> IgeoZb;
159  IgeoVol.resize(rotVol, false);
160  IgeoZb.resize(1, 1, YSIZE(rotVol), XSIZE(rotVol),false);
161  IgeoZb.initConstant(1.);
162 
163 // calculateIgeo(rotVol, psf.dzo, IgeoVol, IgeoZb, psf.nThr, thMgr);
164 
165  Image<double> imTemp;
166  imTemp().alias(IgeoVol);
167  imTemp.write("IgeoVol.vol");
168 
170 
171  // projectXrayVolume(rotVol, IgeoVol, psf, projTheo, &mdaProjNorm, thMgr);
172  //
173  // projTheo.write("theproj.spi");
174  // projNorm.write("projNorm.spi");
175 
176  projectXrayGridVolume(muVol, psf, IgeoVol, projTheo, &mdaProjNorm, FORWARD, thMgr);
177 
178  projTheo.write("theproj.spi");
179  projNorm.write("projNorm.spi");
180 
181 
182  // projectXrayGridVolume(volBasis, basis, IgeoVol, projTheo, projNorm, FORWARD, nThreads);
183 
184  double mean_error = 0;
185  Idiff.initZeros(mdaProjExp);
186 
188  {
189  // Compute difference image and error
190  DIRECT_A2D_ELEM(Idiff, i, j) = DIRECT_A2D_ELEM(mdaProjExp, i, j) - DIRECT_A2D_ELEM(mdaProjTheo, i, j);
191  mean_error += DIRECT_A2D_ELEM(Idiff, i, j) * DIRECT_A2D_ELEM(Idiff, i, j);
192 
193  // Compute the correction image
194  DIRECT_A2D_ELEM(mdaProjNorm, i, j) = XMIPP_MAX(DIRECT_A2D_ELEM(mdaProjNorm, i, j), 1);
195  DIRECT_A2D_ELEM(mdaProjNorm, i, j) =
196  lambdaART * DIRECT_A2D_ELEM(Idiff, i, j) / DIRECT_A2D_ELEM(mdaProjNorm, i, j);
197  }
198  mean_error /= YXSIZE(mdaProjExp);
199 
200  projNorm.write("projNorm_2.spi");
201 
202  imTemp().alias(Idiff);
203  imTemp.write("iDiff.spi");
204 
205  projectXrayGridVolume(muVol, psf, IgeoVol, projTheo, &mdaProjNorm, BACKWARD, thMgr);
206 
207  return mean_error;
208 }
209 
211 {
212  // show();
213 
214  Image<double> volVoxels;
215 
216 
217  preProcess(volVoxels);
218  Projection projExp;
219  for (int it=0; it<Nit; it++)
220  {
221  // preIteration();
222  double itError=0;
223  for (size_t objId : MDin.ids())
224  {
225  FileName fnExp;
226  MDin.getValue( MDL_IMAGE, fnExp,objId);
227  double rot;
228  MDin.getValue( MDL_ANGLE_ROT, rot,objId);
229  double tilt;
230  MDin.getValue( MDL_ANGLE_TILT, tilt,objId);
231  double psi;
232  MDin.getValue( MDL_ANGLE_PSI, psi,objId);
233  double shiftX;
234  MDin.getValue( MDL_SHIFT_X, shiftX,objId);
235  double shiftY;
236  MDin.getValue( MDL_SHIFT_Y, shiftY,objId);
237 
238  projExp.read(fnExp);
239  projExp().setXmippOrigin();
240  projExp.setAngles(rot, tilt, psi);
241 
242  itError += singleStep(MULTIDIM_ARRAY(volVoxels), projExp, rot, tilt, psi);
243  }
244  // postIteration();
245 
246  if (MDin.size()>0)
247  itError/=MDin.size();
248  std::cerr << "Error at iteration " << it << " = " << itError << std::endl;
249  }
250 
251  volVoxels.write(fnOut);
252 }
double singleStep(MultidimArray< double > &muVol, const Projection &projExp, double rot, double tilt, double psi)
Rotation angle of an image (double,degrees)
#define YSIZE(v)
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
size_t xdim
double getDoubleParam(const char *param, int arg=0)
FileName fnDoc
Selfile with the input images.
void read(const FileName &inFile, const std::vector< MDLabel > *desiredLabels=nullptr, bool decomposeStack=true) override
double psi(const size_t n=0) const
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY2D(m)
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
void resizeNoCopy(const MultidimArray< T1 > &v)
Tilting angle of an image (double,degrees)
FileName fnStart
Start Volume Filename.
Shift for the image in the X axis (double)
void applyGeometry(int SplineDegree, MultidimArray< std::complex< double > > &V2, const MultidimArray< std::complex< double > > &V1, const Matrix2D< double > &A, bool inv, bool wrap, std::complex< double > outside, MultidimArray< double > *BcoeffsPtr)
#define DIRECT_A2D_ELEM(v, i, j)
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)
#define MULTIDIM_ARRAY(v)
double lambdaART
Lambda.
Special label to be used when gathering MDs in MpiMetadataPrograms.
void initConstant(T val)
#define BACKWARD
Definition: blobs.cpp:1092
ThreadManager * thMgr
double rot(const size_t n=0) const
virtual IdIteratorProxy< false > ids()
int projXdim
Projection X dimension.
int nThr
Definition: psf_xr.h:215
FileName fnOut
Output filename.
size_t size() const override
#define i
double tilt(const size_t n=0) const
void projectXrayGridVolume(MultidimArray< double > &muVol, XRayPSF &psf, MultidimArray< double > &IgeoVol, Projection &proj, MultidimArray< double > *projNorm, int FORW, ThreadManager *thMgr)
Project as in an X-ray microscope using a grids and blobs.
double psfThr
threshold for psfSlabs
void getImageInfo(const MetaData &md, size_t &Xdim, size_t &Ydim, size_t &Zdim, size_t &Ndim, DataType &datatype, MDLabel image_label)
const char * getParam(const char *param, int arg=0)
void read(const FileName &fn, bool readVolume=true)
Definition: psf_xr.cpp:82
int Nit
Number of iterations.
void preProcess(Image< double > &volVoxels)
#define XSIZE(v)
#define ZSIZE(v)
ArrayDim adim
void calculateParams(double _dxo, double _dzo=-1, double threshold=0.)
Produce Side information.
Definition: psf_xr.cpp:279
int projYdim
Projection Y dimension.
MetaDataVec MDin
Metadata with projections info.
#define j
#define FORWARD
Definition: blobs.cpp:1091
FileName fnPSF
psf Filename
void adjustParam()
Calculate if a resize of the X-Y plane is needed to avoid the Nyquist Limit.
Definition: psf_xr.cpp:673
bool getValue(MDObject &mdValueOut, size_t id) const override
XRayPSF psf
Microscope parameters.
double psi(const double x)
void read(const FileName &fn, const bool only_apply_shifts=false, DataMode datamode=DATA, MDRow *row=nullptr)
size_t ydim
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
Shift for the image in the Y axis (double)
void addUsageLine(const char *line, bool verbatim=false)
void setAngles(double _rot, double _tilt, double _psi)
void initZeros(const MultidimArray< T1 > &op)
int getIntParam(const char *param, int arg=0)
#define YXSIZE(v)
MultidimArray< double > IgeoVol
Vol with the Igeometrical distribution along specimen volume.
Name of an image (std::string)
double sampling
Sampling rate.
void addParamsLine(const String &line)