Xmipp  v3.23.11-Nereus
transform_adjust_image_grey_levels.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar Sanchez Sorzano coss@cnb.csic.es
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 
27 #include "data/mask.h"
28 
29 // Empty constructor =======================================================
31 {
32  produces_a_metadata = true;
34  projector = nullptr;
35 }
36 
38 {
39  delete projector;
40 }
41 
42 // Read arguments ==========================================================
44 {
46  fnVol = getParam("--ref");
47  maxResol = getDoubleParam("--max_resolution");
48  maxA = getDoubleParam("--max_gray_scale");
49  maxB = getDoubleParam("--max_gray_shift");
50  Ts = getDoubleParam("--sampling");
51  Rmax = getIntParam("--Rmax");
52  pad = getIntParam("--padding");
53 }
54 
55 // Show ====================================================================
57 {
58  if (!verbose)
59  return;
61  std::cout
62  << "Reference volume: " << fnVol << std::endl
63  << "Max. Resolution: " << maxResol << std::endl
64  << "Max. Gray Scale: " << maxA << std::endl
65  << "Max. Gray Shift: " << maxB << std::endl
66  << "Sampling: " << Ts << std::endl
67  << "Max. Radius: " << Rmax << std::endl
68  << "Padding factor: " << pad << std::endl
69  ;
70 }
71 
72 // usage ===================================================================
74 {
75  addUsageLine("Make a continuous angular assignment");
76  defaultComments["-i"].clear();
77  defaultComments["-i"].addComment("Metadata with images and alignment");
78  defaultComments["-o"].clear();
79  defaultComments["-o"].addComment("Stack of images prepared for 3D reconstruction");
81  addParamsLine(" --ref <volume> : Reference volume");
82  addParamsLine(" [--max_resolution <f=4>] : Maximum resolution (A)");
83  addParamsLine(" [--max_gray_scale <a=0.05>] : Maximum gray scale change");
84  addParamsLine(" [--max_gray_shift <b=0.05>] : Maximum gray shift change as a factor of the image standard deviation");
85  addParamsLine(" [--sampling <Ts=1>] : Sampling rate (A/pixel)");
86  addParamsLine(" [--Rmax <R=-1>] : Maximum radius (px). -1=Half of volume size");
87  addParamsLine(" [--padding <p=2>] : Padding factor");
88 }
89 
90 // Produce side information ================================================
92 {
93  // Read the reference volume
94  Image<double> V;
95  V.read(fnVol);
96  V().setXmippOrigin();
97  Xdim=XSIZE(V());
98 
99  // Construct mask
100  if (Rmax<0)
101  Rmax=Xdim/2;
102  Mask mask;
103  mask.type = BINARY_CIRCULAR_MASK;
104  mask.mode = INNER_MASK;
105  mask.R1 = Rmax;
106  mask.generate_mask(Xdim,Xdim);
107  mask2D=mask.get_binary_mask();
108  iMask2Dsum=1.0/mask2D.sum();
109 
110  // Construct projector
112 
113  // Low pass filter
116  filter.raised_w=0.02;
117 }
118 
120 {
121  if (fabs(a-1)>prm->maxA)
122  return 1e38;
123  if (fabs(b)>prm->maxB*prm->Istddev)
124  return 1e38;
125 
126  double cost=0;
127  const MultidimArray<double> &mP=prm->P();
128  const MultidimArray<int> &mMask2D=prm->mask2D;
129  MultidimArray<double> &mIfiltered=prm->Ifiltered();
131  {
132 // if (DIRECT_MULTIDIM_ELEM(mMask2D,n))
133  {
134  double val=fabs((a*DIRECT_MULTIDIM_ELEM(mP,n)+b)-DIRECT_MULTIDIM_ELEM(mIfiltered,n));
135  cost+=val*val;
136  }
137  }
138  cost*=prm->iMask2Dsum;
139  return cost;
140 }
141 
142 double transformImageGrayCostAB(double *x, void *_prm)
143 {
144  return transformImageGrayCost(x[1],x[2],(ProgTransformImageGreyLevels *)_prm);
145 }
146 
147 double transformImageGrayCostBA(double *x, void *_prm)
148 {
149  return transformImageGrayCost(x[2],x[1],(ProgTransformImageGreyLevels *)_prm);
150 }
151 
152 // Predict =================================================================
153 //#define DEBUG
154 void ProgTransformImageGreyLevels::processImage(const FileName &fnImg, const FileName &fnImgOut, const MDRow &rowIn, MDRow &rowOut)
155 {
156  rowOut=rowIn;
157 
158  // Read input image and initial parameters
159  double rot, tilt, psi;
160  rowIn.getValue(MDL_ANGLE_ROT,rot);
161  rowIn.getValue(MDL_ANGLE_TILT,tilt);
162  rowIn.getValue(MDL_ANGLE_PSI,psi);
163 
164  double olda=1.0, oldb=0.0;
166  rowIn.getValue(MDL_CONTINUOUS_GRAY_A,olda);
167  rowIn.getValue(MDL_CONTINUOUS_GRAY_B,oldb);
168  }
169 
170  I.read(fnImg);
171  I().setXmippOrigin();
172  Istddev=I().computeStddev();
173 
174  Ifiltered()=I();
176 
177  projectVolume(*projector, P, (int)XSIZE(I()), (int)XSIZE(I()), rot, tilt, psi);
178 
179 #ifdef DEBUG
180  Image<double> save;
181  save()=P();
182  std::cout << "P: "; P().printStats(); std::cout << std::endl;
183  save.write("PPPprojection.xmp");
184  save()=I();
185  std::cout << "I: "; I().printStats(); std::cout << std::endl;
186  save.write("PPPexperimental.xmp");
187  save()=P()-I();
188  std::cout << "P-I init: "; save().printStats(); std::cout << std::endl;
189  save.write("PPPdiffInit.xmp");
190 #endif
191 
192  Matrix1D<double> pAB(2), steps(2), pBA(2), p(2);
193  steps.initConstant(1);
194 
195  // Optimize
196  double costAB=-1, costBA=-1;
197  int iter;
198  try
199  {
200  costAB=1e38;
201  pAB(0)=olda; // a in I'=a*I+b
202  pAB(1)=oldb; // b in I'=a*I+b
203  powellOptimizer(pAB, 1, 2, &transformImageGrayCostAB, this, 0.01, costAB, iter, steps, verbose>=2);
204  if (costAB>1e30)
205  {
206  rowOut.setValue(MDL_ENABLED,-1);
207  pAB.initZeros();
208  pAB(0)=1; // a in I'=a*I+b
209  pAB(1)=0; // b in I'=a*I+b
210  }
211 
212  costBA=1e38;
213  pBA(0)=oldb; // a in I'=a*I+b
214  pBA(1)=olda; // b in I'=a*I+b
215  powellOptimizer(pBA, 1, 2, &transformImageGrayCostBA, this, 0.01, costBA, iter, steps, verbose>=2);
216  if (costBA>1e30)
217  {
218  rowOut.setValue(MDL_ENABLED,-1);
219  pBA.initZeros();
220  pBA(0)=0; // a in I'=a*I+b
221  pBA(1)=1; // b in I'=a*I+b
222  }
223 
224  // Decide
225  if (costAB<costBA)
226  p=pAB;
227  else
228  {
229  p(0)=pBA(1);
230  p(1)=pBA(0);
231  }
232 
233  // Apply
234  MultidimArray<double> &mI=I();
235  double ia=1.0/p(0);
236  double b=p(1);
238  {
239  if (DIRECT_MULTIDIM_ELEM(mask2D,n) || true)
241  else
242  DIRECT_MULTIDIM_ELEM(mI,n)=0.0;
243  }
244  rowOut.setValue(MDL_IMAGE,fnImgOut);
245  I.write(fnImgOut);
246  }
247  catch (XmippError XE)
248  {
249  std::cerr << XE.what() << std::endl;
250  std::cerr << "Warning: Cannot refine " << fnImg << std::endl;
251  rowOut.setValue(MDL_ENABLED,-1);
252  }
253  rowOut.setValue(MDL_CONTINUOUS_GRAY_A,p(0));
254  rowOut.setValue(MDL_CONTINUOUS_GRAY_B,p(1));
255 
256 #ifdef DEBUG
257  save()=I();
258  save.write("PPPexperimentalCorrected.xmp");
259  std::cout << "I corrected: "; I().printStats(); std::cout << std::endl;
260  save()=P()-I();
261  std::cout << "P-I final: "; save().printStats(); std::cout << std::endl;
262  save.write("PPPdiff.xmp");
263  std::cout << fnImgOut << " rewritten\n";
264  std::cout << "Press any key" << std::endl;
265  char c; std::cin >> c;
266 #endif
267 }
268 #undef DEBUG
Rotation angle of an image (double,degrees)
double getDoubleParam(const char *param, int arg=0)
double transformImageGrayCostBA(double *x, void *_prm)
doublereal * c
Definition: mask.h:360
Tilting angle of an image (double,degrees)
void processImage(const FileName &fnImg, const FileName &fnImgOut, const MDRow &rowIn, MDRow &rowOut)
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 readParams()
Read argument from command line.
Special label to be used when gathering MDs in MpiMetadataPrograms.
void powellOptimizer(Matrix1D< double > &p, int i0, int n, double(*f)(double *x, void *), void *prm, double ftol, double &fret, int &iter, const Matrix1D< double > &steps, bool show)
glob_prnt iter
doublereal * x
Is this image enabled? (int [-1 or 1])
doublereal * b
T & getValue(MDLabel label)
const char * getParam(const char *param, int arg=0)
double transformImageGrayCost(double a, double b, ProgTransformImageGreyLevels *prm)
a value of continuous assignment
double R1
Definition: mask.h:413
#define XSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
int type
Definition: mask.h:402
#define DIRECT_MULTIDIM_ELEM(v, n)
void projectVolume(FourierProjector &projector, Projection &P, int Ydim, int Xdim, double rot, double tilt, double psi, const MultidimArray< double > *ctf)
int verbose
Verbosity level.
double steps
void setValue(MDLabel label, const T &d, bool addLabel=true)
void show() const override
void generate_mask(bool apply_geo=false)
Definition: mask.cpp:1577
b value of continuous assignment
virtual bool containsLabel(MDLabel label) const =0
#define BINARY_CIRCULAR_MASK
Definition: mask.h:365
double psi(const double x)
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
ProgClassifyCL2D * prm
bool each_image_produces_an_output
Indicate that an output is produced for each image in the input.
void addUsageLine(const char *line, bool verbatim=false)
double transformImageGrayCostAB(double *x, void *_prm)
const MultidimArray< int > & get_binary_mask() const
Definition: mask.h:707
int getIntParam(const char *param, int arg=0)
int * n
Name of an image (std::string)
bool produces_a_metadata
Indicate that the unique final output file is a Metadata.
doublereal * a
double sum() const
#define LOWPASS
void addParamsLine(const String &line)
int mode
Definition: mask.h:407
void applyMaskSpace(MultidimArray< double > &v)
std::map< String, CommentList > defaultComments
Definition: xmipp_program.h:83
constexpr int INNER_MASK
Definition: mask.h:47