Xmipp  v3.23.11-Nereus
xmippmodule.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: J.M. De la Rosa Trevin (jmdelarosa@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 #include "xmippmodule.h"
26 #include "core/geometry.h"
27 #include "core/matrix2d.h"
28 #include "core/metadata_db.h"
30 #include "core/metadata_sql.h"
31 #include "core/transformations.h"
34 #include "core/xmipp_color.h"
35 #include "data/fourier_filter.h"
37 #include "data/projection.h"
39 #include "python_filename.h"
40 #include "python_image.h"
41 #include "python_program.h"
42 #include "python_metadata.h"
43 #include "python_symmetry.h"
45 #include "numpy/arrayobject.h"
46 
47 PyObject * PyXmippError;
48 
49 /***************************************************************/
50 /* Global methods */
51 /***************************************************************/
52 PyObject *
53 xmipp_str2Label(PyObject *obj, PyObject *args)
54 {
55  char * str;
56  if (PyArg_ParseTuple(args, "s", &str))
57  return Py_BuildValue("i", (int) MDL::str2Label(str));
58  return nullptr;
59 }
60 
61 PyObject *
62 xmipp_label2Str(PyObject *obj, PyObject *args)
63 {
64  int label;
65  if (PyArg_ParseTuple(args, "i", &label))
66  {
67  String labelStr = MDL::label2Str((MDLabel) label);
68  return PyUnicode_FromString(labelStr.c_str());
69  }
70  return nullptr;
71 }
72 
73 PyObject *
74 xmipp_colorStr(PyObject *obj, PyObject *args)
75 {
76  char *str;
77  int color;
78  int attrib = BRIGHT;
79  if (PyArg_ParseTuple(args, "is|i", &color, &str, &attrib))
80  {
81  String labelStr = colorString(str, color, attrib);
82  return PyUnicode_FromString(labelStr.c_str());
83  }
84  return nullptr;
85 }
86 
87 PyObject *
88 xmipp_labelType(PyObject *obj, PyObject *args)
89 {
90  PyObject * input;
91  PyObject* str_exc_type = nullptr;
92  PyObject* pyStr = nullptr;
93  if (PyArg_ParseTuple(args, "O", &input))
94  {
95  if (PyUnicode_Check(input))
96  return Py_BuildValue("i", (int) MDL::labelType((char*)PyUnicode_AsUTF8(PyObject_Str(input))));
97 
98  else if (PyLong_Check(input))
99  return Py_BuildValue("i", (int) MDL::labelType((MDLabel) PyLong_AsLong(input)));
100 
101  else
102  PyErr_SetString(PyExc_TypeError,
103  "labelType: Only int or string are allowed as input");
104  }
105  return nullptr;
106 }
107 
108 PyObject *
109 xmipp_labelHasTag(PyObject *obj, PyObject *args)
110 {
111  PyObject * input;
112  PyObject* str_exc_type = nullptr;
113  PyObject* pyStr = nullptr;
114  int tag;
115 
116  if (PyArg_ParseTuple(args, "Oi", &input, &tag))
117  {
118  MDLabel label = MDL_UNDEFINED;
119 
120  if (PyUnicode_Check(input))
121  {
122 // str_exc_type = PyObject_Repr(input); //Now a unicode object
123 // pyStr = PyUnicode_AsEncodedString(str_exc_type, "utf-8", "Error ~");
124 // label = MDL::str2Label(PyBytes_AS_STRING(pyStr));
125  label = MDL::str2Label((char*)PyUnicode_AsUTF8(input));
126  }
127  else if (PyLong_Check(input))
128  label = (MDLabel) PyLong_AsLong(input);
129 
130  if (label != MDL_UNDEFINED)
131  {
132  if (MDL::hasTag(label, tag))
133  Py_RETURN_TRUE;
134  else
135  Py_RETURN_FALSE;
136  }
137 
138  PyErr_SetString(PyExc_TypeError,
139  "labelHasTag: Input label should be int or string");
140  }
141  return nullptr;
142 }
143 
144 PyObject *
145 xmipp_labelIsImage(PyObject *obj, PyObject *args)
146 {
147  PyObject * input;
148  int tag = TAGLABEL_IMAGE;
149 
150  if (PyArg_ParseTuple(args, "O", &input))
151  {
152  MDLabel label = MDL_UNDEFINED;
153 
154  if (PyUnicode_Check(input))
155  label = MDL::str2Label((char*)PyUnicode_AsUTF8(PyObject_Str(input)));
156 
157  else if (PyLong_Check(input))
158  label = (MDLabel) PyLong_AsLong(input);
159 
160  if (label != MDL_UNDEFINED)
161  {
162  if (MDL::hasTag(label, tag))
163  Py_RETURN_TRUE;
164  else
165  Py_RETURN_FALSE;
166  }
167 
168  PyErr_SetString(PyExc_TypeError,
169  "labelIsImage: Input label should be int or string");
170  }
171  return nullptr;
172 }
173 
174 /* isInStack */
175 PyObject *
176 xmipp_isValidLabel(PyObject *obj, PyObject *args, PyObject *kwargs)
177 {
178  char *str;
179  int label;
180  if (PyArg_ParseTuple(args, "s", &str))
181  label = MDL::str2Label(str);
182  else if (PyArg_ParseTuple(args, "i", &label))
183  ;
184  else
185  return nullptr;
186  if (MDL::isValidLabel((MDLabel) label))
187  Py_RETURN_TRUE;
188  else
189  Py_RETURN_FALSE;
190 }
191 
192 /* createEmptyFile */
193 //ROB: argument of this python function do not much arguments of C funcion Ndim does not exists in C
194 PyObject *
195 xmipp_createEmptyFile(PyObject *obj, PyObject *args, PyObject *kwargs)
196 {
197  int Xdim;
198  int Ydim;
199  int Zdim=1;
200  size_t Ndim=1;
201  DataType dataType = DT_Float;
202 
203  PyObject * input;
204  if (PyArg_ParseTuple(args, "Oii|iii", &input, &Xdim, &Ydim, &Zdim,
205  &Ndim, &dataType))
206  {
207  try
208  {
209 
210  auto inputStr = (std::string)(char*)PyUnicode_AsUTF8(PyObject_Str(input));
211  inputStr += "%";
212  inputStr += datatype2Str(dataType);
213  createEmptyFile(inputStr, Xdim, Ydim, Zdim, Ndim, true, WRITE_REPLACE);
214  Py_RETURN_NONE;
215  }
216  catch (XmippError &xe)
217  {
218  PyErr_SetString(PyXmippError, xe.what());
219  }
220  }
221  return nullptr;
222 }
223 /* getImageSize */
224 PyObject *
225 xmipp_getImageSize(PyObject *obj, PyObject *args, PyObject *kwargs)
226 {
227  PyObject *pyValue;
228 
229  if (PyArg_ParseTuple(args, "O", &pyValue))
230  {
231  try
232  {
233 
234  PyObject * pyStr = PyObject_Str(pyValue);
235  auto *str = (char*)PyUnicode_AsUTF8(pyStr);
236  size_t xdim;
237  size_t ydim;
238  size_t zdim;
239  size_t ndim;
240  getImageSize(str, xdim, ydim, zdim, ndim);
241  Py_DECREF(pyStr);
242  return Py_BuildValue("kkkk", xdim, ydim, zdim, ndim);
243  }
244  catch (XmippError &xe)
245  {
246  PyErr_SetString(PyXmippError, xe.what());
247  }
248  }
249  return nullptr;
250 }
251 
252 PyObject * xmipp_MetaDataInfo(PyObject *obj, PyObject *args, PyObject *kwargs)
253 {
254  PyObject *pyValue; //Only used to skip label and value
255  PyObject *pyStr = nullptr;
256 
257  if (PyArg_ParseTuple(args, "O", &pyValue))
258  {
259  try
260  {
261  MetaData *md = nullptr;
262  size_t size; //number of elements in the metadata
263  bool destroyMd = true;
264 
265  if (PyUnicode_Check(pyValue))
266  {
267  PyObject* repr = PyObject_Str(pyValue);
268  auto * str = (char*)PyUnicode_AsUTF8(pyValue);
269  md = new MetaDataDb();
270  md->setMaxRows(1);
271  md->read(str);
272  size = md->getParsedLines();
273  }
274  else if (FileName_Check(pyValue))
275  {
276  md = new MetaDataDb();
277  md->setMaxRows(1);
278  md->read(FileName_Value(pyValue));
279  size = md->getParsedLines();
280  }
281  else if (MetaData_Check(pyValue))
282  {
283  md = ((MetaDataObject*)pyValue)->metadata.get();
284  destroyMd = false;
285  size = md->size();
286  }
287  else
288  {
289  PyErr_SetString(PyXmippError, "Invalid argument: expected String, FileName or MetaData");
290  return nullptr;
291  }
292  size_t xdim;
293  size_t ydim;
294  size_t zdim;
295  size_t ndim;
296  getImageSize(*md, xdim, ydim, zdim, ndim);
297 
298  if (destroyMd)
299  delete md;
300  return Py_BuildValue("iiikk", xdim, ydim, zdim, ndim, size);
301  }
302  catch (XmippError &xe)
303  {
304  PyErr_SetString(PyXmippError, xe.what());
305  }
306  }
307  return nullptr;
308 }/* Metadata info (from metadata filename)*/
309 /* check if block exists in file*/
310 
311 PyObject *
312 xmipp_existsBlockInMetaDataFile(PyObject *obj, PyObject *args, PyObject *kwargs)
313 {
314 
315  PyObject *input = nullptr;
316  PyObject *pyStr = nullptr;
317  char *str = nullptr;
318  if (PyArg_ParseTuple(args, "O", &input))
319  {
320  try
321  {
322  if ((pyStr = PyObject_Str(input)) != nullptr )
323  {
324  str = (char*)PyUnicode_AsUTF8(pyStr);
325  if (existsBlockInMetaDataFile( (std::string) str))
326  Py_RETURN_TRUE;
327  else
328  Py_RETURN_FALSE;
329  }
330  else
331  return nullptr;
332  }
333  catch (XmippError &xe)
334  {
335  PyErr_SetString(PyXmippError, xe.what());
336  return nullptr;
337  }
338  }
339 
340  return nullptr;
341 }
342 
343 PyObject *
344 xmipp_CheckImageFileSize(PyObject *obj, PyObject *args, PyObject *kwargs)
345 {
346  PyObject *filename;
347 
348  if (PyArg_ParseTuple(args, "O", &filename))
349  {
350  try
351  {
352  PyObject * pyStr = PyObject_Str(filename);
353  auto *str = (char*)PyUnicode_AsUTF8(pyStr);
354  bool result = checkImageFileSize(str);
355  Py_DECREF(pyStr);
356  if (result)
357  Py_RETURN_TRUE;
358  else
359  Py_RETURN_FALSE;
360  }
361  catch (XmippError &xe)
362  {
363  PyErr_SetString(PyXmippError, xe.what());
364  }
365  }
366  return nullptr;
367 }
368 
369 PyObject *
370 xmipp_CheckImageCorners(PyObject *obj, PyObject *args, PyObject *kwargs)
371 {
372  PyObject *filename;
373 
374  if (PyArg_ParseTuple(args, "O", &filename))
375  {
376  try
377  {
378  PyObject * pyStr = PyObject_Str(filename);
379  auto * str = (char*)PyUnicode_AsUTF8(pyStr);
380  bool result = checkImageCorners(str);
381  Py_DECREF(pyStr);
382  if (result)
383  Py_RETURN_TRUE;
384  else
385  Py_RETURN_FALSE;
386  }
387  catch (XmippError &xe)
388  {
389  PyErr_SetString(PyXmippError, xe.what());
390  }
391  }
392  return nullptr;
393 }
394 
395 PyObject *
396 xmipp_ImgCompare(PyObject *obj, PyObject *args, PyObject *kwargs)
397 {
398  PyObject *filename1;
399  PyObject *filename2;
400 
401  if (PyArg_ParseTuple(args, "OO", &filename1, &filename2))
402  {
403  try
404  {
405  PyObject * pyStr1 = PyObject_Str(filename1);
406  PyObject * pyStr2 = PyObject_Str(filename2);
407 
408  auto * str1 = (char*)PyUnicode_AsUTF8(pyStr1);
409  auto * str2 = (char*)PyUnicode_AsUTF8(pyStr2);
410  bool result = compareImage(str1, str2);
411  Py_DECREF(pyStr1);
412  Py_DECREF(pyStr2);
413  if (result)
414  Py_RETURN_TRUE;
415  else
416  Py_RETURN_FALSE;
417  }
418  catch (XmippError &xe)
419  {
420  PyErr_SetString(PyXmippError, xe.what());
421  }
422  }
423  return nullptr;
424 }
425 
426 PyObject *
427 xmipp_compareTwoFiles(PyObject *obj, PyObject *args, PyObject *kwargs)
428 {
429  PyObject *filename1;
430  PyObject *filename2;
431  size_t offset=0;
432  if (PyArg_ParseTuple(args, "OO|i", &filename1, &filename2, &offset))
433  {
434  try
435  {
436  PyObject * pyStr1 = PyObject_Str(filename1);
437  PyObject * pyStr2 = PyObject_Str(filename2);
438 
439  auto * str1 = (char*)PyUnicode_AsUTF8(pyStr1);
440  auto * str2 = (char*)PyUnicode_AsUTF8(pyStr2);
441  bool result = compareTwoFiles(str1, str2, offset);
442  Py_DECREF(pyStr1);
443  Py_DECREF(pyStr2);
444  if (result)
445  Py_RETURN_TRUE;
446  else
447  Py_RETURN_FALSE;
448  }
449  catch (XmippError &xe)
450  {
451  PyErr_SetString(PyXmippError, xe.what());
452  }
453  }
454  return nullptr;
455 }
456 
457 
458 PyObject *
459 xmipp_bsoftRemoveLoopBlock(PyObject *obj, PyObject *args, PyObject *kwargs)
460 {
461  PyObject *filename1;
462  PyObject *filename2;
463  if (PyArg_ParseTuple(args, "OO", &filename1, &filename2))
464  {
465  try
466  {
467  PyObject * pyStr1 = PyObject_Str(filename1);
468  PyObject * pyStr2 = PyObject_Str(filename2);
469 
470  auto * str1 = (char*)PyUnicode_AsUTF8(pyStr1);
471  auto * str2 = (char*)PyUnicode_AsUTF8(pyStr2);
472  bsoftRemoveLoopBlock(str1, str2);
473  Py_DECREF(pyStr1);
474  Py_DECREF(pyStr2);
475  Py_RETURN_TRUE;
476  }
477  catch (XmippError &xe)
478  {
479  PyErr_SetString(PyXmippError, xe.what());
480  }
481  }
482  return nullptr;
483 }
484 
485 
486 PyObject *
487 xmipp_bsoftRestoreLoopBlock(PyObject *obj, PyObject *args, PyObject *kwargs)
488 {
489  PyObject *filename1;
490  PyObject *filename2;
491  if (PyArg_ParseTuple(args, "OO", &filename1, &filename2))
492  {
493  try
494  {
495  PyObject * pyStr1 = PyObject_Str(filename1);
496  PyObject * pyStr2 = PyObject_Str(filename2);
497 
498  auto * str1 = (char*)PyUnicode_AsUTF8(pyStr1);
499  auto * str2 = (char*)PyUnicode_AsUTF8(pyStr2);
500  bsoftRestoreLoopBlock(str1, str2);
501  Py_DECREF(pyStr1);
502  Py_DECREF(pyStr2);
503  Py_RETURN_TRUE;
504  }
505  catch (XmippError &xe)
506  {
507  PyErr_SetString(PyXmippError, xe.what());
508  }
509  }
510  return nullptr;
511 }
512 
513 PyObject *
514 xmipp_compareTwoImageTolerance(PyObject *obj, PyObject *args, PyObject *kwargs)
515 {
516  PyObject *input1;
517  PyObject *input2;
518  double tolerance=0.;
519 
520  if (PyArg_ParseTuple(args, "OO|d", &input1, &input2, &tolerance))
521 
522  {
523  try
524  {
525  size_t index1 = 0;
526  size_t index2 = 0;
527  char * fn1;
528  char * fn2;
529 
530  // If the inputs objects are tuples, consider it (index, filename)
531  if (PyTuple_Check(input1))
532  {
533  // Get the index and filename from the Python tuple object
534  index1 = PyLong_AsSsize_t(PyTuple_GetItem(input1, 0));
535  fn1 = (char*)PyUnicode_AsUTF8(PyObject_Str(PyTuple_GetItem(input1, 1)));
536  }
537  else
538  fn1 = (char*)PyUnicode_AsUTF8(PyObject_Str(input1));
539 
540  if (PyTuple_Check(input2))
541  {
542  // Get the index and filename from the Python tuple object
543  index2 = PyLong_AsSsize_t(PyTuple_GetItem(input2, 0));
544  fn2 = (char*)PyUnicode_AsUTF8(PyObject_Str(PyTuple_GetItem(input2, 1)));
545  }
546  else
547  fn2 = (char*)PyUnicode_AsUTF8(PyObject_Str(input2));
548 
549  bool result = compareTwoImageTolerance(fn1, fn2, tolerance, index1, index2);
550 
551  if (result)
552  Py_RETURN_TRUE;
553  else
554  Py_RETURN_FALSE;
555  }
556  catch (XmippError &xe)
557  {
558  PyErr_SetString(PyXmippError, xe.what());
559  }
560  }
561  return nullptr;
562 }
563 
564 /***************************************************************/
565 /* Some specific utility functions */
566 /***************************************************************/
567 /* readMetaDataWithTwoPossibleImages */
568 PyObject *
570  PyObject *kwargs)
571 {
572  PyObject *pyStr;
573  PyObject *pyMd; //Only used to skip label and value
574 
575  if (PyArg_ParseTuple(args, "OO", &pyStr, &pyMd))
576  {
577  try
578  {
579  if (!MetaData_Check(pyMd))
580  PyErr_SetString(PyExc_TypeError,
581  "Expected MetaData as second argument");
582  else
583  {
584  if (PyUnicode_Check(pyStr))
585  {
586  readMetaDataWithTwoPossibleImages((char*)PyUnicode_AsUTF8(pyStr),
587  MetaData_Value(pyMd));
588  }
589  else if (FileName_Check(pyStr))
591  MetaData_Value(pyMd));
592  else
593  PyErr_SetString(PyExc_TypeError,
594  "Expected string or FileName as first argument");
595  Py_RETURN_NONE;
596  }
597  }
598  catch (XmippError &xe)
599  {
600  PyErr_SetString(PyXmippError, xe.what());
601  }
602  }
603  return nullptr;
604 }
605 
606 /* substituteOriginalImages */
607 PyObject *
608 xmipp_substituteOriginalImages(PyObject *obj, PyObject *args, PyObject *kwargs)
609 {
610  PyObject *pyStrFn;
611  PyObject *pyStrFnOrig;
612  PyObject *pyStrFnOut;
613  int label;
614  int skipFirstBlock;
615 
616  if (PyArg_ParseTuple(args, "OOOii", &pyStrFn, &pyStrFnOrig, &pyStrFnOut,
617  &label, &skipFirstBlock))
618  {
619  try
620  {
621  FileName fn;
622  FileName fnOrig;
623  FileName fnOut;
624  if (PyUnicode_Check(pyStrFn))
625  fn = (char*)PyUnicode_AsUTF8(pyStrFn);
626 
627  else if (FileName_Check(pyStrFn))
628  fn = FileName_Value(pyStrFn);
629  else
630  PyErr_SetString(PyExc_TypeError,
631  "Expected string or FileName as first argument");
632 
633  if (PyUnicode_Check(pyStrFnOrig))
634  fnOrig = (char*)PyUnicode_AsUTF8(pyStrFnOrig);
635 
636  else if (FileName_Check(pyStrFnOrig))
637  fnOrig = FileName_Value(pyStrFnOrig);
638  else
639  PyErr_SetString(PyExc_TypeError,
640  "Expected string or FileName as second argument");
641 
642  if (PyUnicode_Check(pyStrFnOut))
643  fnOut = (char*)PyUnicode_AsUTF8(pyStrFnOut);
644 
645  else if (FileName_Check(pyStrFnOut))
646  fnOut = FileName_Value(pyStrFnOut);
647  else
648  PyErr_SetString(PyExc_TypeError,
649  "Expected string or FileName as third argument");
650 
651  substituteOriginalImages(fn, fnOrig, fnOut, (MDLabel) label,
652  (bool) skipFirstBlock);
653  Py_RETURN_NONE;
654  }
655  catch (XmippError &xe)
656  {
657  PyErr_SetString(PyXmippError, xe.what());
658  }
659  }
660  return nullptr;
661 }
662 
663 bool validateInputImageString(PyObject * pyImage, PyObject *pyStrFn, FileName &fn)
664 {
665  if (!Image_Check(pyImage))
666  {
667  PyErr_SetString(PyExc_TypeError,
668  "bad argument: Expected Image as first argument");
669  return false;
670  }
671  if (PyUnicode_Check(pyStrFn))
672  fn = (char*)PyUnicode_AsUTF8(pyStrFn);
673 
674  else if (FileName_Check(pyStrFn))
675  fn = FileName_Value(pyStrFn);
676  else
677  {
678  PyErr_SetString(PyExc_TypeError,
679  "bad argument:Expected string or FileName as second argument");
680  return false;
681  }
682  return true;
683 }
684 
685 PyObject *
686 xmipp_compareTwoMetadataFiles(PyObject *obj, PyObject *args, PyObject *kwargs)
687 {
688  PyObject *pyStrFn1;
689  PyObject *pyStrFn2;
690  PyObject *pyStrAux;
691 
692  if (PyArg_ParseTuple(args, "OO", &pyStrFn1, &pyStrFn2))
693  {
694  try
695  {
696  FileName fn1;
697  FileName fn2;
698 
699  pyStrAux = PyObject_Str(pyStrFn1);
700 
701  if (pyStrAux != nullptr)
702  fn1 = (char*)PyUnicode_AsUTF8(pyStrAux);
703  else
704  PyErr_SetString(PyExc_TypeError, "Expected string or FileName as first argument");
705 
706  pyStrAux = PyObject_Str(pyStrFn2);
707  if (pyStrAux != nullptr)
708  fn2 = (char*)PyUnicode_AsUTF8(pyStrAux);
709 
710  else
711  PyErr_SetString(PyExc_TypeError,
712  "Expected string or FileName as first argument");
713 
714  if (compareTwoMetadataFiles(fn1, fn2))
715  Py_RETURN_TRUE;
716  else
717  Py_RETURN_FALSE;
718  }
719  catch (XmippError &xe)
720  {
721  PyErr_SetString(PyXmippError, xe.what());
722  }
723  }
724  return nullptr;
725 }
726 
728 #define FILTER_TRY()\
729 try {\
730 if (validateInputImageString(pyImage, pyStrFn, fn)) {\
731 Image<double> img;\
732 img.read(fn);\
733 MultidimArray<double> &data = MULTIDIM_ARRAY(img);\
734 ArrayDim idim;\
735 data.getDimensions(idim);
736 
737 #define FILTER_CATCH()\
738 size_t w = dim, h = dim, &x = idim.xdim, &y = idim.ydim;\
739 if (x > y) h = y * (dim/x);\
740 else if (y > x)\
741  w = x * (dim/y);\
742 selfScaleToSize(LINEAR, data, w, h);\
743 Image_Value(pyImage).setDatatype(DT_Double);\
744 data.resetOrigin();\
745 MULTIDIM_ARRAY_GENERIC(Image_Value(pyImage)).setImage(data);\
746 Py_RETURN_NONE;\
747 }} catch (XmippError &xe)\
748 { PyErr_SetString(PyXmippError, xe.what());}\
749 
750 
751 /* dump metadatas to database*/
752 PyObject *
753 xmipp_dumpToFile(PyObject *obj, PyObject *args, PyObject *kwargs)
754 {
755  PyObject *pyStrFn;
756  PyObject *pyStrAux;
757  FileName fn;
758 
759  if (PyArg_ParseTuple(args, "O", &pyStrFn))
760  {
761  pyStrAux = PyObject_Str(pyStrFn);
762  if (pyStrAux != nullptr)
763  {
764  fn = (char*)PyUnicode_AsUTF8(pyStrAux);
765  MDSql::dumpToFile(fn);
766  Py_RETURN_NONE;
767  }
768  }
769  return nullptr;
770 }
771 
772 PyObject *
773 xmipp_Euler_angles2matrix(PyObject *obj, PyObject *args, PyObject *kwargs)
774 {
775  import_array();
776  double rot;
777  double tilt;
778  double psi;
779  if (PyArg_ParseTuple(args, "ddd", &rot,&tilt,&psi))
780  {
781  npy_intp dims[2];
782  dims[0] = 3;
783  dims[1] = 3;
784  auto * arr = (PyArrayObject*) PyArray_SimpleNew(2, dims, NPY_DOUBLE);
785  void * data = PyArray_DATA(arr);
786  Matrix2D<double> euler(3,3);
787  Euler_angles2matrix(rot, tilt, psi,euler,false);
788  memcpy(data, (euler.mdata), 9 * sizeof(double));
789  return (PyObject*)arr;
790  }
791  return nullptr;
792 }
793 
794 PyObject *
795 xmipp_Euler_matrix2angles(PyObject *obj, PyObject *args, PyObject *kwargs)
796 {
797  import_array()
798  PyObject *input;
799  if (PyArg_ParseTuple(args, "O", &input))
800  {
801  // parse python object into numpy array (Numpy/C API)
802  auto dType = PyArray_ObjectType(input, NPY_FLOAT);
803  auto *arr = reinterpret_cast<PyArrayObject*>(PyArray_FROM_OTF(input, dType, NPY_ARRAY_IN_ARRAY));
804  if (nullptr == arr) {
805  return nullptr;
806  }
807  if (const auto *dims = PyArray_DIMS(arr); 2 != PyArray_NDIM(arr) || (3 != dims[0]) || (3 != dims[1])) {
808  PyErr_SetString(PyExc_IndexError, "2D array of size <3,3> expected");
809  return nullptr;
810  }
811  Matrix2D<double> euler(3,3);
812  // let's assume that the stride == 1
813  if (PyTypeNum_ISFLOAT(dType)) {
814  memcpy(euler.mdata, PyArray_DATA(arr), 9 * sizeof(double));
815  } else if (PyTypeNum_ISINTEGER(dType)) {
816  for (auto i = 0; i < 9; ++i) {
817  euler.mdata[i] = static_cast<double>(*reinterpret_cast<int*>(PyArray_GETPTR1(arr, i)));
818  }
819  } else {
820  PyErr_SetString(PyExc_TypeError, "Array of type 'double' or 'int' expected");
821  return nullptr;
822  }
823  double rot;
824  double tilt;
825  double psi;
826  Euler_matrix2angles(euler,rot, tilt, psi);
827  return Py_BuildValue("fff", rot, tilt, psi);//fff three real
828  }
829  return nullptr;
830 }
831 
832 
833 PyObject *
834 xmipp_Euler_direction(PyObject *obj, PyObject *args, PyObject *kwargs)
835 {
836  double rot;
837  double tilt;
838  double psi;
839  if (PyArg_ParseTuple(args, "ddd", &rot,&tilt,&psi))
840  {
842  Euler_direction(rot, tilt, psi, direction);
843  return Py_BuildValue("fff", VEC_ELEM(direction, 0), VEC_ELEM(direction, 1), VEC_ELEM(direction, 2));//fff three real
844  }
845  return nullptr;
846 }
847 
848 PyObject *
849 xmipp_alignWithZ(PyObject *obj, PyObject *args, PyObject *kwargs)
850 {
851  import_array();
852  double x;
853  double y;
854  double z;
855  bool homogeneous;
856  auto *pyHomogeneous = Py_False;
857  if (PyArg_ParseTuple(args, "ddd|O", &x,&y,&z,&pyHomogeneous))
858  {
859  if(PyBool_Check(pyHomogeneous))
860  homogeneous = pyHomogeneous == Py_True;
861 
862  npy_intp dims[2];
863  if (!homogeneous)
864  {
865  dims[0] = 3;
866  dims[1] = 3;
867  }
868  else
869  {
870  dims[0] = 4;
871  dims[1] = 4;
872  }
873  auto * arr = (PyArrayObject*) PyArray_SimpleNew(2, dims, NPY_DOUBLE);
874  void * data = PyArray_DATA(arr);
875  Matrix1D<double> u(3);
877  VECTOR_R3(u,x,y,z);
878  alignWithZ(u, R, homogeneous);
879  memcpy(data, (R.mdata), dims[0] * dims[1] * sizeof(double));
880  return (PyObject*)arr;
881  }
882  return nullptr;
883 }
884 
885 /* activateMathExtensions */
886 PyObject *
887 xmipp_activateMathExtensions(PyObject *obj, PyObject *args, PyObject *kwargs)
888 {
889  try
890  {
892  Py_RETURN_TRUE;
893  else
894  Py_RETURN_FALSE;
895  }
896  catch (XmippError &xe)
897  {
898  PyErr_SetString(PyXmippError, xe.what());
899  }
900  return nullptr;
901 }
902 
903 /* activateRegExtensions */
904 PyObject *
905 xmipp_activateRegExtensions(PyObject *obj, PyObject *args, PyObject *kwargs)
906 {
907  try
908  {
910  Py_RETURN_TRUE;
911  else
912  Py_RETURN_FALSE;
913  }
914  catch (XmippError &xe)
915  {
916  PyErr_SetString(PyXmippError, xe.what());
917  }
918  return nullptr;
919 }
920 
921 /* calculate enhanced psd and return preview*/
922 PyObject *
923 xmipp_fastEstimateEnhancedPSD(PyObject *obj, PyObject *args, PyObject *kwargs)
924 {
925  PyObject *pyStrFn;
926  PyObject *pyImage;
927  //ImageObject *pyImage;
928  double downsampling;
929  int dim;
930  int Nthreads;
931  FileName fn;
932 
933  if (PyArg_ParseTuple(args, "OOdii", &pyImage, &pyStrFn, &downsampling, &dim, &Nthreads))
934  {
935  try
936  {
937  if (validateInputImageString(pyImage, pyStrFn, fn))
938  {
940  fastEstimateEnhancedPSD(fn, downsampling, data, Nthreads);
942  Image_Value(pyImage).setDatatype(DT_Double);
943  Image_Value(pyImage).data->setImage(data);
944  Py_RETURN_NONE;
945  }
946  }
947  catch (XmippError &xe)
948  {
949  PyErr_SetString(PyXmippError, xe.what());
950  }
951  }
952  return nullptr;
953 }
954 
956 #define FILTER_TRY()\
957 try {\
958 if (validateInputImageString(pyImage, pyStrFn, fn)) {\
959 Image<double> img;\
960 img.read(fn);\
961 MultidimArray<double> &data = MULTIDIM_ARRAY(img);\
962 ArrayDim idim;\
963 data.getDimensions(idim);
964 
965 #undef FILTER_CATCH
966 #define FILTER_CATCH()\
967 size_t w = dim, h = dim, &x = idim.xdim, &y = idim.ydim;\
968 if (x > y) h = y * (dim/x);\
969 else if (y > x)\
970  w = x * (dim/y);\
971 selfScaleToSize(xmipp_transformation::LINEAR, data, w, h);\
972 Image_Value(pyImage).setDatatype(DT_Double);\
973 data.resetOrigin();\
974 MULTIDIM_ARRAY_GENERIC(Image_Value(pyImage)).setImage(data);\
975 Py_RETURN_NONE;\
976 }} catch (XmippError &xe)\
977 { PyErr_SetString(PyXmippError, xe.what());}\
978 
979 
980 /* calculate enhanced psd and return preview
981 * used for protocol preprocess_particles*/
982 PyObject *
983 xmipp_bandPassFilter(PyObject *obj, PyObject *args, PyObject *kwargs)
984 {
985  PyObject *pyStrFn;
986  PyObject *pyImage;
987  double w1;
988  double w2;
989  double raised_w;
990  int dim;
991  FileName fn;
992 
993  if (PyArg_ParseTuple(args, "OOdddi", &pyImage, &pyStrFn, &w1, &w2, &raised_w, &dim))
994  {
995  FILTER_TRY()
996  bandpassFilter(data, w1, w2, raised_w);
997  FILTER_CATCH()
998  }
999  return nullptr;
1000 }
1001 
1002 /* calculate enhanced psd and return preview
1003  * used for protocol preprocess_particles*/
1004 PyObject *
1005 xmipp_gaussianFilter(PyObject *obj, PyObject *args, PyObject *kwargs)
1006 {
1007  PyObject *pyStrFn;
1008  PyObject *pyImage;
1009  double freqSigma;
1010  int dim;
1011  FileName fn;
1012 
1013  if (PyArg_ParseTuple(args, "OOdi", &pyImage, &pyStrFn, &freqSigma, &dim))
1014  {
1015  FILTER_TRY()
1016  gaussianFilter(data, freqSigma);
1017  FILTER_CATCH()
1018  }
1019  return nullptr;
1020 }
1021 
1022 /* calculate enhanced psd and return preview
1023  * used for protocol preprocess_particles*/
1024 PyObject *
1025 xmipp_realGaussianFilter(PyObject *obj, PyObject *args, PyObject *kwargs)
1026 {
1027  PyObject *pyStrFn;
1028  PyObject *pyImage;
1029  double realSigma;
1030  int dim;
1031  FileName fn;
1032 
1033  if (PyArg_ParseTuple(args, "OOdi", &pyImage, &pyStrFn, &realSigma, &dim))
1034  {
1035  FILTER_TRY()
1036  realGaussianFilter(data, realSigma);
1037  FILTER_CATCH()
1038  }
1039  return nullptr;
1040 }
1041 
1042 /* calculate enhanced psd and return preview
1043  * used for protocol preprocess_particles*/
1044 PyObject *
1045 xmipp_badPixelFilter(PyObject *obj, PyObject *args, PyObject *kwargs)
1046 {
1047  PyObject *pyStrFn;
1048  PyObject *pyImage;
1049  double factor;
1050  int dim;
1051  FileName fn;
1052 
1053  if (PyArg_ParseTuple(args, "OOdi", &pyImage, &pyStrFn, &factor, &dim))
1054  {
1055  FILTER_TRY()
1056  BadPixelFilter filter;
1057  filter.type = BadPixelFilter::OUTLIER;
1058  filter.factor = factor;
1059  filter.apply(data);
1060  FILTER_CATCH()
1061  }
1062  return nullptr;
1063 }
1064 
1065 PyObject *
1066 xmipp_errorBetween2CTFs(PyObject *obj, PyObject *args, PyObject *kwargs)
1067 {
1068  PyObject *pyMd1;
1069  PyObject *pyMd2;
1070  double minFreq=0.05;
1071  double maxFreq=0.25;
1072  size_t dim=256;
1073 
1074  if (PyArg_ParseTuple(args, "OO|idd"
1075  ,&pyMd1, &pyMd2
1076  ,&dim,&minFreq,&maxFreq))
1077  {
1078  try
1079  {
1080  if (!MetaData_Check(pyMd1))
1081  PyErr_SetString(PyExc_TypeError,
1082  "Expected MetaData as first argument");
1083  else if (!MetaData_Check(pyMd2))
1084  PyErr_SetString(PyExc_TypeError,
1085  "Expected MetaData as second argument");
1086  else
1087  {
1088  double error = errorBetween2CTFs(MetaData_Value(pyMd1),
1089  MetaData_Value(pyMd2),
1090  dim,
1091  minFreq,maxFreq);
1092  return Py_BuildValue("f", error);
1093  }
1094  }
1095  catch (XmippError &xe)
1096  {
1097  PyErr_SetString(PyXmippError, xe.what());
1098  }
1099  }
1100  return nullptr;
1101 
1102 }
1103 
1104 PyObject *
1105 xmipp_errorMaxFreqCTFs(PyObject *obj, PyObject *args, PyObject *kwargs)
1106 {
1107  PyObject *pyMd1;
1108  double phaseDiffRad;
1109 
1110  if (PyArg_ParseTuple(args, "Od", &pyMd1, &phaseDiffRad))
1111  {
1112  try
1113  {
1114  if (!MetaData_Check(pyMd1))
1115  PyErr_SetString(PyExc_TypeError,
1116  "Expected MetaData as first argument");
1117  else
1118  {
1119  double resolutionA = errorMaxFreqCTFs(MetaData_Value(pyMd1),
1120  phaseDiffRad
1121  );
1122  return Py_BuildValue("f", resolutionA);
1123  }
1124  }
1125  catch (XmippError &xe)
1126  {
1127  PyErr_SetString(PyXmippError, xe.what());
1128  }
1129  }
1130  return nullptr;
1131 
1132 }
1133 
1134 PyObject *
1135 xmipp_errorMaxFreqCTFs2D(PyObject *obj, PyObject *args, PyObject *kwargs)
1136 {
1137  PyObject *pyMd1;
1138  PyObject *pyMd2;
1139 
1140  if (PyArg_ParseTuple(args, "OO", &pyMd1, &pyMd2))
1141  {
1142  try
1143  {
1144  if (!MetaData_Check(pyMd1))
1145  PyErr_SetString(PyExc_TypeError,
1146  "Expected MetaData as first argument");
1147  else if (!MetaData_Check(pyMd2))
1148  PyErr_SetString(PyExc_TypeError,
1149  "Expected MetaData as second argument");
1150  else
1151  {
1152  double resolutionA = errorMaxFreqCTFs2D(MetaData_Value(pyMd1),
1153  MetaData_Value(pyMd2)
1154  );
1155  return Py_BuildValue("f", resolutionA);
1156  }
1157  }
1158  catch (XmippError &xe)
1159  {
1160  PyErr_SetString(PyXmippError, xe.what());
1161  }
1162  }
1163  return nullptr;
1164 
1165 }
1166 
1167 /* convert to psd */
1168 PyObject *
1169 Image_convertPSD(PyObject *obj, PyObject *args, PyObject *kwargs)
1170 {
1171  auto *self = (ImageObject*) obj;
1172 
1173  if (self != nullptr)
1174  {
1175  try
1176  {
1177  auto &image = self->image;
1178  image->convert2Datatype(DT_Double);
1180  MULTIDIM_ARRAY_GENERIC(*image).getMultidimArrayPointer(in);
1181  xmipp2PSD(*in, *in, true);
1182 
1183  Py_RETURN_NONE;
1184  }
1185  catch (XmippError &xe)
1186  {
1187  PyErr_SetString(PyXmippError, xe.what());
1188  }
1189  }
1190  return nullptr;
1191 }//function Image_convertPSD
1192 
1193 /* I2aligned=align(I1,I2) */
1194 PyObject *
1195 Image_align(PyObject *obj, PyObject *args, PyObject *kwargs)
1196 {
1197  PyObject *pimg1 = nullptr;
1198  PyObject *pimg2 = nullptr;
1199  auto * result = (ImageObject*)PyObject_CallFunction((PyObject*)&ImageType, "");
1200  try
1201  {
1202  if (PyArg_ParseTuple(args, "OO", &pimg1, &pimg2))
1203  {
1204  auto *img1=(ImageObject *)pimg1;
1205  auto *img2=(ImageObject *)pimg2;
1206 
1207  result->image = std::make_unique<ImageGeneric>(Image_Value(img2));
1208  *result->image = *img2->image;
1209 
1210  result->image->convert2Datatype(DT_Double);
1211  MultidimArray<double> *mimgResult;
1212  MULTIDIM_ARRAY_GENERIC(*result->image).getMultidimArrayPointer(mimgResult);
1213 
1214  img1->image->convert2Datatype(DT_Double);
1215  MultidimArray<double> *mimg1;
1216  MULTIDIM_ARRAY_GENERIC(*img1->image).getMultidimArrayPointer(mimg1);
1217 
1218  //AJ testing
1219  MULTIDIM_ARRAY_GENERIC(*img1->image).setXmippOrigin();
1220  MULTIDIM_ARRAY_GENERIC(*result->image).setXmippOrigin();
1221  //END AJ
1222 
1223  Matrix2D<double> M;
1224  alignImagesConsideringMirrors(*mimg1, *mimgResult, M, true);
1225  }
1226  }
1227  catch (XmippError &xe)
1228  {
1229  PyErr_SetString(PyXmippError, xe.what());
1230  }
1231  return (PyObject *)result;
1232 }//function Image_align
1233 
1234 /* Apply CTF to this image */
1235 PyObject *
1236 Image_applyCTF(PyObject *obj, PyObject *args, PyObject *kwargs)
1237 {
1238  PyObject *pimg = nullptr;
1239  PyObject *input = nullptr;
1240  double Ts=1.0;
1241  size_t rowId;
1242  auto *pyReplace = Py_False;
1243  bool absPhase = false;
1244 
1245  try
1246  {
1247  PyArg_ParseTuple(args, "OOd|kO", &pimg, &input,&Ts,&rowId,&pyReplace);
1248  if (pimg != nullptr && input != nullptr)
1249  {
1250  if(PyBool_Check(pyReplace))
1251  absPhase = pyReplace == Py_True;
1252 
1253  PyObject *pyStr;
1254  if (PyUnicode_Check(input) || MetaData_Check(input))
1255  {
1256  auto *img = (ImageObject*) pimg;
1257  auto &image = img->image;
1258  image->convert2Datatype(DT_Double);
1259  MultidimArray<double> * mImage=nullptr;
1260  MULTIDIM_ARRAY_GENERIC(*image).getMultidimArrayPointer(mImage);
1261 
1262  // COSS: This is redundant? image->data->getMultidimArrayPointer(mImage);
1263 
1264  CTFDescription ctf;
1265  ctf.enable_CTF=true;
1266  ctf.enable_CTFnoise=false;
1267  if (MetaData_Check(input))
1268  ctf.readFromMetadataRow(MetaData_Value(input), rowId );
1269  else
1270  {
1271  pyStr = PyObject_Str(input);
1272  FileName fnCTF = (char*)PyUnicode_AsUTF8(pyStr);
1273  ctf.read(fnCTF);
1274  }
1275  ctf.produceSideInfo();
1276  ctf.applyCTF(*mImage,Ts,absPhase);
1277  Py_RETURN_NONE;
1278  }
1279  }
1280  }
1281  catch (XmippError &xe)
1282  {
1283  PyErr_SetString(PyXmippError, xe.what());
1284  }
1285  return nullptr;
1286 }
1287 
1288 /* projectVolumeDouble */
1289 PyObject *
1290 Image_projectVolumeDouble(PyObject *obj, PyObject *args, PyObject *kwargs)
1291 {
1292  PyObject *pvol = nullptr;
1293  ImageObject * result = nullptr;
1294  double rot;
1295  double tilt;
1296  double psi;
1297 
1298  if (PyArg_ParseTuple(args, "Oddd", &pvol, &rot,&tilt,&psi))
1299  {
1300  try
1301  {
1302  // We use the following macro to release the Python Interpreter Lock (GIL)
1303  // while running this C extension code and allows threads to run concurrently.
1304  // See: https://docs.python.org/2.7/c-api/init.html for details.
1305  Py_BEGIN_ALLOW_THREADS
1306  Projection P;
1307  auto *vol = (ImageObject*) pvol;
1308  MultidimArray<double> * mVolume;
1309  vol->image->data->getMultidimArrayPointer(mVolume);
1310  ArrayDim aDim;
1311  mVolume->getDimensions(aDim);
1312  mVolume->setXmippOrigin();
1313  projectVolume(*mVolume, P, aDim.xdim, aDim.ydim,rot, tilt, psi);
1314  result = (ImageObject*)PyObject_CallFunction((PyObject*)&ImageType, "");
1315  Image <double> I;
1316  result->image = std::make_unique<ImageGeneric>();
1317  result->image->setDatatype(DT_Double);
1318  result->image->data->setImage(MULTIDIM_ARRAY(P));
1319  Py_END_ALLOW_THREADS
1320  return (PyObject *)result;
1321  }
1322  catch (XmippError &xe)
1323  {
1324  PyErr_SetString(PyXmippError, xe.what());
1325  }
1326  }
1327  return nullptr;
1328 }//function Image_projectVolumeDouble
1329 
1330 
1331 static PyMethodDef
1332 xmipp_methods[] =
1333  {
1334  { "getBlocksInMetaDataFile",
1335  xmipp_getBlocksInMetaDataFile, METH_VARARGS,
1336  "return list with metadata blocks in a file" },
1337  { "label2Str", xmipp_label2Str, METH_VARARGS,
1338  "Convert MDLabel to string" },
1339  { "colorStr", xmipp_colorStr, METH_VARARGS,
1340  "Create a string with color characters sequence for print in console" },
1341  { "labelType", xmipp_labelType, METH_VARARGS,
1342  "Return the type of a label" },
1343  { "labelHasTag", xmipp_labelHasTag, METH_VARARGS,
1344  "Return the if the label has a specific tag" },
1345  { "labelIsImage", xmipp_labelIsImage, METH_VARARGS,
1346  "Return if the label has the TAGLABEL_IMAGE tag" },
1347  { "str2Label", xmipp_str2Label, METH_VARARGS,
1348  "Convert an string to MDLabel" },
1349  { "isValidLabel", (PyCFunction) xmipp_isValidLabel,
1350  METH_VARARGS,
1351  "Check if the label is a valid one" },
1352  { "MDValueRelational",
1353  (PyCFunction) xmipp_MDValueRelational,
1354  METH_VARARGS, "Construct a relational query" },
1355  { "MDValueEQ", (PyCFunction) xmipp_MDValueEQ,
1356  METH_VARARGS, "Construct a relational query" },
1357  { "MDValueNE", (PyCFunction) xmipp_MDValueNE,
1358  METH_VARARGS, "Construct a relational query" },
1359  { "MDValueLT", (PyCFunction) xmipp_MDValueLT,
1360  METH_VARARGS, "Construct a relational query" },
1361  { "MDValueLE", (PyCFunction) xmipp_MDValueLE,
1362  METH_VARARGS, "Construct a relational query" },
1363  { "MDValueGT", (PyCFunction) xmipp_MDValueGT,
1364  METH_VARARGS, "Construct a relational query" },
1365  { "MDValueGE", (PyCFunction) xmipp_MDValueGE,
1366  METH_VARARGS, "Construct a relational query" },
1367  { "MDValueRange", (PyCFunction) xmipp_MDValueRange,
1368  METH_VARARGS, "Construct a range query" },
1369  { "addLabelAlias", (PyCFunction) xmipp_addLabelAlias,
1370  METH_VARARGS, "Add a label alias dinamically in run time. Use for reading non xmipp star files" },
1371  { "getNewAlias", (PyCFunction) xmipp_getNewAlias,
1372  METH_VARARGS, "Add a label dinamically in run time. Use for reading non xmipp star files" },
1373  { "createEmptyFile", (PyCFunction) xmipp_createEmptyFile,
1374  METH_VARARGS, "create empty stack (speed up things)" },
1375  { "getImageSize", (PyCFunction) xmipp_getImageSize,
1376  METH_VARARGS, "Get image dimensions" },
1377  { "MetaDataInfo", (PyCFunction) xmipp_MetaDataInfo, METH_VARARGS,
1378  "Get image dimensions of first metadata entry and the number of entries" },
1379  { "existsBlockInMetaDataFile", (PyCFunction) xmipp_existsBlockInMetaDataFile, METH_VARARGS,
1380  "Does block exists in file" },
1381  { "ImgCompare", (PyCFunction) xmipp_ImgCompare, METH_VARARGS,
1382  "return true if both files are identical" },
1383  { "checkImageFileSize", (PyCFunction) xmipp_CheckImageFileSize, METH_VARARGS,
1384  "return true if the file has at least as many bytes as needed to read the image" },
1385  { "checkImageCorners", (PyCFunction) xmipp_CheckImageCorners, METH_VARARGS,
1386  "return false if the image has repeated pixels at some corner" },
1387  { "compareTwoFiles", (PyCFunction) xmipp_compareTwoFiles, METH_VARARGS,
1388  "return true if both files are identical" },
1389  { "bsoftRemoveLoopBlock", (PyCFunction) xmipp_bsoftRemoveLoopBlock, METH_VARARGS,
1390  "convert bsoft star files to xmipp star files" },
1391  { "bsoftRestoreLoopBlock", (PyCFunction) xmipp_bsoftRestoreLoopBlock, METH_VARARGS,
1392  "convert xmipp star files to bsoft star files" },
1393  { "compareTwoImageTolerance", (PyCFunction) xmipp_compareTwoImageTolerance, METH_VARARGS,
1394  "return true if both images are very similar" },
1395  { "readMetaDataWithTwoPossibleImages", (PyCFunction) xmipp_readMetaDataWithTwoPossibleImages, METH_VARARGS,
1396  "Read a 1 or two column list of micrographs" },
1397  { "substituteOriginalImages", (PyCFunction) xmipp_substituteOriginalImages, METH_VARARGS,
1398  "Substitute the original images into a given column of a metadata" },
1399  { "compareTwoMetadataFiles", (PyCFunction) xmipp_compareTwoMetadataFiles, METH_VARARGS,
1400  "Compare two metadata files" },
1401  { "dumpToFile", (PyCFunction) xmipp_dumpToFile, METH_VARARGS,
1402  "dump metadata to sqlite database" },
1403  { "Euler_angles2matrix", (PyCFunction) xmipp_Euler_angles2matrix, METH_VARARGS,
1404  "convert euler angles to transformation matrix" },
1405  { "Euler_matrix2angles", (PyCFunction) xmipp_Euler_matrix2angles, METH_VARARGS,
1406  "convert transformation matrix to euler angles" },
1407  { "Euler_direction", (PyCFunction) xmipp_Euler_direction, METH_VARARGS,
1408  "converts euler angles to direction" },
1409  { "alignWithZ", (PyCFunction) xmipp_alignWithZ, METH_VARARGS,
1410  "align vector with Z" },
1411  { "activateMathExtensions", (PyCFunction) xmipp_activateMathExtensions,
1412  METH_VARARGS, "activate math function in metadatas" },
1413  { "activateRegExtensions", (PyCFunction) xmipp_activateRegExtensions,
1414  METH_VARARGS, "activate regular expressions in metadatas" },
1415  { "fastEstimateEnhancedPSD", (PyCFunction) xmipp_fastEstimateEnhancedPSD, METH_VARARGS,
1416  "Utility function to calculate PSD preview" },
1417  { "bandPassFilter", (PyCFunction) xmipp_bandPassFilter, METH_VARARGS,
1418  "Utility function to apply bandpass filter" },
1419  { "gaussianFilter", (PyCFunction) xmipp_gaussianFilter, METH_VARARGS,
1420  "Utility function to apply gaussian filter in Fourier space" },
1421  { "realGaussianFilter", (PyCFunction) xmipp_realGaussianFilter, METH_VARARGS,
1422  "Utility function to apply gaussian filter in Real space" },
1423  { "badPixelFilter", (PyCFunction) xmipp_badPixelFilter, METH_VARARGS,
1424  "Bad pixel filter" },
1425  { "errorBetween2CTFs", (PyCFunction) xmipp_errorBetween2CTFs,
1426  METH_VARARGS, "difference between two metadatas" },
1427  { "errorMaxFreqCTFs", (PyCFunction) xmipp_errorMaxFreqCTFs,
1428  METH_VARARGS, "resolution at which CTFs phase differs more than 90 degrees" },
1429  { "errorMaxFreqCTFs2D", (PyCFunction) xmipp_errorMaxFreqCTFs2D,
1430  METH_VARARGS, "resolution at which CTFs phase differs more than 90 degrees, 2D case" },
1431  { "convertPSD", (PyCFunction) Image_convertPSD, METH_VARARGS,
1432  "Convert to PSD: center FFT and use logarithm" },
1433  { "image_align", (PyCFunction) Image_align, METH_VARARGS,
1434  "I2aligned=image_align(I1,I2), align I2 to resemble I1." },
1435  { "applyCTF", (PyCFunction) Image_applyCTF, METH_VARARGS,
1436  "Apply CTF to this image. Ts is the sampling rate of the image." },
1437  { "projectVolumeDouble", (PyCFunction) Image_projectVolumeDouble, METH_VARARGS,
1438  "project a volume using Euler angles" },
1439  { nullptr } /* Sentinel */
1440  };//xmipp_methods
1441 
1442 #define INIT_TYPE(type) if (PyType_Ready(&type##Type) < 0) return module; Py_INCREF(&type##Type);\
1443  PyModule_AddObject(module, #type, (PyObject *) &type##Type);
1444 
1445 
1446 static struct PyModuleDef moduledef = {
1447  PyModuleDef_HEAD_INIT,
1448  "xmippLib", /* m_name */
1449  "xmippLib objects", /* m_doc */
1450  -1, /* m_size */
1451  xmipp_methods /* m_methods */
1452 };
1453 
1454 PyMODINIT_FUNC
1456  //Initialize module variable
1457 
1458  PyObject *module = PyModule_Create(&moduledef);
1459 
1460  //Check types and add to module
1462  INIT_TYPE(Image);
1463  INIT_TYPE(MDQuery);
1465  INIT_TYPE(Program);
1466  INIT_TYPE(SymList);
1468 
1469 
1470  //Add PyXmippError
1471  char message[32]="xmipp.XmippError";
1472  PyXmippError = PyErr_NewException(message, nullptr, nullptr);
1473  Py_INCREF(PyXmippError);
1474  PyModule_AddObject(module, "XmippError", PyXmippError);
1475 
1476  //Add MDLabel constants
1477  PyObject * dict = PyModule_GetDict(module);
1478  addLabels(dict);
1479 
1480  return module;
1481 }
std::string datatype2Str(DataType datatype)
PyObject * xmipp_errorMaxFreqCTFs2D(PyObject *obj, PyObject *args, PyObject *kwargs)
void bsoftRemoveLoopBlock(const FileName &_inFile, const FileName &_outFile)
virtual void setMaxRows(size_t maxRows=0)
#define FILTER_TRY()
PyObject * xmipp_labelIsImage(PyObject *obj, PyObject *args)
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
PyTypeObject ImageType
size_t xdim
PyObject_HEAD std::unique_ptr< ImageGeneric > image
Definition: python_image.h:50
static MDLabel str2Label(const String &labelName)
void addLabels(PyObject *dict)
PyObject * xmipp_MDValueGT(PyObject *obj, PyObject *args, PyObject *kwargs)
PyMODINIT_FUNC PyInit_xmippLib(void)
PyObject * xmipp_MDValueEQ(PyObject *obj, PyObject *args, PyObject *kwargs)
static bool activateMathExtensions(void)
String colorString(const char *msg, int color, int attribute, int bgcolor)
Definition: xmipp_color.cpp:28
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
PyObject * xmipp_str2Label(PyObject *obj, PyObject *args)
Definition: xmippmodule.cpp:53
void Euler_direction(double alpha, double beta, double gamma, Matrix1D< double > &v)
Definition: geometry.cpp:721
PyObject * xmipp_dumpToFile(PyObject *obj, PyObject *args, PyObject *kwargs)
PyObject * xmipp_createEmptyFile(PyObject *obj, PyObject *args, PyObject *kwargs)
#define INIT_TYPE(type)
void gaussianFilter(MultidimArray< double > &img, double w1)
PyObject * xmipp_alignWithZ(PyObject *obj, PyObject *args, PyObject *kwargs)
static double * y
#define Image_Value(v)
Definition: python_image.h:44
void apply(MultidimArray< double > &img)
Definition: filters.cpp:3600
static bool isValidLabel(const MDLabel &label)
#define FileName_Check(v)
PyObject * PyXmippError
Definition: xmippmodule.cpp:47
bool existsBlockInMetaDataFile(const FileName &inFileWithBlock)
void getImageSize(const MetaData &md, size_t &Xdim, size_t &Ydim, size_t &Zdim, size_t &Ndim, MDLabel image_label)
PyObject * xmipp_compareTwoFiles(PyObject *obj, PyObject *args, PyObject *kwargs)
PyObject * xmipp_ImgCompare(PyObject *obj, PyObject *args, PyObject *kwargs)
PyObject * xmipp_MetaDataInfo(PyObject *obj, PyObject *args, PyObject *kwargs)
PyObject * xmipp_badPixelFilter(PyObject *obj, PyObject *args, PyObject *kwargs)
#define MULTIDIM_ARRAY(v)
PyObject * xmipp_MDValueRange(PyObject *obj, PyObject *args, PyObject *kwargs)
void substituteOriginalImages(const FileName &fn, const FileName &fnOrig, const FileName &fnOut, MDLabel label, bool skipFirstBlock)
T * mdata
Definition: matrix2d.h:395
PyObject * xmipp_getImageSize(PyObject *obj, PyObject *args, PyObject *kwargs)
PyObject * Image_convertPSD(PyObject *obj, PyObject *args, PyObject *kwargs)
double errorMaxFreqCTFs2D(MetaData &MD1, MetaData &MD2, size_t Xdim, double phaseRad)
Definition: ctf.cpp:214
PyObject * xmipp_addLabelAlias(PyObject *obj, PyObject *args, PyObject *kwargs)
doublereal * x
#define i
void selfScaleToSize(int SplineDegree, MultidimArrayGeneric &V1, int Xdim, int Ydim, int Zdim)
PyObject * xmipp_MDValueRelational(PyObject *obj, PyObject *args, PyObject *kwargs)
static bool activateRegExtensions(void)
void read(const FileName &fn, bool disable_if_not_K=true)
Definition: ctf.cpp:1220
bool enable_CTF
Enable CTF part.
Definition: ctf.h:275
static MDLabelType labelType(const MDLabel label)
#define FILTER_CATCH()
PyObject * xmipp_Euler_direction(PyObject *obj, PyObject *args, PyObject *kwargs)
PyObject * xmipp_substituteOriginalImages(PyObject *obj, PyObject *args, PyObject *kwargs)
SWIGINTERN int PyModule_AddObject(PyObject *m, char *name, PyObject *o)
Definition: frm_wrap.cpp:2694
PyObject * xmipp_fastEstimateEnhancedPSD(PyObject *obj, PyObject *args, PyObject *kwargs)
PyObject * xmipp_bandPassFilter(PyObject *obj, PyObject *args, PyObject *kwargs)
void xmipp2PSD(const MultidimArray< T > &input, MultidimArray< T > &output, bool takeLog)
Definition: xmipp_fft.cpp:443
bool compareImage(const FileName &filename1, const FileName &filename2)
compare two image files
PyObject * xmipp_getBlocksInMetaDataFile(PyObject *obj, PyObject *args)
PyObject * xmipp_bsoftRestoreLoopBlock(PyObject *obj, PyObject *args, PyObject *kwargs)
void applyCTF(MultidimArray< std::complex< double > > &FFTI, const MultidimArray< double > &I, double Ts, bool absPhase=false)
Apply CTF to an image.
Definition: ctf.cpp:1521
PyObject * xmipp_isValidLabel(PyObject *obj, PyObject *args, PyObject *kwargs)
#define Image_Check(v)
Definition: python_image.h:43
void readFromMetadataRow(const MetaData &MD, size_t id, bool disable_if_not_K=true)
Definition: ctf.cpp:1214
int in
FileName fnOut
PyObject * xmipp_activateRegExtensions(PyObject *obj, PyObject *args, PyObject *kwargs)
void bsoftRestoreLoopBlock(const FileName &_inFile, const FileName &_outFile)
PyObject * xmipp_bsoftRemoveLoopBlock(PyObject *obj, PyObject *args, PyObject *kwargs)
bool compareTwoImageTolerance(const FileName &fn1, const FileName &fn2, double tolerance, size_t index1, size_t index2)
binary comparison of two images with a tolerance factor
PyObject * xmipp_compareTwoMetadataFiles(PyObject *obj, PyObject *args, PyObject *kwargs)
double errorBetween2CTFs(MetaData &MD1, MetaData &MD2, size_t Xdim, double minFreq, double maxFreq)
Definition: ctf.cpp:107
#define MetaData_Check(v)
PyObject * xmipp_gaussianFilter(PyObject *obj, PyObject *args, PyObject *kwargs)
#define FileName_Value(v)
PyObject * xmipp_getNewAlias(PyObject *obj, PyObject *args, PyObject *kwargs)
static void dumpToFile(const FileName &fileName)
bool compareTwoFiles(const FileName &fn1, const FileName &fn2, size_t offset)
binary comparison of two files skipping first "offset" bytes
bool validateInputImageString(PyObject *pyImage, PyObject *pyStrFn, FileName &fn)
double z
PyObject * xmipp_compareTwoImageTolerance(PyObject *obj, PyObject *args, PyObject *kwargs)
void readMetaDataWithTwoPossibleImages(const FileName &fn, MetaData &md)
void projectVolume(FourierProjector &projector, Projection &P, int Ydim, int Xdim, double rot, double tilt, double psi, const MultidimArray< double > *ctf)
DataType
void direction(const MultidimArray< double > &orMap, MultidimArray< double > &qualityMap, double lambda, int size, MultidimArray< double > &dirMap, int x, int y)
PyObject * Image_align(PyObject *obj, PyObject *args, PyObject *kwargs)
void createEmptyFile(const FileName &filename, int xdim, int ydim, int Zdim, size_t select_img, bool isStack, int mode, int _swapWrite, const MDRowVec *md)
#define MetaData_Value(v)
PyObject * xmipp_activateMathExtensions(PyObject *obj, PyObject *args, PyObject *kwargs)
virtual size_t size() const =0
PyObject * xmipp_labelHasTag(PyObject *obj, PyObject *args)
PyObject * xmipp_colorStr(PyObject *obj, PyObject *args)
Definition: xmippmodule.cpp:74
double factor
Definition: filters.h:1471
PyObject * xmipp_label2Str(PyObject *obj, PyObject *args)
Definition: xmippmodule.cpp:62
PyObject * xmipp_readMetaDataWithTwoPossibleImages(PyObject *obj, PyObject *args, PyObject *kwargs)
PyObject * xmipp_Euler_angles2matrix(PyObject *obj, PyObject *args, PyObject *kwargs)
double errorMaxFreqCTFs(MetaData &MD1, double phaseRad)
Definition: ctf.cpp:187
void bandpassFilter(MultidimArray< double > &img, double w1, double w2, double raised_w)
virtual size_t getParsedLines()
#define MULTIDIM_ARRAY_GENERIC(v)
PyObject * xmipp_CheckImageFileSize(PyObject *obj, PyObject *args, PyObject *kwargs)
PyObject * xmipp_errorMaxFreqCTFs(PyObject *obj, PyObject *args, PyObject *kwargs)
void realGaussianFilter(MultidimArray< double > &img, double sigma)
PyObject * xmipp_Euler_matrix2angles(PyObject *obj, PyObject *args, PyObject *kwargs)
PyObject * xmipp_CheckImageCorners(PyObject *obj, PyObject *args, PyObject *kwargs)
PyObject * xmipp_MDValueGE(PyObject *obj, PyObject *args, PyObject *kwargs)
std::string String
Definition: xmipp_strings.h:34
void produceSideInfo()
Produce Side information.
Definition: ctf.cpp:1392
double psi(const double x)
void Euler_matrix2angles(const Matrix2D< double > &A, double &alpha, double &beta, double &gamma, bool homogeneous)
Definition: geometry.cpp:839
#define VECTOR_R3(v, x, y, z)
Definition: matrix1d.h:124
BadPixelFilterType type
Definition: filters.h:1470
PyObject * Image_projectVolumeDouble(PyObject *obj, PyObject *args, PyObject *kwargs)
static bool hasTag(const MDLabel label, const int tags)
doublereal * u
size_t ydim
void(* obj)()
static String label2Str(const MDLabel &label)
PyObject * xmipp_realGaussianFilter(PyObject *obj, PyObject *args, PyObject *kwargs)
bool enable_CTFnoise
Enable CTFnoise part.
Definition: ctf.h:273
PyObject * xmipp_existsBlockInMetaDataFile(PyObject *obj, PyObject *args, PyObject *kwargs)
void alignWithZ(const Matrix1D< double > &axis, Matrix2D< double > &result, bool homogeneous)
bool compareTwoMetadataFiles(const FileName &fn1, const FileName &fn2)
PyObject * xmipp_MDValueLT(PyObject *obj, PyObject *args, PyObject *kwargs)
double alignImagesConsideringMirrors(const MultidimArray< double > &Iref, const AlignmentTransforms &IrefTransforms, MultidimArray< double > &I, Matrix2D< double > &M, AlignmentAux &aux, CorrelationAux &aux2, RotationalCorrelationAux &aux3, bool wrap, const MultidimArray< int > *mask)
Definition: filters.cpp:2150
PyObject * Image_applyCTF(PyObject *obj, PyObject *args, PyObject *kwargs)
MDLabel
void fastEstimateEnhancedPSD(const FileName &fnMicrograph, double downsampling, MultidimArray< double > &enhancedPSD, int numberOfThreads)
bool checkImageFileSize(const FileName &name, const ImageInfo &imgInfo, bool error)
PyObject * xmipp_MDValueLE(PyObject *obj, PyObject *args, PyObject *kwargs)
PyObject * xmipp_errorBetween2CTFs(PyObject *obj, PyObject *args, PyObject *kwargs)
virtual void read(const FileName &inFile, const std::vector< MDLabel > *desiredLabels=nullptr, bool decomposeStack=true)=0
bool checkImageCorners(const FileName &name)
PyObject * xmipp_labelType(PyObject *obj, PyObject *args)
Definition: xmippmodule.cpp:88
PyObject * xmipp_MDValueNE(PyObject *obj, PyObject *args, PyObject *kwargs)
void getDimensions(size_t &Xdim, size_t &Ydim, size_t &Zdim, size_t &Ndim) const