Xmipp  v3.23.11-Nereus
transform_window.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar S. 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/unitCell.h"
28 
30 public:
31  typedef enum {
33  } WindowMode;
34 
36  int sizeX, sizeY, sizeZ;
37  int cropX, cropY, cropZ;
38  int x0, y0, z0;
39  int xF, yF, zF;
41  //unit cell option parameters
43  double padValue;
45  WindowMode windowMode;
48 
49  void defineParams() {
51  allow_apply_geo = true;
53  addUsageLine("This program takes a region from the input images");
54  addUsageLine(" ");
56  "But... what is windowing? Let's suppose we have an image 32x32,");
58  "and we window it to 16x16, then the central part which contains");
60  "this 16x16 square is returned, but if we window to 64x64 then the");
62  "image is kept in the center of the final image and it is padded");
64  "with 0's until the new size is reached (the padding value may be");
66  "modified using --pad_value, --corner_pad_value or --average_pad_value).");
67  addUsageLine(" ");
69  "With this idea in mind of padding or cutting, if you define two");
71  "logical corners in the input image (the most negative -the top");
73  "left in an image- and the most positive -bottom right in an image-)");
75  "you can store the new image or volume generated by windowing with");
76  addUsageLine("a square box.");
78  " --corners <...> : Windows corners (by default indexes are logical)");
80  " : 2D: <x0> <y0> <xF> <yF>");
82  " : 3D: <x0> <y0> <z0> <xF> <yF> <zF>");
84  " or --size <sizeX> <sizeY=0> <sizeZ=0> : Output dimension. The volume is windowed");
86  " : (expanded or cutted) in all directions such");
88  " : that the origin of the volume remains the");
90  " : same. If the Y and Z dimensions are not");
92  " : specified they are assumed to be the same as");
94  " : the X dimension.");
96  " or --crop <sizeX> <sizeY=0> <sizeZ=0> : Crop this amount of pixels in each direction.");
98  " : Half of the pixels will be cropped from the left");
100  " : and the other half from the right");
102  " : if only one is given, the other two");
104  " : are supposed to be the same");
106  " or --unitcell <sym> <rmin=0> <rmax=0> <expandFactor=0> <offset=0> <sampling=1.> <x_origin=-1.> <y_origin=-1.> <z_origin=-1.> : Extract a unit cell from volume");
108  " : sym = particle symmetry");
110  " : expandFactor = expand unitcell by this factor");
112  " : rmax, rmin = cut a shell with these radii (pixels)");
114  " : offset= for CN symmetry rotate unit cell by this angle");
116  " : sampling=if the output is a mrc file it will use this value to fill the header");
118  " : x_origin = origin x coordinate introduced by the user with the input volume (in pixels)");
120  " : y_origin = origin y coordinate introduced by the user with the input volume (in pixels)");
122  " : z_origin = origin z coordinate introduced by the user with the input volume (in pixels)");
124  " [--physical] : use physical instead of logical coordinates");
125  addParamsLine(" requires --corners;");
127  " [--pad <padtype=value>] : value used for padding");
128  addParamsLine(" where <padtype>");
130  " value <v=0> : use this value for padding");
132  " corner : use the top-left corner for padding");
134  " avg : use the image average for padding");
136  "Window a single image to 16x16, overwriting input image",
137  false);
138  addExampleLine("xmipp_transform_window -i g0ta0001.xmp --size 16");
139  addExampleLine("Window a single volume to 32x64x64", false);
140  addExampleLine("xmipp_transform_window -i g0ta.vol --size 64 64 32");
141  addExampleLine("The same using logical indexes", false);
143  "xmipp_transform_window -i g0ta.vol --corners -32 -32 -16 31 31 15");
145  "Note that r0 and rF are not symmetric because the volume is of an",
146  false);
148  "even size, if we wanted to get a 33x65x65 volume, the right indexes",
149  false);
150  addExampleLine("would be", false);
152  "xmipp_transform_window -i g0ta.vol --corners -32 -32 -16 32 32 16");
153  addExampleLine("Reduce the volume by 10 pixels on each direction",
154  false);
155  addExampleLine("xmipp_transform_window -i g0ta.vol --crop 10");
157  "Enlarge the volume by 10 pixels on each direction (negative crop)",
158  false);
159  addExampleLine("xmipp_transform_window -i g0ta.vol --crop -10");
160  addExampleLine("scipion xmipp_transform_window -i postprocess.mrc:mrc -o postprocess_win.mrc --unitcell i2 0 300 20 0 0.34");
161  addKeywords("window, crop, resize, corner, padding");
162  }
163 
164  void readParams() {
166  padType = getParam("--pad");
167  if (padType == "value")
168  padValue = getDoubleParam("--pad", "value");
169  if (checkParam("--corners")) {
170  int nparams = getCountParam("--corners");
171  if (nparams == 4 || nparams == 6) {
172  x0 = getIntParam("--corners", 0);
173  y0 = getIntParam("--corners", 1);
174  if (nparams == 4) {
175  xF = getIntParam("--corners", 2);
176  yF = getIntParam("--corners", 3);
177  zF = z0 = 0;
178  } else {
179  z0 = getIntParam("--corners", 2);
180  xF = getIntParam("--corners", 3);
181  yF = getIntParam("--corners", 4);
182  zF = getIntParam("--corners", 5);
183  }
184  } else
186  "Incorrect number of arguments after --corners");
187  physical_coords = checkParam("--physical");
188  windowMode = CORNERMODE;
189  } else if (checkParam("--size")) {
190  sizeX = getIntParam("--size", 0);
191  sizeY = getIntParam("--size", 1);
192  sizeZ = getIntParam("--size", 2);
193  if (sizeY == 0)
194  sizeY = sizeX;
195  if (sizeZ == 0)
196  sizeZ = sizeX;
197  x0 = FIRST_XMIPP_INDEX(sizeX);
198  y0 = FIRST_XMIPP_INDEX(sizeY);
199  z0 = FIRST_XMIPP_INDEX(sizeZ);
200  xF = LAST_XMIPP_INDEX(sizeX);
201  yF = LAST_XMIPP_INDEX(sizeY);
202  zF = LAST_XMIPP_INDEX(sizeZ);
203  windowMode = SIZEMODE;
204  physical_coords = false;
205  }
206  //<sym> <rmin=0> <rmax=0> <expandFactor=0> <offset=0> <x_offset=-1.> <y_offset=-1.> <z_offset=-1.>: Extract a unit cell from volume");
207 
208  else if (checkParam("--crop")) {
209  cropX = getIntParam("--crop", 0);
210  cropY = getIntParam("--crop", 1);
211  cropZ = getIntParam("--crop", 2);
212  if (cropY == 0)
213  cropY = cropX;
214  if (cropZ == 0)
215  cropZ = cropX;
216  windowMode = CROPMODE;
217  physical_coords = false;
218  } else if (checkParam("--unitcell")) {
219  int nparams = getCountParam("--unitcell");
220  if (nparams != 9) REPORT_ERROR(ERR_ARG_INCORRECT, "Incorrect number of arguments after --unitcell");
221  sym = getParam("--unitcell", 0);
222  rmin = getDoubleParam("--unitcell", 1);
223  rmax = getDoubleParam("--unitcell", 2);
224  expand = getDoubleParam("--unitcell", 3);
225  offset = DEG2RAD(getDoubleParam("--unitcell", 4));
226  sampling = getDoubleParam("--unitcell", 5);
227  x_origin = getDoubleParam("--unitcell", 6);
228  y_origin = getDoubleParam("--unitcell", 7);
229  z_origin = getDoubleParam("--unitcell", 8);
230 
231  windowMode = UNITCELLMODE;
232  }
233  }
234 
235  void show() {
236  if (verbose == 0)
237  return;
239  switch (windowMode) {
240  case SIZEMODE:
241  std::cout << "New size: (XxYxZ)=" << sizeX << "x" << sizeY << "x"
242  << sizeZ << std::endl;
243  break;
244  case CROPMODE:
245  std::cout << "Crop: (XxYxZ)=" << cropX << "x" << cropY << "x"
246  << cropZ << std::endl;
247  break;
248  case CORNERMODE:
249  std::cout << "New window: from (z0,y0,x0)=(" << z0 << "," << y0
250  << "," << x0 << ") to (zF,yF,xF)=(" << zF << "," << yF
251  << "," << xF << ")\n" << "Physical: " << physical_coords
252  << std::endl;
253  break;
254  case UNITCELLMODE:
255  std::cout << "Sym: " << sym << ", rmin: " << rmin << ", rmax: " << rmax
256  << ", Expand Factor: " << expand << ", offset: " << offset
257  << ", sampling: " << sampling << "; Origin in Angstroms: "
258  << " x: " << x_origin * sampling << ", y: " << y_origin * sampling << ", z: " << z_origin * sampling
259  << std::endl;
260  break;
261  }
262  }
263 
264  void preProcess() {
265  create_empty_stackfile = false;
266  renameTempFn = false;
267 
268  /* Since dimensions are usually changed in this program, we cannot reuse the same file
269  * but we can create a temporary file */
270  if (input_is_stack && fn_out.empty()) {
271 // tempFn.initUniqueName("temp_XXXXXX");
272  fn_out = fn_in + "xtw_tmpfile" + "." + fn_in.getExtension();
273  renameTempFn = true;
274  }
275  }
276 
277  void unitcell(ImageGeneric &in3Dmap,
278  ImageGeneric & out3DDmap) {
279  //1) init class and compute auxiliary vectors
280  UnitCell UC(sym, rmin, rmax, expand, offset, sampling, x_origin, y_origin, z_origin);
281  //2) mask image
282  UC.maskUnitCell(in3Dmap,out3DDmap);
283  //3) shift them
284  //4) retain only positive cases
285  }
286  void processImage(const FileName &fnImg, const FileName &fnImgOut,
287  const MDRow &rowIn, MDRow &rowOut) {
288  ImageGeneric Iin;
289  bool createTempFile = (fnImg == fnImgOut);
290  if (apply_geo) {
291  Iin.readApplyGeo(fnImg, rowIn);
292  } else {
293  Iin.read(fnImg, DATA, ALL_IMAGES, true);
294  }
295 
296  double init_value(padValue);
297  if (padType == "avg")
298  init_value = Iin().computeAvg();
299  else if (padType == "corner")
300  init_value = Iin()(0, 0, 0, 0);
301 
302  Iin().setXmippOrigin();
303  if (ZSIZE(Iin()()) == 1)
304  zF = z0 = 0;
305 
306  String oext = fnImgOut.getExtension();
307  DataType dataType = Iin.getDatatype();
308  ImageGeneric result(dataType);
309  if (windowMode == UNITCELLMODE) {
311  unitcell(Iin, result);
312  } else if (windowMode == CROPMODE) {
313  int xl = cropX / 2;
314  int xr = cropX - xl;
315  int yl = cropY / 2;
316  int yr = cropY - yl;
317  int zl = cropZ / 2;
318  int zr = cropZ - zl;
319  if (ZSIZE(Iin()()) == 1) {
320  zl = zr = 0;
321  }
322  //call to a generic 4D function;
323  result.mapFile2Write(
324  FINISHINGX(Iin()()) - xr - (STARTINGX(Iin()()) + xl) + 1,
325  FINISHINGY(Iin()()) - yr - (STARTINGY(Iin()()) + yl) + 1,
326  FINISHINGZ(Iin()()) - zr - (STARTINGZ(Iin()()) + zl) + 1, fnImgOut,
327  createTempFile);
328  Iin().window(result(),
329  STARTINGZ(Iin()()) + zl, STARTINGY(Iin()()) + yl,
330  STARTINGX(Iin()()) + xl,
331  FINISHINGZ(Iin()()) - zr, FINISHINGY(Iin()()) - yr,
332  FINISHINGX(Iin()()) - xr);
333  } else if (!physical_coords) {
334  result.mapFile2Write(xF - x0 + 1, yF - y0 + 1, zF - z0 + 1,
335  fnImgOut, createTempFile);
336  Iin().window(result(), z0, y0, x0, zF, yF, xF, init_value);
337  } else {
338  result.mapFile2Write(xF - x0 + 1, yF - y0 + 1, zF - z0 + 1,
339  fnImgOut, createTempFile);
340  Iin().window(result(),
341  STARTINGZ(Iin()()) + z0,
342  STARTINGY(Iin()()) + y0,
343  STARTINGX(Iin()()) + x0,
344  STARTINGZ(Iin()()) + zF,
345  STARTINGY(Iin()()) + yF,
346  STARTINGX(Iin()()) + xF, init_value);
347  }
348  Iin.clear(); // Close the input file
349  result.write(fnImgOut);
350  }
351 
352  void postProcess() {
353  /* Since dimensions are usually changed in this program, we cannot reuse the same file
354  * but we can create a temporary file. Now it must be deleted */
355  if (renameTempFn) {
356  if (std::rename(fn_out.c_str(), fn_in.c_str()) != 0)
358  formatString("Error renaming file '%s' to '%s'.",
359  fn_out.c_str(), fn_in.c_str()));
360  }
361  }
362 };
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)
double getDoubleParam(const char *param, int arg=0)
#define FINISHINGX(v)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
#define DEG2RAD(d)
Definition: xmipp_macros.h:312
doublereal * xl
WindowMode windowMode
Input/Output general error.
Definition: xmipp_error.h:134
#define FINISHINGZ(v)
bool input_is_stack
Input is a stack.
#define STARTINGX(v)
DataType getDatatype() const
#define STARTINGY(v)
void addKeywords(const char *keywords)
String getExtension() const
FileName fn_in
Filenames of input and output Metadata.
const char * getParam(const char *param, int arg=0)
Incorrect argument received.
Definition: xmipp_error.h:113
void mapFile2Write(int Xdim, int Ydim, int Zdim, const FileName &_filename, bool createTempFile=false, size_t select_img=APPEND_IMAGE, bool isStack=false, int mode=WRITE_OVERWRITE, int _swapWrite=0)
#define ZSIZE(v)
void addExampleLine(const char *example, bool verbatim=true)
DataType
int verbose
Verbosity level.
void convert2Datatype(DataType datatype, CastWriteMode castMode=CW_CONVERT)
int getCountParam(const char *param)
#define FINISHINGY(v)
void show() const override
void maskUnitCell(ImageGeneric &in3DDmap, ImageGeneric &out3DDmap)
Definition: unitCell.cpp:568
#define FIRST_XMIPP_INDEX(size)
Definition: xmipp_macros.h:439
int readApplyGeo(const FileName &name, const MDRow &row, const ApplyGeoParams &params=DefaultApplyGeoParams)
std::string String
Definition: xmipp_strings.h:34
#define ALL_IMAGES
String formatString(const char *format,...)
void processImage(const FileName &fnImg, const FileName &fnImgOut, const MDRow &rowIn, MDRow &rowOut)
bool checkParam(const char *param)
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)
#define LAST_XMIPP_INDEX(size)
Definition: xmipp_macros.h:448
int getIntParam(const char *param, int arg=0)
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false)
#define STARTINGZ(v)
void addParamsLine(const String &line)
void unitcell(ImageGeneric &in3Dmap, ImageGeneric &out3DDmap)
FileName oext
Output extension and root.