EMAN2
processor.h
Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
00007  * Copyright (c) 2000-2006 Baylor College of Medicine
00008  *
00009  * This software is issued under a joint BSD/GNU license. You may use the
00010  * source code in this file under either license. However, note that the
00011  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00012  * so you are responsible for compliance with the licenses of these packages
00013  * if you opt to use BSD licensing. The warranty disclaimer below holds
00014  * in either instance.
00015  *
00016  * This complete copyright notice must be included in any revised version of the
00017  * source code. Additional authorship citations may be added, but existing
00018  * author citations must be preserved.
00019  *
00020  * This program is free software; you can redistribute it and/or modify
00021  * it under the terms of the GNU General Public License as published by.edge
00022  * the Free Software Foundation; either version 2 of the License, or
00023  * (at your option) any later version.
00024  *
00025  * This program is distributed in the hope that it will be useful,
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00028  * GNU General Public License for more details.
00029  *
00030  * You should have received a copy of the GNU General Public License
00031  * along with this program; if not, write to the Free Software
00032  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00033  *
00034  * */
00035 
00036 #ifndef eman_processor_h__
00037 #define eman_processor_h__ 1
00038 
00039 #include "emobject.h"
00040 #include "util.h"
00041 #include "geometry.h"
00042 #include "transform.h"
00043 #include "emdata.h"
00044 #include "gorgon/skeletonizer.h"
00045 
00046 #include <cfloat>
00047 #include <climits>
00048 #include <cstring>
00049 
00050 using std::vector;
00051 using std::map;
00052 using std::string;
00053 
00054 namespace EMAN
00055 {
00056         class EMData;
00057 
00093         class Processor
00094         {
00095           public:
00096                 virtual ~ Processor()
00097                 {
00098                 }
00099 
00105                 virtual void process_inplace(EMData *image) = 0;
00106 
00113                 virtual EMData* process(const EMData * const image);
00114 
00118                 virtual void process_list_inplace(vector < EMData * > & images)
00119                 {
00120                         for (size_t i = 0; i < images.size(); i++) {
00121                                 process_inplace(images[i]);
00122                         }
00123                 }
00124 
00128                 virtual string get_name() const = 0;
00129 
00133                 virtual Dict get_params() const
00134                 {
00135                         return params;
00136                 }
00137 
00141                 virtual void set_params(const Dict & new_params)
00142                 {
00143                         params = new_params;
00144                 }
00145 
00152                 virtual TypeDict get_param_types() const
00153                 {
00154                         return TypeDict();
00155                 }
00156 
00163                 static string get_group_desc()
00164                 {
00165                         return "EMAN processors are in-place image processors. You may apply a processor to process a single image or process multiple images. Processor class is the base class for all processor. <br> \
00166 The basic design of EMAN Processors: <br>\
00167     1) Each Processor class defines an image-processinging algorithm. <br>\
00168     2) All the Processor classes in EMAN are managed by a Factory pattern. So each Processor class must define: <br> a) a unique name to idenfity itself in the factory. <br>b) a static method to register itself in the factory.<br>\
00169     3) Each Processor class defines its own parameter set.<br>\
00170     4) Each Processor class defines functions to return its documentation including parameter information, and processor description. These functions enable EMAN to generate processor manuals dynamically.";
00171                 }
00172 
00178                 virtual string get_desc() const = 0;
00179 
00186                 enum fourier_filter_types {
00187                         TOP_HAT_LOW_PASS,
00188                         TOP_HAT_HIGH_PASS,
00189                         TOP_HAT_BAND_PASS,
00190                         TOP_HOMOMORPHIC,
00191                         GAUSS_LOW_PASS,
00192                         GAUSS_HIGH_PASS,
00193                         GAUSS_BAND_PASS,
00194                         GAUSS_INVERSE,
00195                         GAUSS_HOMOMORPHIC,
00196                         BUTTERWORTH_LOW_PASS,
00197                         BUTTERWORTH_HIGH_PASS,
00198                         BUTTERWORTH_HOMOMORPHIC,
00199                         KAISER_I0,
00200                         KAISER_SINH,
00201                         KAISER_I0_INVERSE,
00202                         KAISER_SINH_INVERSE,
00203                         SHIFT,
00204                         TANH_LOW_PASS,
00205                         TANH_HIGH_PASS,
00206                         TANH_HOMOMORPHIC,
00207                         TANH_BAND_PASS,
00208                         RADIAL_TABLE,
00209                         CTF_,
00210                 };
00211 
00236                 static void
00237                 EMFourierFilterInPlace(EMData* fimage, Dict params) {
00238                         bool doInPlace = true;
00239                         EMFourierFilterFunc(fimage, params, doInPlace);
00240                 }
00241 
00267                 static EMData*
00268                 EMFourierFilter(EMData* fimage, Dict params) {
00269                         bool doInPlace = false;
00270                         return EMFourierFilterFunc(fimage, params, doInPlace);
00271                 }
00272 
00273           private:
00309                 static EMData*
00310                 EMFourierFilterFunc(EMData* fimage, Dict params, bool doInPlace=true);
00311 
00312           protected:
00313                 mutable Dict params;
00314         };
00315 
00316         class ImageProcessor:public Processor
00317         {
00318           public:
00319                 void process_inplace(EMData * image);
00320 
00321                 static string get_group_desc()
00322                 {
00323                         return "An Image Processor defines a way to create a processor image. The processor image is used to multiply the input-image in the fourier space. ImageFilter class is the base class. Each specific ImageFilter class must define function create_processor_image(). ";
00324                 }
00325 
00326           protected:
00327                 virtual EMData * create_processor_image() const = 0;
00328         };
00329 
00336         class FourierProcessor:public Processor
00337         {
00338           public:
00339                 void process_inplace(EMData * image);
00340 
00341                 static string get_group_desc()
00342                 {
00343                         return "Fourier Filter processors are a group of processor in the frequency domain. Before using such processors on an image, the image must be transformed from real space to the fourier space. FourierProcessor class is the base class of fourier space processors. Each specific processor is either a lowpass filter processor, or a highpass filter processor, or neighter. The unit of lowpass and highpass parameters are in terms of Nyquist, valid range is [0,0.5]. ";
00344                 }
00345 
00346                 TypeDict get_param_types() const
00347                 {
00348                         TypeDict d;
00349                         d.put("cutoff_abs", EMObject::FLOAT, "Processor radius in terms of Nyquist (0-.5)");
00350                         d.put("cutoff_pixels", EMObject::FLOAT, " Width in Fourier pixels (0 - size()/2)");
00351                         d.put("cutoff_freq", EMObject::FLOAT, "1/Resolution in 1/A (0 - 1 / 2*apix). eg - a 20 A filter is cutoff_freq=0.05");
00352                         d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
00353                         d.put("return_radial", EMObject::BOOL, "Return the radial filter function as an attribute (filter_curve)");
00354                         return d;
00355                 }
00356 
00357           protected:
00358                   virtual void preprocess(EMData *image) {
00359                         if(params.has_key("apix")) {
00360                                 image->set_attr("apix_x", (float)params["apix"]);
00361                                 image->set_attr("apix_y", (float)params["apix"]);
00362                                 image->set_attr("apix_z", (float)params["apix"]);
00363                         }
00364 
00365                         const Dict dict = image->get_attr_dict();
00366                         if( params.has_key("sigma")) {
00367                                 params["cutoff_abs"] = (float)params["sigma"];
00368                         }
00369                         else if( params.has_key("cutoff_abs") ) {
00370                                 params["sigma"] = (float)params["cutoff_abs"];
00371                         }
00372                         else if( params.has_key("cutoff_freq") ) {
00373                                 float val =  (float)params["cutoff_freq"] * (float)dict["apix_x"];
00374                                 params["cutoff_abs"] = val;
00375                                 params["sigma"] = val;
00376                         }
00377                         else if( params.has_key("cutoff_pixels") ) {
00378                                 float val = (0.5f*(float)params["cutoff_pixels"] / (float)dict["nx"]);
00379                                 params["cutoff_abs"] = val;
00380                                 params["sigma"] = val;
00381                         }
00382 
00383                         }
00384                   virtual void create_radial_func(vector < float >&radial_mask) const = 0;
00385         };
00386 
00394         class FourierAnlProcessor:public Processor
00395         {
00396           public:
00397                 void process_inplace(EMData * image);
00398 
00399                 static string get_group_desc()
00400                 {
00401                         return "Fourier Filter processors are a group of processor in the frequency domain. Before using such processors on an image, the image must be transformed from real space to the fourier space. FourierProcessor class is the base class of fourier space processors. Each specific processor is either a lowpass filter processor, or a highpass filter processor, or neighter. The unit of lowpass and highpass parameters are in terms of Nyquist, valid range is [0,0.5]. ";
00402                 }
00403 
00404                 TypeDict get_param_types() const
00405                 {
00406                         TypeDict d;
00407                         d.put("cutoff_abs", EMObject::FLOAT, "Processor radius in terms of Nyquist (0-.5)");
00408                         d.put("cutoff_pixels", EMObject::FLOAT, " Width in Fourier pixels (0 - size()/2)");
00409                         d.put("cutoff_freq", EMObject::FLOAT, "1/Resolution in 1/A (0 - 1 / 2*apix). eg - a 20 A filter is cutoff_freq=0.05");
00410                         d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
00411                         d.put("return_radial", EMObject::BOOL, "Return the radial filter function as an attribute (filter_curve)");
00412                         d.put("interpolate", EMObject::BOOL, "Whether or not to interpolate the radial scaling function. Default=false. Prb should be true.");
00413                         return d;
00414                 }
00415 
00416           protected:
00417                   virtual void preprocess(EMData *) {}
00418                   virtual void create_radial_func(vector < float >&radial_mask,EMData *image) const = 0;
00419         };
00420 
00423         class SNREvalProcessor:public Processor
00424         {
00425                 public:
00426                 string get_name() const
00427                 {
00428                         return NAME;
00429                 }
00430 
00431                 void process_inplace(EMData * image);
00432 
00433                 void set_params(const Dict & new_params)
00434                 {
00435                         params = new_params;
00436 //                      sum = params["sum"];
00437 //                      dosqrt = params["sqrt"];
00438 //                      printf("%s %f\n",params.keys()[0].c_str(),lowpass);
00439                 }
00440 
00441                 TypeDict get_param_types() const
00442                 {
00443                         TypeDict d;
00444 //                      d.put("sum", EMObject::EMDATA, "Adds the weights to sum for normalization");
00445 //                      d.put("sqrt", EMObject::INT, "Weights using sqrt of the amplitude if set");
00446                         return d;
00447                 }
00448 
00449                 static Processor *NEW()
00450                 {
00451                         return new SNREvalProcessor();
00452                 }
00453 
00454                 string get_desc() const
00455                 {
00456                         return "Evaluates the SNR of the particle using a masking method similar to that used in the CTF analysis process. The image is not changed. The resulting value is placed in the particle dictionary as eval_maskedsnr";
00457                 }
00458 
00459                 static const string NAME;
00460 
00461                 protected:
00462                 EMData *sum;
00463                 int dosqrt;
00464         };
00465 
00468         class Axis0FourierProcessor:public Processor
00469         {
00470           public:
00471                 string get_name() const
00472                 {
00473                         return NAME;
00474                 }
00475 
00476                 void process_inplace(EMData * image);
00477 
00478                 void set_params(const Dict & new_params)
00479                 {
00480                         params = new_params;
00481                 }
00482 
00483                 TypeDict get_param_types() const
00484                 {
00485                         TypeDict d;
00486                         d.put("x", EMObject::INT, "If set, zeroes along X axis. Default True.");
00487                         d.put("y", EMObject::INT, "If set, zeroes along X axis. Default True.");
00488                         return d;
00489                 }
00490 
00491                 static Processor *NEW()
00492                 {
00493                         return new Axis0FourierProcessor();
00494                 }
00495 
00496                 string get_desc() const
00497                 {
00498                         return "Sets values along X/Y Fourier axes to 0, except origin";
00499                 }
00500 
00501                 static const string NAME;
00502 
00503                 protected:
00504         };
00505 
00506 
00511         class AmpweightFourierProcessor:public Processor
00512         {
00513           public:
00514                 string get_name() const
00515                 {
00516                         return NAME;
00517                 }
00518 
00519                 void process_inplace(EMData * image);
00520 
00521                 void set_params(const Dict & new_params)
00522                 {
00523                         params = new_params;
00524                         sum = params["sum"];
00525                         dosqrt = params["sqrt"];
00526 //                      printf("%s %f\n",params.keys()[0].c_str(),lowpass);
00527                 }
00528 
00529                 TypeDict get_param_types() const
00530                 {
00531                         TypeDict d;
00532                         d.put("sum", EMObject::EMDATA, "Adds the weights to sum for normalization");
00533                         d.put("sqrt", EMObject::INT, "Weights using sqrt of the amplitude if set");
00534                         return d;
00535                 }
00536 
00537                 static Processor *NEW()
00538                 {
00539                         return new AmpweightFourierProcessor();
00540                 }
00541 
00542                 string get_desc() const
00543                 {
00544                         return "Multiplies each Fourier pixel by its amplitude";
00545                 }
00546 
00547                 static const string NAME;
00548 
00549                 protected:
00550                 EMData *sum;
00551                 int dosqrt;
00552         };
00559         class ConvolutionProcessor : public Processor
00560         {
00561                 public:
00562                         ConvolutionProcessor() {}
00563 
00564                         string get_name() const
00565                         {
00566                                 return NAME;
00567                         }
00568 
00569                         void process_inplace(EMData *image);
00570 
00571                         static Processor *NEW()
00572                         {
00573                                 return new ConvolutionProcessor();
00574                         }
00575 
00576                         string get_desc() const
00577                         {
00578                                 return "Performs Fourier space convolution. Maintains the space that the image is in - i.e. if image is real, the result is real and vice versa.";
00579                         }
00580 
00581                         TypeDict get_param_types() const
00582                         {
00583                                 TypeDict d;
00584                                 d.put("with", EMObject::EMDATA, "The image that will convolute the other image");
00585                                 return d;
00586                         }
00587 
00588                         static const string NAME;
00589         };
00590 
00597         class XGradientProcessor : public Processor
00598         {
00599          public:
00600                 XGradientProcessor() {}
00601 
00602                 string get_name() const
00603                 {
00604                         return NAME;
00605                 }
00606 
00607                 void process_inplace(EMData *image);
00608 
00609                 static Processor *NEW()
00610                 {
00611                         return new XGradientProcessor();
00612                 }
00613 
00614                 string get_desc() const
00615                 {
00616                         return "Determines the image gradient in the x direction";
00617                 }
00618 
00619                 TypeDict get_param_types() const
00620                 {
00621                         TypeDict d;
00622                         return d;
00623                 }
00624 
00625                 static const string NAME;
00626         };
00627 
00628         class YGradientProcessor : public Processor
00629         {
00630                 public:
00631                         YGradientProcessor() {}
00632 
00633                         string get_name() const
00634                         {
00635                                 return NAME;
00636                         }
00637 
00638                         void process_inplace(EMData *image);
00639 
00640                         static Processor *NEW()
00641                         {
00642                                 return new YGradientProcessor();
00643                         }
00644 
00645                         string get_desc() const
00646                         {
00647                                 return "Determines the image gradient in the y direction";
00648                         }
00649 
00650 
00651                         TypeDict get_param_types() const
00652                         {
00653                                 TypeDict d;
00654                                 return d;
00655                         }
00656 
00657                         static const string NAME;
00658         };
00659 
00660         class ZGradientProcessor : public Processor
00661         {
00662                 public:
00663                         ZGradientProcessor() {}
00664 
00665                         string get_name() const
00666                         {
00667                                 return NAME;
00668                         }
00669 
00670                         void process_inplace(EMData *image);
00671 
00672                         static Processor *NEW()
00673                         {
00674                                 return new ZGradientProcessor();
00675                         }
00676 
00677                         string get_desc() const
00678                         {
00679                                 return "Determines the image gradient in the z direction";
00680                         }
00681 
00682                         TypeDict get_param_types() const
00683                         {
00684                                 TypeDict d;
00685                                 return d;
00686                         }
00687 
00688                         static const string NAME;
00689         };
00690 
00699         class Wiener2DAutoAreaProcessor:public Processor
00700         {
00701           public:
00702                 string get_name() const
00703                 {
00704                         return NAME;
00705                 }
00706 
00707                 virtual EMData* process(const EMData * const image);
00708 
00709                 void process_inplace(EMData *image);
00710 
00711                 void set_params(const Dict & new_params)
00712                 {
00713                         params = new_params;
00714                         bgsize = params["size"];
00715 //                      printf("%s %f\n",params.keys()[0].c_str(),lowpass);
00716                 }
00717 
00718                 TypeDict get_param_types() const
00719                 {
00720                         TypeDict d;
00721                         d.put("size", EMObject::INT, "Size in pixels of the boxes to chop the image into");
00722                         return d;
00723                 }
00724 
00725                 static Processor *NEW()
00726                 {
00727                         return new Wiener2DAutoAreaProcessor();
00728                 }
00729 
00730                 string get_desc() const
00731                 {
00732                         return "Automatically detrmines the background for the image then uses this to perform Wiener filters on overlapping subregions of the image, which are then combined using linear interpolation";
00733                 }
00734 
00735                 static const string NAME;
00736 
00737                 protected:
00738                 int bgsize;
00739         };
00740 
00747         class DistanceSegmentProcessor:public Processor
00748         {
00749           public:
00750                 string get_name() const
00751                 {
00752                         return NAME;
00753                 }
00754 
00755                 virtual EMData* process(const EMData * const image);
00756                 void process_inplace( EMData * image);
00757 
00758                 TypeDict get_param_types() const
00759                 {
00760                         TypeDict d ;
00761                         d.put("thr",EMObject::FLOAT,"Optional : Isosurface threshold value. Pixels below this will not be segment centers (default = 0.9)");
00762                         d.put("minsegsep",EMObject::FLOAT,"Required: Minimum segment separation in pixels. Segments too close will trigger a reseed");
00763                         d.put("maxsegsep",EMObject::FLOAT,"Required: Maximum segment separation in pixels. Segments too close will trigger a reseed");
00764                         d.put("verbose",EMObject::INT,"Be verbose while running");
00765                         return d;
00766                 }
00767 
00768                 static Processor *NEW()
00769                 {
00770                         return new DistanceSegmentProcessor();
00771                 }
00772 
00773                 string get_desc() const
00774                 {
00775                         return "Segments a volume into pieces separated by distances in the specified range.";
00776                 }
00777 
00778                 static const string NAME;
00779 
00780         };
00781 
00788         class KmeansSegmentProcessor:public Processor
00789         {
00790           public:
00791                 string get_name() const
00792                 {
00793                         return NAME;
00794                 }
00795 
00796                 virtual EMData* process(const EMData * const image);
00797                 void process_inplace( EMData * image);
00798 
00799                 TypeDict get_param_types() const
00800                 {
00801                         TypeDict d ;
00802                         d.put("nseg", EMObject::INT, "Number of segments to divide the image into. default=12" );
00803                         d.put("thr",EMObject::FLOAT,"Isosurface threshold value. Pixels below this will not be segmented");
00804                         d.put("ampweight",EMObject::INT,"If set, will weight centers by voxel amplitude. default = 1");
00805                         d.put("maxsegsize",EMObject::FLOAT,"Maximum radial distance from segment center to member voxel. Default=10000");
00806                         d.put("minsegsep",EMObject::FLOAT,"Minimum segment separation. Segments too close will trigger a reseed");
00807                         d.put("maxiter",EMObject::FLOAT,"Maximum number of iterations to run before stopping. Default=100");
00808                         d.put("maxvoxmove",EMObject::FLOAT,"Maximum number of voxels that can move before quitting. Default=25");
00809                         d.put("verbose",EMObject::INT,"Be verbose while running");
00815                         d.put("psudoatom",EMObject::BOOL,"Doing psudoatom generation");
00816                         d.put("sep",EMObject::FLOAT,"Separation distance, used only in psudoatom generation. Default=3.78");
00817                         return d;
00818                 }
00819 
00820                 static Processor *NEW()
00821                 {
00822                         return new KmeansSegmentProcessor();
00823                 }
00824 
00825                 string get_desc() const
00826                 {
00827                         return "Performs K-means segmentation on a volume. Note that this method uses random seeds, and thus will return different results each time it is run. Returned map contains number of segment for each voxel (or 0 for unsegmented voxels). Segmentation centers are stored in 'segmentcenters' attribute, consisting of a list of 3n floats in x,y,z triples.";
00828                 }
00829 
00830                 static const string NAME;
00831 
00832         };
00833 
00834 
00848         class CtfSimProcessor:public Processor
00849         {
00850           public:
00851                 string get_name() const
00852                 {
00853                         return NAME;
00854                 }
00855 
00856                 virtual EMData* process(const EMData * const image);
00857 
00858                 void process_inplace(EMData *image);
00859 
00860                 TypeDict get_param_types() const
00861                 {
00862                         TypeDict d;
00863                         d.put("defocus", EMObject::FLOAT, "Defocus in microns (underfocus positive)");
00864                         d.put("ampcont", EMObject::FLOAT, "% amplitude contrast (0-100)");
00865                         d.put("bfactor", EMObject::FLOAT, "B-factor in A^2, uses MRC convention rather than EMAN1 convention");
00866                         d.put("noiseamp", EMObject::FLOAT, "Amplitude of the added empirical pink noise");
00867                         d.put("noiseampwhite", EMObject::FLOAT, "Amplitude of added white noise");
00868                         d.put("voltage", EMObject::FLOAT, "Microscope voltage in KV");
00869                         d.put("cs", EMObject::FLOAT, "Cs of microscope in mm");
00870                         d.put("apix", EMObject::FLOAT, "A/pix of data");
00871                         return d;
00872                 }
00873 
00874                 static Processor *NEW()
00875                 {
00876                         return new CtfSimProcessor();
00877                 }
00878 
00879                 string get_desc() const
00880                 {
00881                         return "Applies a simulated CTF with noise to an image. The added noise is either white or based on an empirical curve generated from cryoEM data. ";
00882                 }
00883 
00884                 static const string NAME;
00885 
00886 //              protected:
00887         };
00888 
00889 
00896         class Wiener2DFourierProcessor:public Processor
00897         {
00898           public:
00899                 string get_name() const
00900                 {
00901                         return NAME;
00902                 }
00903 
00904                 virtual EMData* process(const EMData * const image);
00905 
00906                 void process_inplace(EMData *image);
00907 
00908                 void set_params(const Dict & new_params)
00909                 {
00910                         params = new_params;
00911                         ctf = params["ctf"];
00912 //                      printf("%s %f\n",params.keys()[0].c_str(),lowpass);
00913                 }
00914 
00915                 TypeDict get_param_types() const
00916                 {
00917                         TypeDict d;
00918                         d.put("ctf", EMObject::EMDATA, "Ctf object to use for Wiener filter parameters");
00919                         return d;
00920                 }
00921 
00922                 static Processor *NEW()
00923                 {
00924                         return new Wiener2DFourierProcessor();
00925                 }
00926 
00927                 string get_desc() const
00928                 {
00929                         return "Applies a 2-D Wiener filter to an image based on its Ctf parameters";
00930                 }
00931 
00932                 static const string NAME;
00933 
00934                 protected:
00935                 Ctf *ctf;
00936         };
00937 
00938         class LinearRampFourierProcessor:public FourierProcessor
00939         {
00940                 public:
00941                         virtual string get_name() const
00942                         {
00943                                 return NAME;
00944                         }
00945 
00946                         virtual string get_desc() const
00947                         {
00948                                 return "";
00949                         }
00950 
00951                         static Processor *NEW()
00952                         {
00953                                 return new LinearRampFourierProcessor();
00954                         }
00955 
00956                         static const string NAME;
00957 
00958                 protected:
00959                         virtual void create_radial_func(vector < float >&radial_mask) const ;
00960         };
00961 
00962 
00965         class LowpassRandomPhaseProcessor:public FourierProcessor
00966         {
00967           public:
00968                 string get_name() const
00969                 { return NAME; }
00970                 static Processor *NEW() { return new LowpassRandomPhaseProcessor(); }
00971                 string get_desc() const
00972                 {
00973                         return "Above the cutoff frequency, phases will be completely randomized, but amplitudes will be unchanged. Used for testing for noise bias. If you can reconstruct information that isn't there, then you have noise bias problems.";
00974                 }
00975                                 void process_inplace(EMData * image);
00976                                 void create_radial_func(vector < float >&radial_mask) const;
00977 
00978                 static const string NAME;
00979         };
00980 
00981 
00984         class LowpassAutoBProcessor:public FourierAnlProcessor
00985         {
00986           public:
00987                 string get_name() const
00988                 {
00989                         return NAME;
00990                 }
00991 
00992                 static Processor *NEW()
00993                 {
00994                         return new LowpassAutoBProcessor();
00995                 }
00996 
00997                 string get_desc() const
00998                 {
00999                         return "This processor sharpens a map based on the concept that the power spectrum should be roughly flat over the ~15 A-Nyquist resolution range, then combines this inverse B-factor with the specified low-pass Gaussian filter parameters to produce a single aggregate Gaussian filter.";
01000                 }
01001 
01002                 static const string NAME;
01003 
01004                 virtual TypeDict get_param_types() const
01005                 {
01006                         TypeDict d = FourierAnlProcessor::get_param_types();
01007                         d.put("bfactor", EMObject::FLOAT, "B-factor in terms of e^-(B s^2/4)");
01008                         d.put("noisecutoff", EMObject::FLOAT, "Spatial frequency past which inverse-B will not be applied, default=1/6A");
01009 //                      d.put("adaptnoise", EMObject::INT, "Dual linear fit separating lower resolution signal from higher resolution noise. Noise region not upweighted.");
01010                         d.put("return_radial", EMObject::BOOL, "Return the radial filter function as an attribute (filter_curve)");
01011                         d.put("verbose", EMObject::INT, "Print information about the determined B-factor");
01012                         return d;
01013                 }
01014 
01015           protected:
01016                 virtual void preprocess(EMData * image) {
01017                         if(params.has_key("apix")) {
01018                                 image->set_attr("apix_x", (float)params["apix"]);
01019                                 image->set_attr("apix_y", (float)params["apix"]);
01020                                 image->set_attr("apix_z", (float)params["apix"]);
01021                         }
01022                         float apix=(float)image->get_attr("apix_x");
01023 
01024                         const Dict dict = image->get_attr_dict();
01025                         if (params.has_key("cutoff_abs")) {
01026                                 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
01027                         }
01028                         else if( params.has_key("cutoff_freq") ) {
01029                                 float val =  (float)params["cutoff_freq"] * apix;
01030                                 params["cutoff_abs"] = val;
01031                                 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
01032                         }
01033                         else if( params.has_key("cutoff_pixels") ) {
01034                                 float val = 0.5f*(float)params["cutoff_pixels"] / (float)dict["nx"];
01035                                 params["cutoff_abs"] = val;
01036                                 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
01037                         }
01038                 }
01039 
01040                 void create_radial_func(vector < float >&radial_mask,EMData *image) const;
01041         };
01042 
01045         class HighpassAutoPeakProcessor:public FourierAnlProcessor
01046         {
01047           public:
01048                 string get_name() const
01049                 {
01050                         return NAME;
01051                 }
01052                 static Processor *NEW()
01053                 {
01054                         return new HighpassAutoPeakProcessor();
01055                 }
01056 
01057                 string get_desc() const
01058                 {
01059                         return "Attempts to automatically remove the low resolution peak present in virtually all cryoEM data.";
01060                 }
01061 
01062                 static const string NAME;
01063 
01064           protected:
01065                 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
01066                   virtual void preprocess(EMData * image);
01067                   float highpass;
01068         };
01069 
01074         class LinearRampProcessor:public FourierProcessor
01075         {
01076           public:
01077                 LinearRampProcessor():intercept(0), slope(0)
01078                 {
01079                 }
01080 
01081                 string get_name() const
01082                 {
01083                         return NAME;
01084                 }
01085                 static Processor *NEW()
01086                 {
01087                         return new LinearRampProcessor();
01088                 }
01089 
01090                 string get_desc() const
01091                 {
01092                         return "processor radial function: f(x) = slope * x + intercept;";
01093                 }
01094 
01095                 void set_params(const Dict & new_params)
01096                 {
01097                         params = new_params;
01098                         intercept = params["intercept"];
01099                         slope = params["slope"];
01100                 }
01101 
01102                 TypeDict get_param_types() const
01103                 {
01104                         TypeDict d;
01105                         d.put("intercept", EMObject::FLOAT, "intercept in 'f(x) = slope * x + intercept'");
01106                         d.put("slope", EMObject::FLOAT, "slope in 'f(x) = slope * x + intercept'");
01107                         return d;
01108                 }
01109 
01110                 static const string NAME;
01111 
01112           protected:
01113                 void create_radial_func(vector < float >&radial_mask) const;
01114 
01115           private:
01116                 float intercept;
01117                 float slope;
01118         };
01119 
01123         class LoGFourierProcessor:public FourierProcessor
01124         {
01125           public:
01126                 LoGFourierProcessor():sigma(0)
01127                 {
01128                 }
01129 
01130                 string get_name() const
01131                 {
01132                         return NAME;
01133                 }
01134                 static Processor *NEW()
01135                 {
01136                         return new LoGFourierProcessor();
01137                 }
01138 
01139                 string get_desc() const
01140                 {
01141                         return "processor radial function: f(x) = ((x^2 - s^2)/s^4)e^-(x^2/2s^2)";
01142                 }
01143 
01144                 void set_params(const Dict & new_params)
01145                 {
01146                         params = new_params;
01147                         sigma = params["sigma"];
01148                 }
01149 
01150                 TypeDict get_param_types() const
01151                 {
01152                         TypeDict d;
01153                         d.put("sigma", EMObject::FLOAT, "LoG sigma");
01154                         return d;
01155                 }
01156 
01157                 static const string NAME;
01158 
01159           protected:
01160                 void create_radial_func(vector < float >&radial_mask) const;
01161 
01162           private:
01163                 float sigma;
01164         };
01165 
01170         class DoGFourierProcessor:public FourierProcessor
01171         {
01172           public:
01173                 DoGFourierProcessor():sigma1(0), sigma2(0)
01174                 {
01175                 }
01176 
01177                 string get_name() const
01178                 {
01179                         return NAME;
01180                 }
01181                 static Processor *NEW()
01182                 {
01183                         return new DoGFourierProcessor();
01184                 }
01185 
01186                 string get_desc() const
01187                 {
01188                         return "processor radial function: f(x) = 1/sqrt(2*pi)*[1/sigma1*exp-(x^2/2*sigma1^2) - 1/sigma2*exp-(x^2/2*sigma2^2)]";
01189                 }
01190 
01191                 void set_params(const Dict & new_params)
01192                 {
01193                         params = new_params;
01194                         sigma1 = params["sigma1"];
01195                         sigma2 = params["sigma2"];
01196                 }
01197 
01198                 TypeDict get_param_types() const
01199                 {
01200                         TypeDict d;
01201                         d.put("sigma1", EMObject::FLOAT, "DoG sigma1");
01202                         d.put("sigma2", EMObject::FLOAT, "DoG sigma2");
01203                         return d;
01204                 }
01205 
01206                 static const string NAME;
01207 
01208           protected:
01209                 void create_radial_func(vector < float >&radial_mask) const;
01210 
01211           private:
01212                 float sigma1;
01213                 float sigma2;
01214         };
01215 
01218         class RealPixelProcessor:public Processor
01219         {
01220           public:
01221                 RealPixelProcessor():value(0), maxval(1), mean(0), sigma(0)
01222                 {
01223                 }
01224                 void process_inplace(EMData * image);
01225 
01226                 virtual void set_params(const Dict & new_params)
01227                 {
01228                         params = new_params;
01229                         if (params.size() == 1) {
01230                                 vector < EMObject > dict_values = params.values();
01231                                 value = dict_values[0];
01232                         }
01233                 }
01234 
01235                 static string get_group_desc()
01236                 {
01237                         return "The base class for real space processor working on individual pixels. The processor won't consider the pixel's coordinates and neighbors.";
01238                 }
01239 
01240           protected:
01241                 virtual void process_pixel(float *x) const = 0;
01242                 virtual void calc_locals(EMData *)
01243                 {
01244                 }
01245                 virtual void normalize(EMData *) const
01246                 {
01247                 }
01248 
01249                 float value;
01250                 float maxval;
01251                 float mean;
01252                 float sigma;
01253         };
01254 
01257         class AbsoluateValueProcessor:public RealPixelProcessor
01258         {
01259           public:
01260                 string get_name() const
01261                 {
01262                         return NAME;
01263                 }
01264                 static Processor *NEW()
01265                 {
01266                         return new AbsoluateValueProcessor();
01267                 }
01268 
01269                 static const string NAME;
01270 
01271           protected:
01272                 void process_pixel(float *x) const
01273                 {
01274                         *x = fabs(*x);
01275                 }
01276 
01277                 string get_desc() const
01278                 {
01279                         return "f(x) = |x|";
01280                 }
01281         };
01282 
01285         class FloorValueProcessor:public RealPixelProcessor
01286         {
01287           public:
01288                 string get_name() const
01289                 {
01290                         return NAME;
01291                 }
01292                 static Processor *NEW()
01293                 {
01294                         return new FloorValueProcessor();
01295                 }
01296 
01297                 static const string NAME;
01298 
01299           protected:
01300                 void process_pixel(float *x) const
01301                 {
01302                         *x = floor(*x);
01303                 }
01304 
01305                 string get_desc() const
01306                 {
01307                         return "f(x) = floor(x)";
01308                 }
01309         };
01310 
01311 
01314         class BooleanProcessor:public RealPixelProcessor
01315         {
01316           public:
01317                 string get_name() const
01318                 {
01319                         return NAME;
01320                 }
01321                 static Processor *NEW()
01322                 {
01323                         return new BooleanProcessor();
01324                 }
01325 
01326                 string get_desc() const
01327                 {
01328                         return "f(x) = 0 if x = 0; f(x) = 1 if x != 0;";
01329                 }
01330 
01331                 static const string NAME;
01332 
01333           protected:
01334                 void process_pixel(float *x) const
01335                 {
01336                         if (*x != 0)
01337                         {
01338                                 *x = 1.0;
01339                         }
01340                 }
01341         };
01342 
01346         class RecipCarefullyProcessor:public RealPixelProcessor
01347         {
01348                 public:
01349                         string get_name() const
01350                         {
01351                                 return NAME;
01352                         }
01353                         static Processor *NEW()
01354                         {
01355                                 return new RecipCarefullyProcessor();
01356                         }
01357 
01358                         void set_params(const Dict & new_params)
01359                         {
01360                                 params = new_params;
01361                                 zero_to = params.set_default("zero_to",0.0f);
01362                         }
01363 
01364                         TypeDict get_param_types() const
01365                         {
01366                                 TypeDict d;
01367                                 d.put("zero_to", EMObject::FLOAT, "Inverted zero values are set to this value, default is 0.");
01368                                 return d;
01369                         }
01370 
01371                         string get_desc() const
01372                         {
01373                                 return "if f(x) != 0: f(x) = 1/f(x) else: f(x) = zero_to";
01374                         }
01375 
01376                         static const string NAME;
01377 
01378                 protected:
01379                         void process_pixel(float *x) const
01380                         {
01381                                 if (*x == 0.0) *x = zero_to;
01382                                 else *x = 1.0f/(*x);
01383                         }
01384                 private:
01385                         float zero_to;
01386         };
01387 
01391         class ValuePowProcessor:public RealPixelProcessor
01392         {
01393           public:
01394                 string get_name() const
01395                 {
01396                         return NAME;
01397                 }
01398                 static Processor *NEW()
01399                 {
01400                         return new ValuePowProcessor();
01401                 }
01402 
01403                 void set_params(const Dict & new_params)
01404                 {
01405                         params = new_params;
01406                         pwr = params["pow"];
01407                 }
01408 
01409                 TypeDict get_param_types() const
01410                 {
01411                         TypeDict d;
01412                         d.put("pow", EMObject::FLOAT, "Each pixel is raised to this power");
01413                         return d;
01414                 }
01415 
01416                 string get_desc() const
01417                 {
01418                         return "f(x) = x ^ pow;";
01419                 }
01420 
01421                 static const string NAME;
01422 
01423           protected:
01424                 void process_pixel(float *x) const
01425                 {
01426                         if (*x<0 && pwr!=(int)pwr) *x=0;
01427                         else (*x) = pow(*x,pwr);
01428                 }
01429           private:
01430                 float pwr;
01431         };
01432 
01435         class ValueSquaredProcessor:public RealPixelProcessor
01436         {
01437           public:
01438                 string get_name() const
01439                 {
01440                         return NAME;
01441                 }
01442                 static Processor *NEW()
01443                 {
01444                         return new ValueSquaredProcessor();
01445                 }
01446 
01447 
01448                 string get_desc() const
01449                 {
01450                         return "f(x) = x * x;";
01451                 }
01452 
01453                 static const string NAME;
01454 
01455           protected:
01456                 void process_pixel(float *x) const
01457                 {
01458                         (*x) *= (*x);
01459                 }
01460         };
01461 
01464         class ValueSqrtProcessor:public RealPixelProcessor
01465         {
01466           public:
01467                 string get_name() const
01468                 {
01469                         return NAME;
01470                 }
01471                 static Processor *NEW()
01472                 {
01473                         return new ValueSqrtProcessor();
01474                 }
01475 
01476                 string get_desc() const
01477                 {
01478                         return "f(x) = sqrt(x)";
01479                 }
01480 
01481                 static const string NAME;
01482 
01483           protected:
01484                 void process_pixel(float *x) const
01485                 {
01486                         *x = sqrt(*x);
01487                 }
01488         };
01489 
01493         class ToZeroProcessor:public RealPixelProcessor
01494         {
01495                 public:
01496                         string get_name() const
01497                         {
01498                                 return NAME;
01499                         }
01500                         static Processor *NEW()
01501                         {
01502                                 return new ToZeroProcessor();
01503                         }
01504                         TypeDict get_param_types() const
01505                         {
01506                                 TypeDict d;
01507                                 d.put("minval", EMObject::FLOAT, "Everything below this value is set to zero");
01508                                 return d;
01509                         }
01510 
01511                         string get_desc() const
01512                         {
01513                                 return "f(x) = x if x >= minval; f(x) = 0 if x < minval.";
01514                         }
01515 
01516                         static const string NAME;
01517 
01518                 protected:
01519                         inline void process_pixel(float *x) const
01520                         {
01521                                 if (*x < value) {
01522                                         *x = 0;
01523                                 }
01524                         }
01525         };
01526 
01530         class AboveToZeroProcessor:public RealPixelProcessor
01531         {
01532         public:
01533                 string get_name() const
01534                 {
01535                         return NAME;
01536                 }
01537                 static Processor *NEW()
01538                 {
01539                         return new AboveToZeroProcessor();
01540                 }
01541                 TypeDict get_param_types() const
01542                 {
01543                         TypeDict d;
01544                         d.put("maxval", EMObject::FLOAT, "Everything above this value is set to zero");
01545                         return d;
01546                 }
01547 
01548                 string get_desc() const
01549                 {
01550                         return "f(x) = x if x <= maxval; f(x) = 0 if x > maxval.";
01551                 }
01552 
01553                 static const string NAME;
01554 
01555         protected:
01556                 inline void process_pixel(float *x) const
01557                 {
01558                         if (*x > value) {
01559                                 *x = 0;
01560                         }
01561                 }
01562         };
01563 
01568         class AddShapeProcessor:public Processor
01569         {
01570                 public:
01571                         string get_name() const
01572                         {
01573                                 return NAME;
01574                         }
01575 
01576                         static Processor *NEW()
01577                         {
01578                                 return new AddShapeProcessor();
01579                         }
01580 
01581                         void process_inplace(EMData* image);
01582 
01583                         TypeDict get_param_types() const
01584                         {
01585                                 TypeDict d;
01586                                 d.put("shape", EMObject::STRING, "Name of the shape to add (");
01587                                 d.put("x", EMObject::FLOAT, "X coordinate of object center");
01588                                 d.put("y", EMObject::FLOAT, "Y coordinate of object center");
01589                                 d.put("z", EMObject::FLOAT, "Z coordinate of object center");
01590                                 d.put("size1", EMObject::FLOAT, "Size of the object. Meaning varies by shape.");
01591                                 d.put("size2", EMObject::FLOAT, "2nd axis size of the object. Meaning varies by shape.");
01592                                 d.put("size3", EMObject::FLOAT, "3rd axis size of the object. Meaning varies by shape.");
01593                                 d.put("val1", EMObject::FLOAT, "First pixel value. Meaning varies by shape.");
01594                                 d.put("val2", EMObject::FLOAT, "2nd pixel value. Meaning varies with shape");
01595 
01596                                 return d;
01597                         }
01598 
01599                         string get_desc() const
01600                         {
01601                                 return "Adds a specified shape to a volume.";
01602                         }
01603 
01604                         static const string NAME;
01605         };
01606 
01607 
01613         class Rotate180Processor:public Processor
01614         {
01615                 public:
01616                         string get_name() const
01617                         {
01618                                 return NAME;
01619                         }
01620                         static Processor *NEW()
01621                         {
01622                                 return new Rotate180Processor();
01623                         }
01624 
01628                         void process_inplace(EMData* image);
01629 
01630                         string get_desc() const
01631                         {
01632                                 return "The 2D image is rotated by 180 degree by carefully swapping image pixel values. No explicit matrix multiplication is performed. If image dimensions are even will change pixels along x=0 and y=0. Works for all combinations of even and oddness.";
01633                         }
01634 
01635                         static const string NAME;
01636         };
01637 
01644         class TransformProcessor:public Processor
01645         {
01646                 public:
01647                         virtual string get_name() const
01648                         {
01649                                 return NAME;
01650                         }
01651                         static Processor *NEW()
01652                         {
01653                                 return new TransformProcessor();
01654                         }
01655 
01660                         virtual void process_inplace(EMData* image);
01661 
01666                         virtual EMData* process(const EMData* const image);
01667 
01668                         virtual TypeDict get_param_types() const
01669                         {
01670                                 TypeDict d;
01671                                 d.put("transform", EMObject::TRANSFORM, "The Transform object that will be applied to the image" );
01672                                 return d;
01673                         }
01674 
01675                         virtual string get_desc() const
01676                         {
01677                                 return "The image is transformed using Transform parameter.";
01678                         }
01679 
01680                         static const string NAME;
01681 
01682                         float* transform(const EMData* const image, const Transform& t) const;
01683                 private:
01684                         // This function became redundant if favor of EMData::scale_pixel
01685                         //void update_emdata_attributes(EMData* const image, const Dict& attr_dict, const float& scale) const;
01686 
01687 
01688                         void assert_valid_aspect(const EMData* const image) const;
01689         };
01690 
01698         class IntTranslateProcessor:public Processor
01699         {
01700                 public:
01701                         virtual string get_name() const
01702                         {
01703                                 return NAME;
01704                         }
01705 
01706                         static Processor *NEW()
01707                         {
01708                                 return new IntTranslateProcessor();
01709                         }
01710 
01715                         virtual void process_inplace(EMData* image);
01716 
01721                         virtual EMData* process(const EMData* const image);
01722 
01723                         virtual TypeDict get_param_types() const
01724                         {
01725                                 TypeDict d;
01726                                 d.put("trans", EMObject::INTARRAY, "The displacement array, can be length 1-3" );
01727                                 return d;
01728                         }
01729 
01730                         virtual string get_desc() const
01731                         {
01732                                 return "The image is translated an integer amount";
01733                         }
01734 
01735                         static const string NAME;
01736 
01737                 private:
01741                         void assert_valid_aspect(const vector<int>& translation, const EMData* const image) const;
01742 
01748                         Region get_clip_region(vector<int>& translation, const EMData* const image) const;
01749         };
01750 
01756         class ApplySymProcessor:public Processor
01757         {
01758                 public:
01759                         virtual string get_name() const
01760                         {
01761                                 return NAME;
01762                         }
01763 
01764                         static Processor *NEW()
01765                         {
01766                                 return new ApplySymProcessor();
01767                         }
01768 
01769                         virtual void process_inplace(EMData* image);
01770 
01771                         virtual EMData* process(const EMData* const image);
01772 
01773                         virtual TypeDict get_param_types() const
01774                         {
01775                                 TypeDict d;
01776                                 d.put("sym", EMObject::STRING, "The symmetry under which to do the alignment, Default=c1" );
01777                                 return d;
01778                         }
01779 
01780                         virtual string get_desc() const
01781                         {
01782                                 return "Symmetry is imposed on a 2-D image (Cn only) or 3-D volume";
01783                         }
01784 
01785                         static const string NAME;
01786 
01787         };
01788 
01795         class ScaleTransformProcessor:public Processor
01796         {
01797                 public:
01798                         virtual string get_name() const
01799                         {
01800                                 return NAME;
01801                         }
01802                         static Processor *NEW()
01803                         {
01804                                 return new ScaleTransformProcessor();
01805                         }
01810                         virtual void process_inplace(EMData* image);
01811 
01816                         virtual EMData* process(const EMData* const image);
01817 
01818                         virtual TypeDict get_param_types() const
01819                         {
01820                                 TypeDict d;
01821                                 d.put("scale", EMObject::FLOAT, "The amount by which to scale" );
01822                                 d.put("clip", EMObject::INT, "The length of each output dimension. Non sophisticated, output dimensions can't be different" );
01825                                 return d;
01826                         }
01827 
01828                         virtual string get_desc() const
01829                         {
01830                                 return "The image is scaled with the clip variable in mind, being sure to preserve as much pixel information as possible.";
01831                         }
01832 
01833                         static const string NAME;
01834         };
01835 
01842         class ClampingProcessor :public Processor
01843         {
01844           public:
01845                 ClampingProcessor() : default_max(1.0), default_min(0.0) {}
01846 
01847                 string get_name() const
01848                 {
01849                         return NAME;
01850                 }
01851                 static Processor *NEW()
01852                 {
01853                         return new ClampingProcessor();
01854                 }
01855 
01856                 void process_inplace(EMData *image);
01857 
01858                 TypeDict get_param_types() const
01859                 {
01860                         TypeDict d;
01861                         d.put("minval", EMObject::FLOAT, "The pixel values that bounds the smallest pixel value in the output image" );
01862                         d.put("maxval", EMObject::FLOAT, "The pixel values that bounds the largest pixel value in the output image" );
01863                         d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01864                         d.put("tozero", EMObject::BOOL, "Replace outlying pixels values with zero" );
01865                         return d;
01866                 }
01867 
01868                 string get_desc() const
01869                 {
01870                         return "This function clamps the min and max vals in the image at minval and maxval, respectively. In a sense this a bi-truncation of the data.";
01871                 }
01872 
01873                 static const string NAME;
01874 
01875           protected:
01876                 float default_max, default_min;
01877         };
01878 
01884         class NSigmaClampingProcessor : public ClampingProcessor
01885         {
01886                 public:
01887                         NSigmaClampingProcessor() : default_sigma(2.0) {}
01888 
01889                         string get_name() const
01890                         {
01891                                 return NAME;
01892                         }
01893 
01894                         static Processor *NEW()
01895                         {
01896                                 return new NSigmaClampingProcessor();
01897                         }
01898 
01899                         TypeDict get_param_types() const
01900                         {
01901                                 TypeDict d;
01902                                 d.put("nsigma", EMObject::FLOAT, "The number (n) of sigmas to clamp min and max vals at, so that the clamped boundaries are mean-n*sigma and mean+n*sigma" );
01903                                 d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01904                                 d.put("tozero", EMObject::BOOL, "Replace outlying pixels values with zero" );
01905                                 return d;
01906                         }
01907 
01908                         void process_inplace(EMData *image);
01909 
01910                         string get_desc() const
01911                         {
01912                                 return "This function clamps the min and max vals in the image at minval and maxval at mean-n*sigma and mean+n*sigma, respectively. The parameter specified by the user is n, the default value of n is 2.";
01913                         }
01914 
01915                         static const string NAME;
01916 
01917                 protected:
01918                         float default_sigma;
01919         };
01920 
01924         class ToMinvalProcessor:public Processor
01925         {
01926           public:
01927                 string get_name() const
01928                 {
01929                         return NAME;
01930                 }
01931                 static Processor *NEW()
01932                 {
01933                         return new ToMinvalProcessor();
01934                 }
01935 
01936                 void process_inplace(EMData *image);
01937 
01938                 TypeDict get_param_types() const
01939                 {
01940                         TypeDict d;
01941                         d.put("minval", EMObject::FLOAT, "Everything below this value is set to this value");
01942                         d.put("newval", EMObject::FLOAT, "If set, values below minval will be set to newval instead of minval ");
01943                         return d;
01944                 }
01945 
01946                 string get_desc() const
01947                 {
01948                         return "f(x) = x if x >= minval; f(x) = minval|newval if x < minval.";
01949                 }
01950 
01951                 static const string NAME;
01952 
01953         protected:
01954 
01955         };
01956 
01957 
01958 
01962         class CutToZeroProcessor:public RealPixelProcessor
01963         {
01964           public:
01965                 string get_name() const
01966                 {
01967                         return NAME;
01968                 }
01969                 static Processor *NEW()
01970                 {
01971                         return new CutToZeroProcessor();
01972                 }
01973                 TypeDict get_param_types() const
01974                 {
01975                         TypeDict d;
01976                         d.put("minval", EMObject::FLOAT, "the value that will be set to zero - all values below will also be set to zero. Values above get minval subtracted from them" );
01977                         return d;
01978                 }
01979 
01980                 string get_desc() const
01981                 {
01982                         return "f(x) = x-minval if x >= minval; f(x) = 0 if x < minval.";
01983                 }
01984 
01985                 static const string NAME;
01986 
01987           protected:
01988                 void process_pixel(float *x) const
01989                 {
01990                         *x = *x - value;
01991                         if (*x < 0) {
01992                                 *x = 0;
01993                         }
01994                 }
01995         };
01996 
02000         class BinarizeProcessor:public RealPixelProcessor
02001         {
02002           public:
02003                 string get_name() const
02004                 {
02005                         return NAME;
02006                 }
02007                 static Processor *NEW()
02008                 {
02009                         return new BinarizeProcessor();
02010                 }
02011                 TypeDict get_param_types() const
02012                 {
02013                         TypeDict d;
02014                         d.put("value", EMObject::FLOAT, "The thresholding value. If a pixel value is equal to or above the threshold it is set to 1. If it is below it is set to 0" );
02015                         return d;
02016                 }
02017 
02018                 string get_desc() const
02019                 {
02020                         return "f(x) = 0 if x < value; f(x) = 1 if x >= value.";
02021                 }
02022 
02023                 static const string NAME;
02024 
02025           protected:
02026                 void process_pixel(float *x) const
02027                 {
02028                         if (*x < value)
02029                         {
02030                                 *x = 0;
02031                         }
02032                         else
02033                         {
02034                                 *x = 1;
02035                         }
02036                 }
02037         };
02038 
02046         class BinarizeFourierProcessor:public Processor
02047                 {
02048                   public:
02049                         virtual string get_name() const
02050                         {
02051                                 return NAME;
02052                         }
02053                         static Processor *NEW()
02054                         {
02055                                 return new BinarizeFourierProcessor();
02056                         }
02057 
02062                         virtual void process_inplace(EMData* image);
02063 
02064                         virtual TypeDict get_param_types() const
02065                         {
02066                                 TypeDict d;
02067                                 d.put("value", EMObject::FLOAT, "The Fourier amplitude threshold cutoff" );
02068                                 return d;
02069                         }
02070 
02071                         virtual string get_desc() const
02072                         {
02073                                 return "f(k) = 0 + 0i if ||f(k)|| < value; f(k) = a + bi if ||f(k)|| >= value.";
02074                         }
02075 
02076                         static const string NAME;
02077                 };
02078 
02083         class CollapseProcessor:public RealPixelProcessor
02084         {
02085           public:
02086                 string get_name() const
02087                 {
02088                         return NAME;
02089                 }
02090                 static Processor *NEW()
02091                 {
02092                         return new CollapseProcessor();
02093                 }
02094 
02095                 void set_params(const Dict & new_params)
02096                 {
02097                         params = new_params;
02098                         range = params["range"];
02099                         value = params["value"];
02100                 }
02101 
02102                 TypeDict get_param_types() const
02103                 {
02104                         TypeDict d;
02105                         d.put("range", EMObject::FLOAT, "The range about 'value' which will be collapsed to 'value'");
02106                         d.put("value", EMObject::FLOAT, "The pixel value where the focus of the collapse operation is");
02107                         return d;
02108                 }
02109 
02110                 string get_desc() const
02111                 {
02112                         return "f(x): if v-r<x<v+r -> v; if x>v+r -> x-r; if x<v-r -> x+r";
02113                 }
02114 
02115                 static const string NAME;
02116 
02117           protected:
02118                 void process_pixel(float *x) const
02119                 {
02120                         if (*x>value+range) *x-=range;
02121                         else if (*x<value-range) *x+=range;
02122                         else *x=value;
02123                 }
02124                 float range;
02125         };
02126 
02131         class LinearXformProcessor:public RealPixelProcessor
02132         {
02133           public:
02134                 LinearXformProcessor():shift(0), scale(0)
02135                 {
02136                 }
02137 
02138                 string get_name() const
02139                 {
02140                         return NAME;
02141                 }
02142                 static Processor *NEW()
02143                 {
02144                         return new LinearXformProcessor();
02145                 }
02146 
02147                 void set_params(const Dict & new_params)
02148                 {
02149                         params = new_params;
02150                         shift = params.get("shift");
02151                         scale = params.get("scale");
02152                 }
02153 
02154                 TypeDict get_param_types() const
02155                 {
02156                         TypeDict d;
02157                         d.put("shift", EMObject::FLOAT, "The amount to shift pixel values by before scaling");
02158                         d.put("scale", EMObject::FLOAT, "The scaling factor to be applied to pixel values");
02159                         return d;
02160                 }
02161 
02162                 string get_desc() const
02163                 {
02164                         return "linear transform processor: f(x) = x * scale + shift. This is equivalent to a regular contrast stretching operation";
02165                 }
02166 
02167                 static const string NAME;
02168 
02169           protected:
02170                 void process_pixel(float *x) const
02171                 {
02172                         *x = (*x) * scale + shift;
02173                 }
02174 
02175           private:
02176                 float shift;
02177                 float scale;
02178         };
02179 
02184         class ExpProcessor:public RealPixelProcessor
02185         {
02186           public:
02187                 ExpProcessor():low(0), high(0)
02188                 {
02189                 }
02190 
02191                 string get_name() const
02192                 {
02193                         return NAME;
02194                 }
02195 
02196                 static Processor *NEW()
02197                 {
02198                         return new ExpProcessor();
02199                 }
02200 
02201                 void set_params(const Dict & new_params)
02202                 {
02203                         params = new_params;
02204                         low = params.get("low");
02205                         high = params.get("high");
02206                 }
02207 
02208                 TypeDict get_param_types() const
02209                 {
02210                         TypeDict d;
02211                         d.put("low", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
02212                         d.put("high", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
02213                         return d;
02214                 }
02215 
02216                 string get_desc() const
02217                 {
02218                         return "f(x) = exp( x / low - high)";
02219                 }
02220 
02221                 static const string NAME;
02222 
02223           protected:
02227                 void process_pixel(float *x) const
02228                 {
02229                         float v = *x / low - high;
02230                         if (v > 40) {
02231                                 v = 40;
02232                         }
02233                         *x = exp(v);
02234                 }
02235 
02236           private:
02237                 float low;
02238                 float high;
02239         };
02240 
02244         class FiniteProcessor:public RealPixelProcessor
02245         {
02246                 public:
02247                         FiniteProcessor():to(0)
02248                         {
02249                         }
02250 
02251                         string get_name() const
02252                         {
02253                                 return NAME;
02254                         }
02255 
02256                         static Processor *NEW()
02257                         {
02258                                 return new FiniteProcessor();
02259                         }
02260 
02261                         void set_params(const Dict & new_params)
02262                         {
02263                                 if (new_params.has_key("to") )
02264                                         to = params["to"];
02265                         }
02266 
02267                         TypeDict get_param_types() const
02268                         {
02269                                 TypeDict d;
02270                                 d.put("to", EMObject::FLOAT, "Pixels which are not finite will be set to this value");
02271                                 return d;
02272                         }
02273 
02274                         string get_desc() const
02275                         {
02276                                 return "f(x) = f(x) if f(x) is finite | to if f(x) is not finite";
02277                         }
02278 
02279                         static const string NAME;
02280 
02281                 protected:
02285                         void process_pixel(float *x) const;
02286                 private:
02287                         float to;
02288         };
02289 
02294         class RangeThresholdProcessor:public RealPixelProcessor
02295         {
02296           public:
02297                 RangeThresholdProcessor():low(0), high(0)
02298                 {
02299                 }
02300 
02301                 string get_name() const
02302                 {
02303                         return NAME;
02304                 }
02305                 static Processor *NEW()
02306                 {
02307                         return new RangeThresholdProcessor();
02308                 }
02309 
02310                 void set_params(const Dict & new_params)
02311                 {
02312                         params = new_params;
02313                         low = params.get("low");
02314                         high = params.get("high");
02315                 }
02316 
02317                 TypeDict get_param_types() const
02318                 {
02319                         TypeDict d;
02320                         d.put("low", EMObject::FLOAT, "The lower limit of the range that will be set to 1");
02321                         d.put("high", EMObject::FLOAT, "The upper limit of the range that will be set to 1");
02322                         return d;
02323                 }
02324 
02325                 string get_desc() const
02326                 {
02327                         return "Range thresholding. A range of values is set to 1, all else is set to 0. f(x) = 1 if (low <= x <= high); else f(x) = 0";
02328                 }
02329 
02330                 static const string NAME;
02331 
02332           protected:
02333                 void process_pixel(float *x) const
02334                 {
02335                         if (*x >= low && *x <= high) {
02336                                 *x = 1;
02337                         }
02338                         else {
02339                                 *x = 0;
02340                         }
02341                 }
02342           private:
02343                 float low;
02344                 float high;
02345 
02346         };
02347 
02352         class SigmaProcessor:public RealPixelProcessor
02353         {
02354           public:
02355                 string get_name() const
02356                 {
02357                         return NAME;
02358                 }
02359                 static Processor *NEW()
02360                 {
02361                         return new SigmaProcessor();
02362                 }
02363 
02364                 void set_params(const Dict & new_params)
02365                 {
02366                         params = new_params;
02367                         value1 = params.get("value1");
02368                         value2 = params.get("value2");
02369                 }
02370 
02371                 TypeDict get_param_types() const
02372                 {
02373                         TypeDict d;
02374                         d.put("value1", EMObject::FLOAT, "A number reflecting total standard deviations in the right direction");
02375                         d.put("value2", EMObject::FLOAT, "A number reflecting total standard deviations in the left direction");
02376                         return d;
02377                 }
02378 
02379                 string get_desc() const
02380                 {
02381                         return "f(x) = mean if x<(mean-v2*sigma) or x>(mean+v1*sigma); else f(x) = x;";
02382                 }
02383 
02384                 static const string NAME;
02385 
02386           protected:
02387                 void process_pixel(float *x) const
02388                 {
02389                         if (*x < (mean - value2 * sigma) || *x > (mean + value1 * sigma))
02390                         {
02391                                 *x = mean;
02392                         }
02393                 }
02394 
02395           private:
02396                 float value1;
02397                 float value2;
02398         };
02399 
02402         class LogProcessor:public RealPixelProcessor
02403         {
02404           public:
02405                 string get_name() const
02406                 {
02407                         return NAME;
02408                 }
02409                 static Processor *NEW()
02410                 {
02411                         return new LogProcessor();
02412                 }
02413 
02414                 string get_desc() const
02415                 {
02416                         return "f(x) = log10(x) if x > 0; else f(x) = 0;";
02417                 }
02418 
02419                 static const string NAME;
02420 
02421           protected:
02422                 void process_pixel(float *x) const
02423                 {
02424                         if (*x > 0)
02425                         {
02426                                 *x = log10(*x);
02427                         }
02428                         else
02429                         {
02430                                 *x = 0;
02431                         }
02432                 }
02433         };
02434 
02437         class CoordinateProcessor:public Processor
02438         {
02439           public:
02440                 CoordinateProcessor():nx(0), ny(0), nz(0), mean(0), sigma(0), maxval(0), is_complex(false)
02441                 {
02442                 }
02443                 void process_inplace(EMData * image);
02444 
02445                 static string get_group_desc()
02446                 {
02447                         return "CoordinateProcessor applies processing based on a pixel's value and it coordinates. This is the base class. Specific coordinate processor should implement process_pixel().";
02448                 }
02449 
02450           protected:
02451                 virtual void process_pixel(float *pixel, int xi, int yi, int zi) const = 0;
02452                 virtual void calc_locals(EMData *)
02453                 {
02454                 }
02455                 virtual bool is_valid() const
02456                 {
02457                         return true;
02458                 }
02459 
02460                 int nx;
02461                 int ny;
02462                 int nz;
02463                 float mean;
02464                 float sigma;
02465                 float maxval;
02466 
02467                 bool is_complex;
02468         };
02469 
02477         class CircularMaskProcessor:public CoordinateProcessor
02478         {
02479           public:
02480                 CircularMaskProcessor():inner_radius(0), outer_radius(0), inner_radius_square(0),
02481                         outer_radius_square(0), dx(0), dy(0), dz(0), xc(0), yc(0), zc(0)
02482                 {
02483                 }
02484 
02485                 void set_params(const Dict & new_params)
02486                 {
02487                         params = new_params;
02488 
02489                         if (params.has_key("inner_radius")) {
02490                                 inner_radius = params["inner_radius"];
02491                                 inner_radius_square = inner_radius * inner_radius;
02492                         }
02493                         else {
02494                                 inner_radius = -1;
02495                                 inner_radius_square = -1;
02496                         }
02497 
02498                         if (params.has_key("outer_radius")) {
02499                                 outer_radius = params["outer_radius"];
02500                                 outer_radius_square = outer_radius * outer_radius;
02501                         }
02502                         else {
02503                                 outer_radius = INT_MAX;
02504                                 outer_radius_square = INT_MAX;
02505                         }
02506 
02507                         if (params.has_key("dx")) dx = params["dx"];
02508                         if (params.has_key("dy")) dy = params["dy"];
02509                         if (params.has_key("dz")) dz = params["dz"];
02510                 }
02511 
02512                 string get_desc() const
02513                 {
02514                         return "CircularMaskProcessor applies a circular mask to the data.This is the base class for specific circular mask processors.Its subclass must implement process_dist_pixel().";
02515                 }
02516 
02517                 TypeDict get_param_types() const
02518                 {
02519                         TypeDict d;
02520 
02521                         d.put("inner_radius", EMObject::INT, "inner mask radius. optional");
02522                         d.put("outer_radius", EMObject::INT, "outer mask radius. Negative value -> box radius + outer_radius +1");
02523 
02524                         d.put("dx", EMObject::FLOAT,
02525                                   "Modify mask center by dx relative to the default center nx/2");
02526                         d.put("dy", EMObject::FLOAT,
02527                                   "Modify mask center by dy relative to the default center ny/2");
02528                         d.put("dz", EMObject::FLOAT,
02529                                   "Modify mask center by dz relative to the default center nz/2");
02530 
02531                         return d;
02532                 }
02533           protected:
02534                 void calc_locals(EMData * image);
02535 
02536                 bool is_valid() const
02537                 {
02538                         return (!is_complex);
02539                 }
02540 
02541                 void process_pixel(float *pixel, int xi, int yi, int zi) const
02542                 {
02543                         float dist = (xi - xc) * (xi - xc) + (yi - yc) * (yi - yc) + (zi - zc) * (zi - zc);
02544                         process_dist_pixel(pixel, dist);
02545                 }
02546 
02547                 virtual void process_dist_pixel(float *pixel, float dist) const = 0;            // note that this function gets the distance SQUARED !
02548 
02549                 int inner_radius;
02550                 int outer_radius;
02551                 int inner_radius_square;
02552                 int outer_radius_square;
02553                 float dx, dy, dz;
02554                 float xc, yc, zc;
02555         };
02556 
02560         class MaskSharpProcessor:public CircularMaskProcessor
02561         {
02562           public:
02563                 MaskSharpProcessor():value(0)
02564                 {
02565                 }
02566 
02567                 string get_name() const
02568                 {
02569                         return NAME;
02570                 }
02571                 static Processor *NEW()
02572                 {
02573                         return new MaskSharpProcessor();
02574                 }
02575 
02576                 void set_params(const Dict & new_params)
02577                 {
02578                         CircularMaskProcessor::set_params(new_params);
02579                         value = params.set_default("value",0.0f);
02580                 }
02581 
02582                 TypeDict get_param_types() const
02583                 {
02584                         TypeDict d = CircularMaskProcessor::get_param_types();
02585                         d.put("value", EMObject::FLOAT, "step cutoff to this value. Default is 0.");
02586                         return d;
02587                 }
02588 
02589                 string get_desc() const
02590                 {
02591                         return "step cutoff to a user-given value in both inner and outer circles.";
02592                 }
02593 
02594                 static const string NAME;
02595 
02596           protected:
02597                 void process_dist_pixel(float *pixel, float dist) const
02598                 {
02599                         if (dist >= outer_radius_square || dist < inner_radius_square)
02600                         {
02601                                 *pixel = value;
02602                         }
02603                 }
02604 
02605                 float value;
02606         };
02607 
02611         class MaskSoftProcessor:public CircularMaskProcessor
02612         {
02613           public:
02614                 MaskSoftProcessor():value(0)
02615                 {
02616                 }
02617 
02618                 string get_name() const
02619                 {
02620                         return NAME;
02621                 }
02622                 static Processor *NEW()
02623                 {
02624                         return new MaskSoftProcessor();
02625                 }
02626 
02627                 void set_params(const Dict & new_params)
02628                 {
02629                         CircularMaskProcessor::set_params(new_params);
02630                         value = params.set_default("value",0.0f);
02631                         width = params.set_default("width",4.0f);
02632                 }
02633 
02634                 TypeDict get_param_types() const
02635                 {
02636                         TypeDict d = CircularMaskProcessor::get_param_types();
02637                         d.put("value", EMObject::FLOAT, "cutoff to this value. default=0");
02638                         d.put("width", EMObject::FLOAT, "1/e width of Gaussian falloff (both inner and outer) in pixels. default=4");
02639                         return d;
02640                 }
02641 
02642                 string get_desc() const
02643                 {
02644                         return "Outer (optionally also inner) mask to a user-provided value with a soft Gaussian edge.";
02645                 }
02646 
02647                 static const string NAME;
02648 
02649           protected:
02650                 void process_dist_pixel(float *pixel, float dist) const
02651                 {
02652                         if (dist>=inner_radius_square && dist<=outer_radius_square) return;
02653 
02654                         if (dist<inner_radius_square) *pixel=value+(*pixel-value)*exp(-pow((inner_radius-sqrt(dist))/width,2.0f));
02655                         else *pixel=value+(*pixel-value)*exp(-pow((sqrt(dist)-outer_radius)/width,2.0f));
02656                 }
02657 
02658                 float value,width;
02659         };
02660 
02664         class MaskEdgeMeanProcessor:public CircularMaskProcessor
02665         {                                                       // 6
02666           public:
02667                 string get_name() const
02668                 {
02669                         return NAME;
02670                 }
02671                 static Processor *NEW()
02672                 {
02673                         return new MaskEdgeMeanProcessor();
02674                 }
02675 
02676                 void set_params(const Dict & new_params)
02677                 {
02678                         CircularMaskProcessor::set_params(new_params);
02679                         ring_width = params["ring_width"];
02680                         if (ring_width == 0) {
02681                                 ring_width = 1;
02682                         }
02683                 }
02684 
02685                 TypeDict get_param_types() const
02686                 {
02687                         TypeDict d = CircularMaskProcessor::get_param_types();
02688                         d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02689                         return d;
02690                 }
02691 
02692                 string get_desc() const
02693                 {
02694                         return "A step cutoff to the the mean value in a ring centered on the outer radius";
02695                 }
02696 
02697                 static const string NAME;
02698 
02699           protected:
02700                 void calc_locals(EMData * image);
02701 
02702 
02703                 void process_dist_pixel(float *pixel, float dist) const
02704                 {
02705                         if (dist >= outer_radius_square || dist < inner_radius_square){
02706                                 *pixel = ring_avg;
02707                         }
02708                 }
02709 
02710           private:
02711                 int ring_width;
02712                 float ring_avg;
02713         };
02714 
02717         class MaskNoiseProcessor:public CircularMaskProcessor
02718         {
02719           public:
02720                 string get_name() const
02721                 {
02722                         return NAME;
02723                 }
02724                 static Processor *NEW()
02725                 {
02726                         return new MaskNoiseProcessor();
02727                 }
02728 
02729                 string get_desc() const
02730                 {
02731                         return "fills masked region";
02732                 }
02733 
02734                 static const string NAME;
02735 
02736           protected:
02737                 void process_dist_pixel(float *pixel, float dist) const
02738                 {
02739                         if (dist >= outer_radius_square || dist < inner_radius_square)
02740                         {
02741                                 *pixel = Util::get_gauss_rand(mean, sigma);
02742                         }
02743                 }
02744         };
02745 
02748         class MaskGaussProcessor:public CircularMaskProcessor
02749         {
02750           public:
02751                 string get_name() const
02752                 {
02753                         return NAME;
02754                 }
02755                 static Processor *NEW()
02756                 {
02757                         return new MaskGaussProcessor();
02758                 }
02759 
02760                 void set_params(const Dict & new_params)
02761                 {
02762                         CircularMaskProcessor::set_params(new_params);
02763                         exponent = params["exponent"];
02764                         if (exponent <= 0.0) {
02765                                 exponent = 2.0;
02766                         }
02767                 }
02768 
02769                 TypeDict get_param_types() const
02770                 {
02771                         TypeDict d = CircularMaskProcessor::get_param_types();
02772                         d.put("exponent", EMObject::FLOAT, "The exponent, f in e^-Bs^f. default 2.0, producing a Gaussian");
02773                         return d;
02774                 }
02775 
02776                 string get_desc() const
02777                 {
02778                         return "a gaussian falloff to zero, radius is the 1/e of the width. If inner_radius>0, then \
02779 outer radius specifies width of Gaussian starting at inner_radius rather than total radius.";
02780                 }
02781 
02782                 static const string NAME;
02783 
02784           protected:
02785                 float exponent;
02786                 void process_dist_pixel(float *pixel, float dist) const
02787                 {
02788                         if (inner_radius_square>0) {
02789                                 if (dist>inner_radius_square) {
02790                                         if (exponent==2.0f) (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,2.0f) / outer_radius_square);
02791                                         else (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,exponent) / pow((float)outer_radius_square,exponent/2.0f));
02792                                 }
02793                         }
02794                         else {
02795                                 if (exponent==2.0f) (*pixel) *= exp(-dist / outer_radius_square);
02796                                 else (*pixel) *= exp(-pow(dist,exponent/2.0f) / pow((float)outer_radius_square,exponent/2.0f));
02797                         }
02798                 }
02799         };
02800 
02807         class MaskGaussNonuniformProcessor:public CoordinateProcessor
02808         {
02809           public:
02810                 MaskGaussNonuniformProcessor():radius_x(0), radius_y(0), radius_z(0), gauss_width(0)
02811                 {
02812                 }
02813 
02814                 void set_params(const Dict & new_params)
02815                 {
02816                         params = new_params;
02817 
02818                         if (params.has_key("radius_x")) radius_x=params["radius_x"];
02819                         else radius_x=5.0;
02820 
02821                         if (params.has_key("radius_y")) radius_y=params["radius_y"];
02822                         else radius_y=5.0;
02823 
02824                         if (params.has_key("radius_z")) radius_z=params["radius_z"];
02825                         else radius_z=5.0;
02826 
02827                         if (params.has_key("gauss_width")) gauss_width=params["gauss_width"];
02828                         else gauss_width=0.05f;
02829                 }
02830 
02831                 TypeDict get_param_types() const
02832                 {
02833                         TypeDict d;
02834 
02835                         d.put("radius_x", EMObject::INT, "x-axis radius");
02836                         d.put("radius_y", EMObject::INT, "y-axis radius");
02837                         d.put("radius_z", EMObject::INT, "z-axis radius");
02838                         d.put("gauss_width", EMObject::FLOAT, "Gaussian falloff width, relative to each radius, default 0.05");
02839 
02840                         return d;
02841                 }
02842 
02843                 string get_name() const
02844                 {
02845                         return NAME;
02846                 }
02847                 static Processor *NEW()
02848                 {
02849                         return new MaskGaussNonuniformProcessor();
02850                 }
02851 
02852                 string get_desc() const
02853                 {
02854                         return "A Gaussian falloff to zero. Nonisotropic, specify inner radius for x,y,z and Gaussian falloff width. Falloff \
02855 width is also nonisotropic and relative to the radii, with 1 being equal to the radius on that axis.";
02856                 }
02857 
02858                 static const string NAME;
02859 
02860           protected:
02861                 void process_pixel(float *pixel, int xi, int yi, int zi) const
02862                 {
02863                         float dist = pow((xi - nx/2)/radius_x,2.0f) + pow((yi - ny/2)/radius_y,2.0f) + pow((zi - nz/2)/radius_z,2.0f);
02864                         if (dist>1.0) (*pixel)*=exp(-pow((sqrt(dist)-1.0f)/gauss_width,2.0f));
02865                 }
02866 
02867                 float radius_x,radius_y,radius_z,gauss_width;
02868         };
02869 
02874         class MaskGaussInvProcessor:public CircularMaskProcessor
02875         {
02876           public:
02877                 TypeDict get_param_types() const
02878                 {
02879 //                      TypeDict d = CircularMaskProcessor::get_param_types();
02880                         TypeDict d;
02881                         d.put("gauss_width", EMObject::FLOAT, "Used to calculate the constant factor - gauss_width / (ny*ny)" );
02882 //                      d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02883                         return d;
02884                 }
02885 
02886                 string get_name() const
02887                 {
02888                         return NAME;
02889                 }
02890 
02891                 static Processor *NEW()
02892                 {
02893                         return new MaskGaussInvProcessor();
02894                 }
02895 
02896                 string get_desc() const
02897                 {
02898                         return "f(x) = f(x) / exp(-radius*radius * gauss_width / (ny*ny))";
02899                 }
02900 
02901                 static const string NAME;
02902 
02903           protected:
02904                 void calc_locals(EMData *)
02905                 {
02906                         xc = Util::fast_floor(nx/2.0f) + dx;
02907                         yc = Util::fast_floor(ny/2.0f) + dy;
02908                         zc = Util::fast_floor(nz/2.0f) + dz;
02909 
02910                         float gauss_width = params["gauss_width"];
02911                         slice_value = gauss_width / (ny * ny);
02912                 }
02913 
02914                 void process_dist_pixel(float *pixel, float dist) const
02915                 {
02916                         (*pixel) /= exp(-dist * slice_value);
02917                 }
02918           private:
02919                 float slice_value;
02920         };
02921 
02922 
02927         class LinearPyramidProcessor:public Processor
02928         {
02929           public:
02930                 string get_name() const
02931                 {
02932                         return NAME;
02933                 }
02934 
02935                 void process_inplace(EMData *image);
02936 
02937                 static Processor *NEW()
02938                 {
02939                         return new LinearPyramidProcessor();
02940                 }
02941 
02942                 string get_desc() const
02943                 {
02944                         return "Multiplies image by a 'linear pyramid', 1-(|x-xsize/2|*|y-ysize/2|*4/(xsize*ysize))";
02945                 }
02946 
02947                 static const string NAME;
02948         };
02949 
02950 
02953         class MakeRadiusSquaredProcessor:public CircularMaskProcessor
02954         {
02955           public:
02956                 string get_name() const
02957                 {
02958                         return NAME;
02959                 }
02960                 static Processor *NEW()
02961                 {
02962                         return new MakeRadiusSquaredProcessor();
02963                 }
02964 
02965                 string get_desc() const
02966                 {
02967                         return "overwrites input, f(x) = radius * radius";
02968                 }
02969 
02970                 static const string NAME;
02971 
02972           protected:
02973                 void process_dist_pixel(float *pixel, float dist) const
02974                 {
02975                         *pixel = dist;
02976                 }
02977         };
02978 
02981         class MakeRadiusProcessor:public CircularMaskProcessor
02982         {
02983           public:
02984                 string get_name() const
02985                 {
02986                         return NAME;
02987                 }
02988                 static Processor *NEW()
02989                 {
02990                         return new MakeRadiusProcessor();
02991                 }
02992 
02993                 string get_desc() const
02994                 {
02995                         return "overwrites input, f(x) = radius;";
02996                 }
02997 
02998                 static const string NAME;
02999 
03000           protected:
03001                 void process_dist_pixel(float *pixel, float dist) const
03002                 {
03003                         *pixel = sqrt(dist);
03004                 }
03005         };
03006 
03009         class ComplexPixelProcessor:public Processor
03010         {
03011           public:
03012                 void process_inplace(EMData * image);
03013 
03014                 static string get_group_desc()
03015                 {
03016                         return "The base class for fourier space processor working on individual pixels. ri2ap() is called before processing, so individual pixels will be A/P rather than R/I. The processor won't consider the pixel's coordinates and neighbors.";
03017                 }
03018 
03019           protected:
03020                 virtual void process_pixel(float *x) const = 0;
03021         };
03022 
03025         class ComplexNormPixel:public ComplexPixelProcessor
03026         {
03027           public:
03028                 string get_name() const
03029                 {
03030                         return NAME;
03031                 }
03032                 static Processor *NEW()
03033                 {
03034                         return new ComplexNormPixel();
03035                 }
03036 
03037                 string get_desc() const
03038                 {
03039                         return "Each Fourier pixel will be normalized. ie - amp=1, phase=unmodified. Useful for performing phase-residual-like computations with dot products.";
03040                 }
03041 
03042                 static const string NAME;
03043 
03044           protected:
03045                 void process_pixel(float *x) const
03046                 {
03047                         *x=1.0;
03048                 }
03049         };
03050 
03054         class AreaProcessor:public Processor
03055         {
03056           public:
03057                 AreaProcessor():areasize(0), kernel(0), nx(0), ny(0), nz(0)
03058                 {
03059                 }
03060 
03061                 void process_inplace(EMData * image);
03062 
03063                 void set_params(const Dict & new_params)
03064                 {
03065                         params = new_params;
03066                         areasize = params["areasize"];
03067                 }
03068 
03069                 TypeDict get_param_types() const
03070                 {
03071                         TypeDict d;
03072                         d.put("areasize", EMObject::INT, "The width of the area to process (not radius)");
03073                         return d;
03074                 }
03075 
03076                 string get_desc() const
03077                 {
03078                         return "AreaProcessor use pixel values and coordinates of a real-space square area. This is the base class. Specific AreaProcessor needs to implement function create_kernel().";
03079                 }
03080 
03081           protected:
03082                 virtual void process_pixel(float *pixel, float, float, float, float *area_matrix) const
03083                 {
03084                         for (int i = 0; i < matrix_size; i++)
03085                         {
03086                                 *pixel += area_matrix[i] * kernel[i];
03087                         }
03088                 }
03089 
03090                 virtual void create_kernel() const = 0;
03091 
03092                 int areasize;
03093                 int matrix_size;
03094                 float *kernel;
03095                 int nx;
03096                 int ny;
03097                 int nz;
03098         };
03099 
03102         class LaplacianProcessor:public AreaProcessor
03103         {
03104           public:
03105                 string get_name() const
03106                 {
03107                         return NAME;
03108                 }
03109                 static Processor *NEW()
03110                 {
03111                         return new LaplacianProcessor();
03112                 }
03113 
03114                 string get_desc() const
03115                 {
03116                         return "Discrete approximation to Laplacian. Edge enchancement, but works poorly in the presence of noise. Laplacian processor (x -> d^2/dx^2 + d^2/dy^2 + d^2/dz^2).";
03117                 }
03118 
03119                 static const string NAME;
03120 
03121           protected:
03122                 void create_kernel() const;
03123 
03124         };
03125 
03128         class ZeroConstantProcessor:public AreaProcessor
03129         {
03130           public:
03131                 string get_name() const
03132                 {
03133                         return NAME;
03134                 }
03135                 static Processor *NEW()
03136                 {
03137                         return new ZeroConstantProcessor();
03138                 }
03139 
03140                 string get_desc() const
03141                 {
03142                         return "Contraction of data, if any nearest neighbor is 0, value -> 0, generally used iteratively";
03143                 }
03144 
03145                 static const string NAME;
03146 
03147           protected:
03148                 void process_pixel(float *pixel, float, float, float, float *matrix) const
03149                 {
03150                         if (*pixel != 0)
03151                         {
03152                                 if (*pixel == matrix[1] || *pixel == matrix[3] || *pixel == matrix[5] ||
03153                                         *pixel == matrix[7] || matrix[1] == 0 || matrix[3] == 0 ||
03154                                         matrix[5] == 0 || matrix[7] == 0) {
03155                                         *pixel = 0;
03156                                 }
03157                         }
03158                 }
03159 
03160                 void create_kernel() const
03161                 {
03162                 }
03163         };
03164 
03173         class BoxStatProcessor:public Processor
03174         {
03175           public:
03176                 void process_inplace(EMData * image);
03177 
03178                 static string get_group_desc()
03179                 {
03180                         return "BoxStatProcessor files are a kind of neighborhood processors. These processors compute every output pixel using information from a reduced region on the neighborhood of the input pixel. The classical form are the 3x3 processors. BoxStatProcessors could perform diverse tasks ranging from noise reduction, to differential , to mathematical morphology. BoxStatProcessor class is the base class. Specific BoxStatProcessor needs to define process_pixel(float *pixel, const float *array, int n).";
03181                 }
03182 
03183                 TypeDict get_param_types() const
03184                 {
03185                         TypeDict d;
03186                         d.put("radius", EMObject::INT, "The radius of the search box, default is 1 which results in a 3x3 box (3 = 2xradius + 1)");
03187                         return d;
03188                 }
03189 
03190           protected:
03191                 virtual void process_pixel(float *pixel, const float *array, int n) const = 0;
03192         };
03193 
03194 
03197         class BoxMedianProcessor:public BoxStatProcessor
03198         {
03199           public:
03200                 string get_name() const
03201                 {
03202                         return NAME;
03203                 }
03204                 static Processor *NEW()
03205                 {
03206                         return new BoxMedianProcessor();
03207                 }
03208 
03209                 string get_desc() const
03210                 {
03211                         return "A processor for noise reduction. pixel = median of values surrounding pixel.";
03212                 }
03213 
03214                 static const string NAME;
03215 
03216           protected:
03217                 void process_pixel(float *pixel, const float *array, int n) const
03218                 {
03219                         float *data = new float[n];
03220                         memcpy(data, array, sizeof(float) * n);
03221 
03222                         for (int i = 0; i <= n / 2; i++)
03223                         {
03224                                 for (int j = i + 1; j < n; j++)
03225                                 {
03226                                         if (data[i] < data[j]) {
03227                                                 float t = data[i];
03228                                                 data[i] = data[j];
03229                                                 data[j] = t;
03230                                         }
03231                                 }
03232                         }
03233 
03234                         if (n % 2 != 0)
03235                         {
03236                                 *pixel = data[n / 2];
03237                         }
03238                         else {
03239                                 *pixel = (data[n / 2] + data[n / 2 - 1]) / 2;
03240                         }
03241                         if( data )
03242                         {
03243                                 delete[]data;
03244                                 data = 0;
03245                         }
03246                 }
03247         };
03248 
03251         class BoxSigmaProcessor:public BoxStatProcessor
03252         {
03253           public:
03254                 string get_name() const
03255                 {
03256                         return NAME;
03257                 }
03258                 static Processor *NEW()
03259                 {
03260                         return new BoxSigmaProcessor();
03261                 }
03262 
03263                 string get_desc() const
03264                 {
03265                         return "pixel = standard deviation of values surrounding pixel.";
03266                 }
03267 
03268                 static const string NAME;
03269 
03270           protected:
03271                 void process_pixel(float *pixel, const float *data, int n) const
03272                 {
03273                         float sum = 0;
03274                         float square_sum = 0;
03275                         for (int i = 0; i < n; i++)
03276                         {
03277                                 sum += data[i];
03278                                 square_sum += data[i] * data[i];
03279                         }
03280 
03281                         float mean = sum / n;
03282                         *pixel = sqrt(square_sum / n - mean * mean);
03283                 }
03284         };
03285 
03288         class BoxMaxProcessor:public BoxStatProcessor
03289         {
03290           public:
03291                 string get_name() const
03292                 {
03293                         return NAME;
03294                 }
03295                 static Processor *NEW()
03296                 {
03297                         return new BoxMaxProcessor();
03298                 }
03299 
03300                 string get_desc() const
03301                 {
03302                         return "peak processor: pixel = max of values surrounding pixel.";
03303                 }
03304 
03305                 static const string NAME;
03306 
03307           protected:
03308                 void process_pixel(float *pixel, const float *data, int n) const
03309                 {
03310                         float maxval = -FLT_MAX;
03311                         for (int i = 0; i < n; i++)
03312                         {
03313                                 if (data[i] > maxval) {
03314                                         maxval = data[i];
03315                                 }
03316                         }
03317                          *pixel = maxval;
03318                 }
03319         };
03320 
03323         class MinusPeakProcessor:public BoxStatProcessor
03324         {
03325           public:
03326                 string get_name() const
03327                 {
03328                         return NAME;
03329                 }
03330                 static Processor *NEW()
03331                 {
03332                         return new MinusPeakProcessor();
03333                 }
03334 
03335                 string get_desc() const
03336                 {
03337                         return "peak processor: pixel = pixel - max of values surrounding pixel. This is a sort of positive peak-finding algorithm.";
03338                 }
03339 
03340                 static const string NAME;
03341 
03342           protected:
03343                 void process_pixel(float *pixel, const float *data, int n) const
03344                 {
03345                         float maxval = -FLT_MAX;
03346                         for (int i = 0; i < n; i++)
03347                         {
03348                                 if (data[i] > maxval) {
03349                                         maxval = data[i];
03350                                 }
03351                         }
03352                          *pixel -= maxval;
03353                 }
03354         };
03355 
03359         class PeakOnlyProcessor:public BoxStatProcessor
03360         {
03361           public:
03362                 string get_name() const
03363                 {
03364                         return NAME;
03365                 }
03366                 static Processor *NEW()
03367                 {
03368                         return new PeakOnlyProcessor();
03369                 }
03370                 void set_params(const Dict & new_params)
03371                 {
03372                         params = new_params;
03373                         npeaks = params["npeaks"];
03374                         if (npeaks == 0) {
03375                                 npeaks = 1;
03376                         }
03377                 }
03378 
03379                 TypeDict get_param_types() const
03380                 {
03381                         TypeDict d;
03382                         d.put("npeaks", EMObject::INT, "the number of surrounding peaks allow to >= pixel values");
03383                         return d;
03384                 }
03385 
03386                 string get_desc() const
03387                 {
03388                         return "peak processor -> if npeaks or more surrounding values >= value, value->0";
03389                 }
03390 
03391                 static const string NAME;
03392 
03393           protected:
03394                 void process_pixel(float *pixel, const float *data, int n) const
03395                 {
03396                         int r = 0;
03397 
03398                         for (int i = 0; i < n; i++)
03399                         {
03400                                 if (data[i] >= *pixel) {
03401                                         r++;
03402                                 }
03403                         }
03404 
03405                         if (r > npeaks)
03406                         {
03407                                 *pixel = 0;
03408                         }
03409                 }
03410           private:
03411                 int npeaks;
03412         };
03413 
03418         class DiffBlockProcessor:public Processor
03419         {
03420           public:
03421                 void process_inplace(EMData * image);
03422 
03423                 string get_name() const
03424                 {
03425                         return NAME;
03426                 }
03427                 static Processor *NEW()
03428                 {
03429                         return new DiffBlockProcessor();
03430                 }
03431 
03432                 string get_desc() const
03433                 {
03434                         return "averages over cal_half_width, then sets the value in a local block";
03435                 }
03436 
03437                 TypeDict get_param_types() const
03438                 {
03439                         TypeDict d;
03440                         d.put("cal_half_width", EMObject::FLOAT, "cal_half_width is dx/dy for calculating an average");
03441                         d.put("fill_half_width", EMObject::FLOAT, "fill_half_width is dx/dy for fill/step");
03442                         return d;
03443                 }
03444 
03445                 static const string NAME;
03446         };
03447 
03452         class CutoffBlockProcessor:public Processor
03453         {
03454           public:
03455                 void process_inplace(EMData * image);
03456 
03457                 string get_name() const
03458                 {
03459                         return NAME;
03460                 }
03461                 static Processor *NEW()
03462                 {
03463                         return new CutoffBlockProcessor();
03464                 }
03465 
03466                 TypeDict get_param_types() const
03467                 {
03468                         TypeDict d;
03469                         d.put("value1", EMObject::FLOAT, "val1 is dx/dy");
03470                         d.put("value2", EMObject::FLOAT, "val2 is lowpass freq cutoff in pixels");
03471                         return d;
03472                 }
03473 
03474                 string get_desc() const
03475                 {
03476                         return "Block processor, val1 is dx/dy, val2 is lp freq cutoff in pixels. Mystery processor.";
03477                 }
03478 
03479                 static const string NAME;
03480         };
03481 
03487         class BooleanShrinkProcessor
03488         {
03489                 protected:
03497                         template<class LogicOp>
03498                         EMData* process(const EMData *const image, Dict& params);
03499 
03506                         template<class LogicOp>
03507                         void process_inplace(EMData * image, Dict& params);
03508 
03509         };
03510 
03519         class MaxShrinkProcessor:public BooleanShrinkProcessor, public Processor
03520         {
03521                 public:
03528                         virtual EMData* process(const EMData *const image)
03529                         {
03530                                 return BooleanShrinkProcessor::process<GreaterThan>(image, params);
03531                         }
03532 
03533                         // resizes the image
03534                         virtual void process_inplace(EMData * image)
03535                         {
03536                                 BooleanShrinkProcessor::process_inplace<GreaterThan>(image, params);
03537                         }
03538 
03539                         string get_desc() const
03540                         {
03541                                 return "Shrink an image by a given amount (default 2), using the maximum value found in the pixel neighborhood.";
03542                         }
03543 
03544                         string get_name() const
03545                         {
03546                                 return NAME;
03547                         }
03548                         static Processor *NEW()
03549                         {
03550                                 return new MaxShrinkProcessor();
03551                         }
03552 
03553                         TypeDict get_param_types() const
03554                         {
03555                                 TypeDict d;
03556                                 d.put("n", EMObject::INT, "The shrink factor");
03557                                 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03558                                 return d;
03559                         }
03560 
03561                         static const string NAME;
03562 
03563                 private:
03564                         struct GreaterThan
03565                         {
03566                                 inline bool operator()(float left,float right) const { return left > right; }
03567                                 inline float get_start_val() { return -10000000; }
03568                         };
03569         };
03570 
03579         class MinShrinkProcessor:public BooleanShrinkProcessor, public Processor
03580         {
03581                 public:
03588                         virtual EMData* process(const EMData *const image)
03589                         {
03590                                 return BooleanShrinkProcessor::process<LessThan>(image, params);
03591                         }
03592 
03593                         // resizes the image
03594                         virtual void process_inplace(EMData * image)
03595                         {
03596                                 BooleanShrinkProcessor::process_inplace<LessThan>(image, params);
03597                         }
03598                         string get_desc() const
03599                         {
03600                                 return "Shrink an image by a given amount (default 2), using the minimum value found in the pixel neighborhood.";
03601                         }
03602 
03603                         string get_name() const
03604                         {
03605                                 return NAME;
03606                         }
03607                         static Processor *NEW()
03608                         {
03609                                 return new MinShrinkProcessor();
03610                         }
03611 
03612                         TypeDict get_param_types() const
03613                         {
03614                                 TypeDict d;
03615                                 d.put("n", EMObject::INT, "The shrink factor");
03616                                 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03617                                 return d;
03618                         }
03619 
03620                         static const string NAME;
03621 
03622                 private:
03623                 struct LessThan
03624                 {
03625                         inline bool operator()(float left,float right) const { return left < right; }
03626                         inline float get_start_val() { return 9999999999.0f; }
03627                 };
03628         };
03629 
03636         class MeanShrinkProcessor : public Processor
03637         {
03638                 public:
03649                         virtual EMData* process(const EMData *const image);
03650 
03657                         virtual void process_inplace(EMData * image);
03658 
03659                         string get_desc() const
03660                         {
03661                                 return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
03662                         }
03663 
03664                         virtual string get_name() const
03665                         {
03666                                 return NAME;
03667                         }
03668                         static Processor *NEW()
03669                         {
03670                                 return new MeanShrinkProcessor();
03671                         }
03672 
03673                         virtual TypeDict get_param_types() const
03674                         {
03675                                 TypeDict d;
03676                                 d.put("n", EMObject::FLOAT, "The shrink factor");
03677                                 return d;
03678                         }
03679 
03680                         static const string NAME;
03681 
03682                 private:
03690                         void accrue_mean(EMData* to, const EMData *const from, const int shrinkfactor);
03691 
03698                         void accrue_mean_one_p_five(EMData* to, const EMData * const from);
03699         };
03700 
03701 
03708         class MedianShrinkProcessor : public Processor
03709         {
03710         public:
03721                 virtual EMData* process(const EMData *const image);
03722 
03729                 virtual void process_inplace(EMData * image);
03730 
03731                 string get_desc() const
03732                 {
03733                         return "Shrink an image by a given amount , using the median value found in the pixel neighborhood.";
03734                 }
03735 
03736                 virtual string get_name() const
03737                 {
03738                         return NAME;
03739                 }
03740                 static Processor *NEW()
03741                 {
03742                         return new MedianShrinkProcessor();
03743                 }
03744 
03745                 virtual TypeDict get_param_types() const
03746                 {
03747                         TypeDict d;
03748                         d.put("n", EMObject::INT, "The shrink factor");
03749                         return d;
03750                 }
03751 
03752                 static const string NAME;
03753 
03754         private:
03762                 void accrue_median(EMData* to, const EMData* const from,const int shrink_factor);
03763         };
03764 
03765 
03774         class FFTResampleProcessor : public Processor
03775         {
03776                 public:
03777                         virtual EMData* process(const EMData *const image);
03778 
03779                         virtual void process_inplace(EMData * image);
03780 
03781                         string get_desc() const
03782                         {
03783                                 return "Robust resampling of an image by clipping its Fourier transform.";
03784                         }
03785 
03786                         string get_name() const
03787                         {
03788                                 return NAME;
03789                         }
03790                         static Processor *NEW()
03791                         {
03792                                 return new FFTResampleProcessor();
03793                         }
03794 
03795                         TypeDict get_param_types() const
03796                         {
03797                                 TypeDict d;
03798                                 d.put("n", EMObject::FLOAT, "The sample rate. Less than one enlarges the image, greater than one shrinks it.");
03799                                 return d;
03800                         }
03801 
03802                         static const string NAME;
03803 
03804                 private:
03811                         void fft_resample(EMData* to, const EMData *const from, const float& sample_rate);
03812 
03813         };
03814 
03817         class GradientRemoverProcessor:public Processor
03818         {
03819           public:
03820                 void process_inplace(EMData * image);
03821 
03822                 string get_name() const
03823                 {
03824                         return NAME;
03825                 }
03826                 static Processor *NEW()
03827                 {
03828                         return new GradientRemoverProcessor();
03829                 }
03830 
03831                 string get_desc() const
03832                 {
03833                         return "Gradient remover, does a rough plane fit to find linear gradients.";
03834                 }
03835 
03836                 static const string NAME;
03837         };
03838 
03847         class GradientPlaneRemoverProcessor:public Processor
03848     {
03849           public:
03850                 void process_inplace(EMData * image);
03851 
03852                 string get_name() const
03853                 {
03854                         return NAME;
03855                 }
03856                 static Processor *NEW()
03857                 {
03858                         return new GradientPlaneRemoverProcessor();
03859                 }
03860 
03861                 string get_desc() const
03862                 {
03863                         return "Remove gradient by least square plane fit";
03864                 }
03865 
03866                 TypeDict get_param_types() const
03867                 {
03868                         TypeDict d;
03869                         d.put("mask", EMObject::EMDATA, "mask object: nonzero pixel positions will be used to fit plane. default = 0");
03870                         d.put("changeZero", EMObject::INT, "if zero pixels are modified when removing gradient. default = 0");
03871                         d.put("planeParam", EMObject::FLOATARRAY, "fitted plane parameters output");
03872                         return d;
03873                 }
03874 
03875                 static const string NAME;
03876         };
03877 
03883         class NonConvexProcessor:public Processor
03884     {
03885           public:
03886                 void process_inplace(EMData * image);
03887 
03888                 string get_name() const
03889                 {
03890                         return NAME;
03891                 }
03892                 static Processor *NEW()
03893                 {
03894                         return new NonConvexProcessor();
03895                 }
03896 
03897                 string get_desc() const
03898                 {
03899                         return "Makes a curve or plane monotonically decreasing and non-convex. Useful in generating background curves from power spectra. Anchored at edges and (in 2d) at the center. If local value > mean(surrounding values) => mean(surrounding values).";
03900                 }
03901 
03902                 TypeDict get_param_types() const
03903                 {
03904                         TypeDict d;
03905 /*                      d.put("mask", EMObject::EMDATA, "mask object: nonzero pixel positions will be used to fit plane. default = 0");
03906                         d.put("changeZero", EMObject::INT, "if zero pixels are modified when removing gradient. default = 0");
03907                         d.put("planeParam", EMObject::FLOATARRAY, "fitted plane parameters output");*/
03908                         return d;
03909                 }
03910 
03911                 static const string NAME;
03912         };
03913 
03920         class FlattenBackgroundProcessor:public Processor
03921         {
03922                 public:
03923                         void process_inplace(EMData * image);
03924 
03925                         string get_name() const
03926                         {
03927                                 return NAME;
03928                         }
03929 
03930                         static Processor *NEW()
03931                         {
03932                                 return new FlattenBackgroundProcessor();
03933                         }
03934 
03935                         string get_desc() const
03936                         {
03937                                 return "Flattens the background by subtracting the local mean";
03938                         }
03939 
03940                         TypeDict get_param_types() const
03941                         {
03942                                 TypeDict d;
03943                                 d.put("mask", EMObject::EMDATA, "A mask the defines the local neighborhood that will be used to find the local mean. Exclusive of the radius argument");
03944                                 d.put("radius", EMObject::INT, "The radius of circle/sphere that defines the local neighborhood. Exclusive of the mask argument");
03945                                 return d;
03946                         }
03947 
03948                         static const string NAME;
03949         };
03950 
03951 
03954         class RampProcessor:public Processor
03955     {
03956           public:
03957                 void process_inplace(EMData * image);
03958 
03959                 string get_name() const
03960                 {
03961                         return NAME;
03962                 }
03963                 static Processor *NEW()
03964                 {
03965                         return new RampProcessor();
03966                 }
03967 
03968                 string get_desc() const
03969                 {
03970                         return "Ramp processor -- Fits a least-squares plane "
03971                                    "to the picture, and subtracts the plane from "
03972                                    "the picture.  A wedge-shaped overall density "
03973                                    "profile can thus be removed from the picture.";
03974                 }
03975 
03976                 static const string NAME;
03977         };
03978 
03981         class VerticalStripeProcessor:public Processor
03982         {
03983           public:
03984                 void process_inplace(EMData * image);
03985 
03986                 string get_name() const
03987                 {
03988                         return NAME;
03989                 }
03990 
03991                 static Processor *NEW()
03992                 {
03993                         return new VerticalStripeProcessor();
03994                 }
03995 
03996                 string get_desc() const
03997                 {
03998                         return "Tries to fix images scanned on the zeiss for poor ccd normalization.";
03999                 }
04000 
04001                 static const string NAME;
04002         };
04003 
04006         class RealToFFTProcessor:public Processor
04007         {
04008                 public:
04009                 void process_inplace(EMData *image);
04010 
04011                 string get_name() const
04012                 {
04013                         return NAME;
04014                 }
04015 
04016                 static Processor *NEW()
04017                 {
04018                         return new RealToFFTProcessor();
04019                 }
04020 
04021                 string get_desc() const
04022                 {
04023                         return "This will replace the image with a full-circle 2D fft amplitude rendering. Note that this renders amplitude, when intensity is more common.";
04024                 }
04025 
04026                 static const string NAME;
04027         };
04028 
04029 
04032         class SigmaZeroEdgeProcessor:public Processor
04033         {
04034           public:
04035                 void process_inplace(EMData * image);
04036 
04037                 string get_name() const
04038                 {
04039                         return NAME;
04040                 }
04041                 static Processor *NEW()
04042                 {
04043                         return new SigmaZeroEdgeProcessor();
04044                 }
04045 
04046                 string get_desc() const
04047                 {
04048                         return "Fill zeroes at edges with nearest horizontal/vertical value.";
04049                 }
04050 
04051                 TypeDict get_param_types() const
04052                 {
04053                         TypeDict d;
04054                         d.put("nonzero", EMObject::BOOL, "If set, will look for constant non-zero values to fill");
04055                         return d;
04056                 }
04057 
04058                 static const string NAME;
04059         };
04060 
04066         class BeamstopProcessor:public Processor
04067         {
04068           public:
04069                 void process_inplace(EMData * image);
04070 
04071                 string get_name() const
04072                 {
04073                         return NAME;
04074                 }
04075 
04076                 static Processor *NEW()
04077                 {
04078                         return new BeamstopProcessor();
04079                 }
04080 
04081                 string get_desc() const
04082                 {
04083                         return "Try to eliminate beamstop in electron diffraction patterns. value1=sig multiplier; value2,value3 are x,y of center, if value1<0 also does radial subtract.";
04084                 }
04085 
04086                 TypeDict get_param_types() const
04087                 {
04088                         TypeDict d;
04089                         d.put("value1", EMObject::FLOAT, "sig multiplier");
04090                         d.put("value2", EMObject::FLOAT, "x of center");
04091                         d.put("value3", EMObject::FLOAT, "y of center");
04092                         return d;
04093                 }
04094 
04095                 static const string NAME;
04096         };
04097 
04100         class MeanZeroEdgeProcessor:public Processor
04101         {
04102           public:
04103                 void process_inplace(EMData * image);
04104 
04105                 string get_name() const
04106                 {
04107                         return NAME;
04108                 }
04109 
04110                 static Processor *NEW()
04111                 {
04112                         return new MeanZeroEdgeProcessor();
04113                 }
04114 
04115                 string get_desc() const
04116                 {
04117                         return "Fill zeroes at edges with nearest horizontal/vertical value damped towards Mean2.";
04118                 }
04119 
04120                 static const string NAME;
04121         };
04122 
04123 
04126         class AverageXProcessor:public Processor
04127         {
04128           public:
04129                 void process_inplace(EMData * image);
04130 
04131                 string get_name() const
04132                 {
04133                         return NAME;
04134                 }
04135 
04136                 static Processor *NEW()
04137                 {
04138                         return new AverageXProcessor();
04139                 }
04140 
04141                 string get_desc() const
04142                 {
04143                         return "Average along Y and replace with average";
04144                 }
04145 
04146                 static const string NAME;
04147         };
04148 
04152         class DecayEdgeProcessor:public Processor
04153         {
04154           public:
04155                 void process_inplace(EMData * image);
04156                 string get_name() const
04157                 {
04158                         return NAME;
04159                 }
04160 
04161                 static Processor *NEW()
04162                 {
04163                         return new DecayEdgeProcessor();
04164                 }
04165 
04166                 string get_desc() const
04167                 {
04168                         return "Decay edges of image to zero";
04169                 }
04170 
04171                 TypeDict get_param_types() const
04172                 {
04173                         TypeDict d;
04174                         d.put("width", EMObject::INT, "Width of the decay region around the edge of the image in pixels");
04175                         return d;
04176                 }
04177 
04178                 static const string NAME;
04179         };
04180 
04187         class ZeroEdgeRowProcessor:public Processor
04188         {
04189           public:
04190                 void process_inplace(EMData * image);
04191                 string get_name() const
04192                 {
04193                         return NAME;
04194                 }
04195 
04196                 static Processor *NEW()
04197                 {
04198                         return new ZeroEdgeRowProcessor();
04199                 }
04200 
04201                 string get_desc() const
04202                 {
04203                         return "zero edges of image on top and bottom, and on left and right.";
04204                 }
04205 
04206                 TypeDict get_param_types() const
04207                 {
04208                         TypeDict d;
04209                         d.put("x0", EMObject::INT, "The number of columns to zero from left");
04210                         d.put("x1", EMObject::INT, "The number of columns to zero from right");
04211                         d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
04212                         d.put("y1", EMObject::INT, "The number of rows to zero from the top");
04213                         return d;
04214                 }
04215 
04216                 static const string NAME;
04217         };
04218 
04227         class ZeroEdgePlaneProcessor:public Processor
04228         {
04229           public:
04230                 void process_inplace(EMData * image);
04231                 string get_name() const
04232                 {
04233                         return NAME;
04234                 }
04235 
04236                 static Processor *NEW()
04237                 {
04238                         return new ZeroEdgePlaneProcessor();
04239                 }
04240 
04241                 string get_desc() const
04242                 {
04243                         return "zero edges of volume on all sides";
04244                 }
04245 
04246                 TypeDict get_param_types() const
04247                 {
04248                         TypeDict d;
04249                         d.put("x0", EMObject::INT, "The number of columns to zero from left");
04250                         d.put("x1", EMObject::INT, "The number of columns to zero from right");
04251                         d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
04252                         d.put("y1", EMObject::INT, "The number of rows to zero from the top");
04253                         d.put("z0", EMObject::INT, "The number of slices to zero from the bottom");
04254                         d.put("z1", EMObject::INT, "The number of slices to zero from the top");
04255                         return d;
04256                 }
04257 
04258                 static const string NAME;
04259         };
04260 
04261 
04268         class BilateralProcessor:public Processor
04269         {
04270           public:
04271                 void process_inplace(EMData * image);
04272                 string get_name() const
04273                 {
04274                         return NAME;
04275                 }
04276 
04277                 string get_desc() const
04278                 {
04279                         return "Bilateral processing on 2D or 3D volume data. Bilateral processing does non-linear weighted averaging processing within a certain window. ";
04280                 }
04281 
04282                 static Processor *NEW()
04283                 {
04284                         return new BilateralProcessor();
04285                 }
04286 
04287                 TypeDict get_param_types() const
04288                 {
04289                         TypeDict d;
04290                         d.put("distance_sigma", EMObject::FLOAT, "means how large the voxel has impact on its neighbors in spatial domain. The larger it is, the more blurry the resulting image.");
04291                         d.put("value_sigma", EMObject::FLOAT, "means how large the voxel has impact on its in  range domain. The larger it is, the more blurry the resulting image.");
04292                         d.put("niter", EMObject::INT, "how many times to apply this processing on your data.");
04293                         d.put("half_width", EMObject::INT, "processing window size = (2 * half_widthh + 1) ^ 3.");
04294                         return d;
04295                 }
04296 
04297                 static const string NAME;
04298         };
04299 
04302         class NormalizeProcessor:public Processor
04303         {
04304           public:
04305                 void process_inplace(EMData * image);
04306 
04307                 static string get_group_desc()
04308                 {
04309                         return "Base class for normalization processors. Each specific normalization processor needs to define how to calculate mean and how to calculate sigma.";
04310                 }
04311 
04312           protected:
04313                 virtual float calc_sigma(EMData * image) const;
04314                 virtual float calc_mean(EMData * image) const = 0;
04315         };
04316 
04319         class NormalizeUnitProcessor:public NormalizeProcessor
04320         {
04321           public:
04322                 string get_name() const
04323                 {
04324                         return NAME;
04325                 }
04326 
04327                 static Processor *NEW()
04328                 {
04329                         return new NormalizeUnitProcessor();
04330                 }
04331 
04332                 string get_desc() const
04333                 {
04334                         return "Normalize an image so its vector length is 1.0.";
04335                 }
04336 
04337                 static const string NAME;
04338 
04339           protected:
04340                 float calc_sigma(EMData * image) const;
04341                 float calc_mean(EMData * image) const;
04342         };
04343 
04344         inline float NormalizeUnitProcessor::calc_mean(EMData *) const { return 0; }
04345 
04348         class NormalizeUnitSumProcessor:public NormalizeProcessor
04349         {
04350           public:
04351                 string get_name() const
04352                 {
04353                         return NAME;
04354                 }
04355 
04356                 static Processor *NEW()
04357                 {
04358                         return new NormalizeUnitSumProcessor();
04359                 }
04360 
04361                 string get_desc() const
04362                 {
04363                         return "Normalize an image so its elements sum to 1.0 (fails if mean=0)";
04364                 }
04365 
04366                 static const string NAME;
04367 
04368           protected:
04369                 float calc_sigma(EMData * image) const;
04370                 float calc_mean(EMData * image) const;
04371         };
04372 
04373         inline float NormalizeUnitSumProcessor::calc_mean(EMData *) const { return 0; }
04374 
04375 
04378         class NormalizeStdProcessor:public NormalizeProcessor
04379         {
04380           public:
04381                 string get_name() const
04382                 {
04383                         return NAME;
04384                 }
04385 
04386                 static Processor *NEW()
04387                 {
04388                         return new NormalizeStdProcessor();
04389                 }
04390 
04391                 string get_desc() const
04392                 {
04393                         return "do a standard normalization on an image.";
04394                 }
04395 
04396                 static const string NAME;
04397 
04398           protected:
04399                 float calc_mean(EMData * image) const;
04400         };
04401 
04406         class NormalizeMaskProcessor:public NormalizeProcessor
04407         {
04408           public:
04409                 string get_name() const
04410                 {
04411                         return NAME;
04412                 }
04413 
04414                 string get_desc() const
04415                 {
04416                         return "Uses a 1/0 mask defining a region to use for the zero-normalization.if no_sigma is 1, standard deviation not modified.";
04417                 }
04418 
04419                 static Processor *NEW()
04420                 {
04421                         return new NormalizeMaskProcessor();
04422                 }
04423 
04424                 TypeDict get_param_types() const
04425                 {
04426                         TypeDict d;
04427                         d.put("mask", EMObject::EMDATA, "the 1/0 mask defining a region to use for the zero-normalization");
04428                         d.put("no_sigma", EMObject::INT, "if this flag is zero, only average under the mask will be substracted. set this flag to 1, standard deviation not modified");
04429                         return d;
04430                 }
04431 
04432                 static const string NAME;
04433 
04434           protected:
04435                 float calc_sigma(EMData * image) const;
04436                 float calc_mean(EMData * image) const;
04437         };
04438 
04444         class NormalizeRampNormVar: public Processor
04445         {
04446                 public:
04447                         string get_name() const
04448                         {
04449                                 return NAME;
04450                         }
04451 
04452                         static Processor *NEW()
04453                         {
04454                                 return new NormalizeRampNormVar();
04455                         }
04456 
04457                         string get_desc() const
04458                         {
04459                                 return "First call filter.ramp on the image, then make the mean 0 and norm 1";
04460                         }
04461 
04462                         void process_inplace(EMData * image);
04463 
04464                         static const string NAME;
04465         };
04466 
04475         class NormalizeByMassProcessor: public Processor
04476         {
04477                 public:
04478                         string get_name() const
04479                         {
04480                                 return NAME;
04481                         }
04482 
04483                         static Processor *NEW()
04484                         {
04485                                 return new NormalizeByMassProcessor();
04486                         }
04487 
04488                         string get_desc() const
04489                         {
04490                                 return "Normalize the mass of the image assuming a density of 1.35 g/ml (0.81 Da/A^3) (3D only)";
04491                         }
04492 
04493                         TypeDict get_param_types() const
04494                         {
04495                                 TypeDict d;
04496                                 d.put("apix", EMObject::FLOAT,"Angstrom per pixel of the image. If not set will use the apix_x attribute of the image");
04497                                 d.put("mass", EMObject::FLOAT,"The approximate mass of protein/structure in kilodaltons");
04498                                 d.put("thr", EMObject::FLOAT,"The isosurface threshold which encapsulates the structure");
04499                                 d.put("verbose", EMObject::INT,"If set will give details about the normalization");
04500                                 return d;
04501                         }
04502 
04503                         void process_inplace(EMData * image);
04504 
04505                         static const string NAME;
04506         };
04507 
04508 
04511         class NormalizeEdgeMeanProcessor:public NormalizeProcessor
04512         {
04513           public:
04514                 string get_name() const
04515                 {
04516                         return NAME;
04517                 }
04518 
04519                 static Processor *NEW()
04520                 {
04521                         return new NormalizeEdgeMeanProcessor();
04522                 }
04523 
04524                 string get_desc() const
04525                 {
04526                         return "normalizes an image, mean value equals to edge mean.";
04527                 }
04528 
04529                 static const string NAME;
04530 
04531           protected:
04532                 float calc_mean(EMData * image) const;
04533         };
04534 
04537         class NormalizeCircleMeanProcessor:public NormalizeProcessor
04538         {
04539           public:
04540                 string get_name() const
04541                 {
04542                         return NAME;
04543                 }
04544 
04545                 static Processor *NEW()
04546                 {
04547                         return new NormalizeCircleMeanProcessor();
04548                 }
04549 
04550                 string get_desc() const
04551                 {
04552                         return "normalizes an image, mean value equals to mean of 2 pixel circular radius or of the circular border if no radius is set.";
04553                 }
04554 
04555                 TypeDict get_param_types() const
04556                 {
04557                         TypeDict d;
04558                         d.put("radius", EMObject::FLOAT,"Radius of 2 pixel circular border");
04559                         return d;
04560                 }
04561 
04562                 static const string NAME;
04563 
04564           protected:
04565                 float calc_mean(EMData * image) const;
04566         };
04567 
04570         class NormalizeLREdgeMeanProcessor:public NormalizeProcessor
04571         {
04572           public:
04573                 string get_name() const
04574                 {
04575                         return NAME;
04576                 }
04577 
04578                 static Processor *NEW()
04579                 {
04580                         return new NormalizeLREdgeMeanProcessor();
04581                 }
04582 
04583                 string get_desc() const
04584                 {
04585                         return "normalizes an image, uses 2 pixels on left and right edge";
04586                 }
04587 
04588                 static const string NAME;
04589 
04590           protected:
04591                 float calc_mean(EMData * image) const;
04592         };
04593 
04596         class NormalizeMaxMinProcessor:public NormalizeProcessor
04597         {
04598           public:
04599                 string get_name() const
04600                 {
04601                         return NAME;
04602                 }
04603 
04604                 static Processor *NEW()
04605                 {
04606                         return new NormalizeMaxMinProcessor();
04607                 }
04608 
04609                 string get_desc() const
04610                 {
04611                         return "normalizes an image. mean -> (maxval-minval)/2; std dev = (maxval+minval)/2;";
04612                 }
04613 
04614                 static const string NAME;
04615 
04616           protected:
04617                 float calc_sigma(EMData * image) const;
04618                 float calc_mean(EMData * image) const;
04619         };
04620 
04623         class NormalizeRowProcessor:public Processor
04624         {
04625           public:
04626                 string get_name() const
04627                 {
04628                         return NAME;
04629                 }
04630 
04631                 static Processor *NEW()
04632                 {
04633                         return new NormalizeRowProcessor();
04634                 }
04635 
04636                 string get_desc() const
04637                 {
04638                         return "normalizes each row in the image individually";
04639                 }
04640 
04641                 static const string NAME;
04642 
04643                 void process_inplace(EMData * image);
04644         };
04645 
04657         class SubtractOptProcessor:public Processor
04658         {
04659           public:
04660                 virtual void process_inplace(EMData *image);
04661                 virtual EMData* process(const EMData * const image);
04662 
04663                 string get_name() const
04664                 {
04665                         return NAME;
04666                 }
04667 
04668                 static Processor *NEW()
04669                 {
04670                         return new SubtractOptProcessor();
04671                 }
04672 
04673                 TypeDict get_param_types() const
04674                 {
04675                         TypeDict d;
04676                         d.put("ref", EMObject::EMDATA, "Reference image to subtract");
04677                         d.put("actual", EMObject::EMDATA, "If specified, ref is used for normalization, but actual is subtracted.");
04678                         d.put("low_cutoff_frequency", EMObject::FLOAT, "Absolute [0,0.5] low cut-off frequency.");
04679                         d.put("high_cutoff_frequency", EMObject::FLOAT, "Absolute [0,0.5] high cut-off frequency.");
04680                         d.put("ctfweight",EMObject::BOOL, "Filter the image by CTF before subtraction");
04681                         d.put("return_fft",EMObject::BOOL, "Skips the final IFT, and returns the FFT of the subtracted image");
04682                         d.put("return_radial", EMObject::BOOL, "Return the radial filter function as an attribute (filter_curve)");
04683                         d.put("return_presigma", EMObject::BOOL, "Return the sigma of the pre-subtracted image in real-space with the specified filter applied as sigma_presub. This is an expensive option.");
04684                         return d;
04685                 }
04686 
04687                 string get_desc() const
04688                 {
04689                         return "This will filter/scale 'ref' optimally and subtract it from image using ring dot products in Fourier space for normalization. Cutoff frequencies apply a bandpass tophat filter to the output.";
04690                 }
04691 
04692                 static const string NAME;
04693         };
04694 
04695 
04701         class NormalizeToLeastSquareProcessor:public Processor
04702         {
04703           public:
04704                 void process_inplace(EMData * image);
04705 
04706                 string get_name() const
04707                 {
04708                         return NAME;
04709                 }
04710 
04711                 static Processor *NEW()
04712                 {
04713                         return new NormalizeToLeastSquareProcessor();
04714                 }
04715 
04716                 TypeDict get_param_types() const
04717                 {
04718                         TypeDict d;
04719                         d.put("to", EMObject::EMDATA, "reference image normalize to");
04720                         d.put("ignore_zero", EMObject::BOOL, "If set, ignores any pixels which are exactly zero in either image. Defaut = True.");
04721                         d.put("ignore_lowsig", EMObject::FLOAT, "If >0, then any pixels closer to the mean than val*sigma in either image excluded");
04722                         d.put("low_threshold", EMObject::FLOAT, "only take into account the reference image's pixel value between high and low threshold (zero is always ignored)");
04723                         d.put("high_threshold", EMObject::FLOAT, "only take into account the reference image's pixel value between high and low threshold (zero is always ignored)");
04724                         return d;
04725                 }
04726 
04727                 string get_desc() const
04728                 {
04729                         return "use least square method to normalize";
04730                 }
04731 
04732                 static const string NAME;
04733         };
04734 
04737         class RotationalAverageProcessor:public Processor
04738         {
04739           public:
04740                 void process_inplace(EMData * image);
04741 
04742                 string get_name() const
04743                 {
04744                         return NAME;
04745                 }
04746 
04747                 static Processor *NEW()
04748                 {
04749                         return new RotationalAverageProcessor();
04750                 }
04751 
04752                 string get_desc() const
04753                 {
04754                         return "Makes image circularly/spherically symmetric.";
04755                 }
04756 
04757                 static const string NAME;
04758         };
04759 
04762         class RotationalSubstractProcessor:public Processor
04763         {
04764           public:
04765                 virtual void process_inplace(EMData * image);
04766 
04767                 virtual string get_name() const
04768                 {
04769                         return NAME;
04770                 }
04771 
04772                 static Processor *NEW()
04773                 {
04774                         return new RotationalSubstractProcessor();
04775                 }
04776 
04777                 virtual string get_desc() const
04778                 {
04779                         return "subtracts circularly/spherically symmetric part of an image.";
04780                 }
04781 
04782                 static const string NAME;
04783         };
04784 
04790         class TransposeProcessor:public Processor
04791         {
04792           public:
04793 
04798                 virtual void process_inplace(EMData * image);
04799 
04804                 virtual EMData* process(const EMData * const image);
04805 
04806                 virtual string get_name() const
04807                 {
04808                         return NAME;
04809                 }
04810 
04811                 static Processor *NEW()
04812                 {
04813                         return new TransposeProcessor();
04814                 }
04815 
04816                 virtual TypeDict get_param_types() const
04817                 {
04818                         TypeDict d;
04819                         return d;
04820                 }
04821 
04822                 virtual string get_desc() const
04823                 {
04824                         return "Get the transpose of an image. Works for 2D only";
04825                 }
04826 
04827                 static const string NAME;
04828         };
04829 
04830 
04834         class FlipProcessor:public Processor
04835         {
04836           public:
04837                 virtual void process_inplace(EMData * image);
04838 
04839                 virtual string get_name() const
04840                 {
04841                         return NAME;
04842                 }
04843 
04844                 static Processor *NEW()
04845                 {
04846                         return new FlipProcessor();
04847                 }
04848 
04849                 virtual TypeDict get_param_types() const
04850                 {
04851                         TypeDict d;
04852                         d.put("axis", EMObject::STRING, "'x', 'y', or 'z' axis.");
04853                         return d;
04854                 }
04855 
04856                 virtual string get_desc() const
04857                 {
04858                         return "Mirrors an image along the specified axis, preserving the center. This will introduce a plane of 0's for even box sizes. Use 'xform.mirror' processor to avoid the zero plane, but not preserve the center.";
04859                 }
04860 
04861                 static const string NAME;
04862         };
04863 
04864         /*class FlipProcessor1:public Processor
04865         {
04866           public:
04867                 void process_inplace(EMData * image);
04868 
04869                 string get_name() const
04870                 {
04871                         return "xform.flip1";
04872                 }
04873 
04874                 static Processor *NEW()
04875                 {
04876                         return new FlipProcessor1();
04877                 }
04878 
04879                 TypeDict get_param_types() const
04880                 {
04881                         TypeDict d;
04882                         d.put("axis", EMObject::STRING, "'x', 'y', or 'z' axis. 'x' means horizonal flip; 'y' means vertical flip;");
04883                         return d;
04884                 }
04885 
04886                 string get_desc() const
04887                 {
04888                         return "flip an image around an axis.";
04889                 }
04890 
04891         };*/
04892 
04897         class AddNoiseProcessor:public Processor
04898         {
04899           public:
04900                 virtual void process_inplace(EMData * image);
04901 
04902                 virtual string get_name() const
04903                 {
04904                         return NAME;
04905                 }
04906 
04907                 static Processor *NEW()
04908                 {
04909                         return new AddNoiseProcessor();
04910                 }
04911 
04912                 virtual TypeDict get_param_types() const
04913                 {
04914                         TypeDict d;
04915                         d.put("noise", EMObject::FLOAT, "noise factor used to generate Gaussian distribution random noise");
04916                         d.put("seed", EMObject::INT, "seed for random number generator");
04917                         return d;
04918                 }
04919 
04920                 virtual string get_desc() const
04921                 {
04922                         return "add noise to an image, image multiply by noise then add a random value";
04923                 }
04924 
04925                 static const string NAME;
04926 
04927           protected:
04928                 virtual float get_sigma(EMData *)
04929                 {
04930                         return 1.0;
04931                 }
04932         };
04933 
04936         class AddSigmaNoiseProcessor:public AddNoiseProcessor
04937         {
04938           public:
04939                 virtual string get_name() const
04940                 {
04941                         return NAME;
04942                 }
04943 
04944                 static Processor *NEW()
04945                 {
04946                         return new AddSigmaNoiseProcessor();
04947                 }
04948 
04949                 virtual string get_desc() const
04950                 {
04951                         return "add sigma noise.";
04952                 }
04953 
04954                 static const string NAME;
04955 
04956           protected:
04957                 float get_sigma(EMData * image);
04958         };
04959 
04968         class AddRandomNoiseProcessor:public Processor
04969         {
04970           public:
04971                 virtual void process_inplace(EMData * image);
04972 
04973                 virtual string get_name() const
04974                 {
04975                         return NAME;
04976                 }
04977 
04978                 static Processor *NEW()
04979                 {
04980                         return new AddRandomNoiseProcessor();
04981                 }
04982 
04983                 virtual TypeDict get_param_types() const
04984                 {
04985                         TypeDict d;
04986                         d.put("n", EMObject::INT);
04987                         d.put("x0", EMObject::FLOAT);
04988                         d.put("dx", EMObject::FLOAT);
04989                         d.put("y", EMObject::FLOATARRAY);
04990                         d.put("interpolation", EMObject::INT);
04991                         d.put("seed", EMObject::INT, "seed for random number generator");
04992                         return d;
04993                 }
04994 
04995                 virtual string get_desc() const
04996                 {
04997                         return "add spectral noise to a complex image.";
04998                 }
04999 
05000                 static const string NAME;
05001         };
05002 
05008         class FourierToCornerProcessor:public Processor
05009         {
05010                 public:
05016                         virtual void process_inplace(EMData * image);
05017 
05018                         virtual string get_name() const
05019                         {
05020                                 return NAME;
05021                         }
05022 
05023                         static Processor *NEW()
05024                         {
05025                                 return new FourierToCornerProcessor();
05026                         }
05027 
05028                         virtual string get_desc() const
05029                         {
05030                                 return "Undoes the xform.fourierorigin.tocenter processor";
05031                         }
05032 
05033                         static const string NAME;
05034         };
05035 
05036 
05048         class FourierToCenterProcessor:public Processor
05049         {
05050                 public:
05056                         virtual void process_inplace(EMData * image);
05057 
05058                         virtual string get_name() const
05059                         {
05060                                 return NAME;
05061                         }
05062 
05063                         static Processor *NEW()
05064                         {
05065                                 return new FourierToCenterProcessor();
05066                         }
05067 
05068                         virtual string get_desc() const
05069                         {
05070                                 return "Translates the origin in Fourier space from the corner to the center in y and z - works in 2D and 3D";
05071                         }
05072 
05073                         static const string NAME;
05074         };
05075 
05085         class Phase180Processor:public Processor
05086         {
05087                 protected:
05100                         void swap_corners_180(EMData * image);
05101 
05113                         void swap_central_slices_180(EMData * image);
05114 
05121                         void fourier_phaseshift180(EMData * image);
05122 
05123         };
05124 
05134         class PhaseToCenterProcessor:public Phase180Processor
05135         {
05136                 public:
05137                         virtual void process_inplace(EMData * image);
05138 
05139                         virtual string get_name() const
05140                         {
05141                                 return NAME;
05142                         }
05143 
05144                         static Processor *NEW()
05145                         {
05146                                 return new PhaseToCenterProcessor();
05147                         }
05148 
05149                         virtual string get_desc() const
05150                         {
05151                                 return "Undoes the effect of the xform.phaseorigin.tocorner processor";
05152                         }
05153 
05154                         static const string NAME;
05155         };
05156 
05164         class PhaseToCornerProcessor:public Phase180Processor
05165         {
05166                 public:
05167                         virtual void process_inplace(EMData * image);
05168 
05169                         virtual string get_name() const
05170                         {
05171                                 return NAME;
05172                         }
05173 
05174                         static Processor *NEW()
05175                         {
05176                                 return new PhaseToCornerProcessor();
05177                         }
05178 
05179                         virtual string get_desc() const
05180                         {
05181                                 return "Translates a centered image to the corner in a forward fashion";
05182                         }
05183 
05184                         static const string NAME;
05185         };
05186 
05191         class AutoMask2DProcessor:public Processor
05192         {
05193           public:
05194                 virtual void process_inplace(EMData * image);
05195 
05196                 virtual string get_name() const
05197                 {
05198                         return NAME;
05199                 }
05200 
05201                 static Processor *NEW()
05202                 {
05203                         return new AutoMask2DProcessor();
05204                 }
05205 
05206                 virtual TypeDict get_param_types() const
05207                 {
05208                         TypeDict d;
05209                         d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
05210                         d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
05211                         d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
05212                         d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
05213                         d.put("nshells", EMObject::INT, "The number of dilation operations");
05214                         d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
05215                         d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
05216                         d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
05217                         return d;
05218                 }
05219 
05220                 virtual string get_desc() const
05221                 {
05222                         return "2D version of mask.auto3d";
05223                 }
05224 
05225                 static const string NAME;
05226         };
05227 
05228 
05235         class AutoMaskAsymUnit:public Processor
05236         {
05237                 public:
05238                         virtual void process_inplace(EMData * image);
05239 
05240                         virtual string get_name() const
05241                         {
05242                                 return NAME;
05243                         }
05244 
05245                         static Processor *NEW()
05246                         {
05247                                 return new AutoMaskAsymUnit();
05248                         }
05249 
05250                         virtual TypeDict get_param_types() const
05251                         {
05252                                 TypeDict d;
05253                                 d.put("au", EMObject::INT, "The asymmetric unit to mask out. If this is -1 will mask all asymmetric units, giving each a unique number.");
05254                                 d.put("sym", EMObject::STRING, "The symmetry, for example, d7");
05255                                 return d;
05256                         }
05257 
05258                         virtual string get_desc() const
05259                         {
05260                                 return "Masks out a specific asymmetric unit of the given symmetry. If the au parameter is -1 will mask all asymmetric units, assigning the asymetric unit number to the masked area.";
05261                         }
05262 
05263                         static const string NAME;
05264         };
05265 
05270         class AutoMaskDustProcessor:public Processor
05271         {
05272           public:
05273                 virtual void process_inplace(EMData * image);
05274 
05275                 virtual string get_name() const
05276                 {
05277                         return NAME;
05278                 }
05279 
05280                 static Processor *NEW()
05281                 {
05282                         return new AutoMaskDustProcessor();
05283                 }
05284 
05285                 virtual TypeDict get_param_types() const
05286                 {
05287                         TypeDict d;
05288                         d.put("threshold", EMObject::FLOAT,"Only considers densities above the threshold");
05289                         d.put("voxels", EMObject::INT,"If a connected mass is smaller than this many voxels it is removed");
05290                         d.put("verbose", EMObject::INT, "Level of verbosity, 0 default. 1 will print each non-excluded zone");
05291                         return d;
05292                 }
05293 
05294                 virtual string get_desc() const
05295                 {
05296                         return "A dust removal filter which will remove above threshold densities smaller than a given size";
05297                 }
05298 
05299                 static const string NAME;
05300 
05301                 protected:
05302                 EMData *mask;
05303                 EMData *image;
05304         };
05305 
05310         class AutoMask3DProcessor:public Processor
05311         {
05312           public:
05313                 virtual void process_inplace(EMData * image);
05314 
05315                 virtual string get_name() const
05316                 {
05317                         return NAME;
05318                 }
05319 
05320                 static Processor *NEW()
05321                 {
05322                         return new AutoMask3DProcessor();
05323                 }
05324 
05325                 virtual TypeDict get_param_types() const
05326                 {
05327                         TypeDict d;
05328                         d.put("threshold1", EMObject::FLOAT);
05329                         d.put("threshold2", EMObject::FLOAT);
05330                         return d;
05331                 }
05332 
05333                 virtual string get_desc() const
05334                 {
05335                         return "Tries to mask out only interesting density";
05336                 }
05337 
05338                 static void search_nearby(float *dat, float *dat2, int nx, int ny, int nz, float thr);
05339                 static void fill_nearby(float *dat2, int nx, int ny, int nz);
05340 
05341                 static const string NAME;
05342         };
05343 
05351         class AutoMask3D2Processor:public Processor
05352         {
05353           public:
05354                 virtual void process_inplace(EMData * image);
05355 
05356                 virtual string get_name() const
05357                 {
05358                         return NAME;
05359                 }
05360 
05361                 static Processor *NEW()
05362                 {
05363                         return new AutoMask3D2Processor();
05364                 }
05365 
05366                 virtual string get_desc() const
05367                 {
05368                         return "This will mask a 3-D volume using a 'flood filling' approach. It begins with a seed generated either as a sphere with \
05369 specified 'radius' or with the 'nmaxseed' highest values. It then includes any mass connected to the seed with value higher than 'threshold'.\
05370 Next, the mask is expanded by 'nshells'+'nshellsgauss'/2 voxels. Finally a gaussian low-pass filter is applied with a width of 'nshellsgauss'.";
05371                 }
05372 
05373                 virtual TypeDict get_param_types() const
05374                 {
05375                         TypeDict d;
05376                         d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
05377                         d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
05378                         d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
05379                         d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
05380                         d.put("nshells", EMObject::INT, "Number of 1-voxel shells to expand the mask by.");
05381                         d.put("nshellsgauss", EMObject::INT, "Width in voxels of a Gaussian decay at the edge of the mask.");
05382                         d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
05383                         d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
05384                         return d;
05385                 }
05386 
05387                 static const string NAME;
05388         };
05389 
05393         class IterMultiMaskProcessor:public Processor
05394         {
05395           public:
05396                 virtual void process_inplace(EMData * image);
05397 
05398                 virtual string get_name() const
05399                 {
05400                         return NAME;
05401                 }
05402 
05403                 virtual string get_desc() const
05404                 {
05405                         return "A multilevel mask has an integer value at each pixel location. -1 indicates unmasked regions. 0-n-1 are individual masks. Expands the masked regions into unmasked areas by nshells.";
05406                 }
05407 
05408                 static Processor *NEW()
05409                 {
05410                         return new IterMultiMaskProcessor();
05411                 }
05412 
05413                 virtual TypeDict get_param_types() const
05414                 {
05415                         TypeDict d;
05416                         d.put("nshells", EMObject::INT, "number of shells to add");
05417                         return d;
05418                 }
05419 
05420                 static const string NAME;
05421         };
05422 
05423 
05427         class AddMaskShellProcessor:public Processor
05428         {
05429           public:
05430                 virtual void process_inplace(EMData * image);
05431 
05432                 virtual string get_name() const
05433                 {
05434                         return NAME;
05435                 }
05436 
05437                 virtual string get_desc() const
05438                 {
05439                         return "Add additional shells/rings to an existing 1/0 mask image";
05440                 }
05441 
05442                 static Processor *NEW()
05443                 {
05444                         return new AddMaskShellProcessor();
05445                 }
05446 
05447                 virtual TypeDict get_param_types() const
05448                 {
05449                         TypeDict d;
05450                         d.put("nshells", EMObject::INT, "number of shells to add");
05451                         return d;
05452                 }
05453 
05454                 static const string NAME;
05455         };
05456 
05461         class PhaseToMassCenterProcessor:public Processor
05462         {
05463                 public:
05464                         virtual void process_inplace(EMData * image);
05465 
05466                         virtual string get_name() const
05467                         {
05468                                 return NAME;
05469                         }
05470 
05471                         static Processor *NEW()
05472                         {
05473                                 return new PhaseToMassCenterProcessor();
05474                         }
05475 
05476                         virtual string get_desc() const
05477                         {
05478                                 return "centers the image the center of mass, which is calculated using Fourier phases, ignores old dx, dy.";
05479                         }
05480 
05481                         virtual TypeDict get_param_types() const
05482                         {
05483                                 TypeDict d;
05484                                 d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05485                                 return d;
05486                         }
05487 
05488                         static const string NAME;
05489         };
05490 
05495         class ToMassCenterProcessor:public Processor
05496         {
05497           public:
05498                 virtual void process_inplace(EMData * image);
05499 
05500                 virtual string get_name() const
05501                 {
05502                         return NAME;
05503                 }
05504 
05505                 static Processor *NEW()
05506                 {
05507                         return new ToMassCenterProcessor();
05508                 }
05509 
05510                 virtual string get_desc() const
05511                 {
05512                         return "ToMassCenterProcessor centers image at center of mass, with a threshold. Only values higher than the threshold are considered.";
05513                 }
05514 
05515                 virtual TypeDict get_param_types() const
05516                 {
05517                         TypeDict d;
05518                         d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05519                         d.put("threshold", EMObject::FLOAT, "Only values larger than the threshold are included in the center of mass computation. Default is 0.");
05520 //                      d.put("positive", EMObject::INT, "uses only densities >0 for the calculatton");
05521                         return d;
05522                 }
05523 
05524                 static const string NAME;
05525         };
05526 
05530         class ACFCenterProcessor:public Processor
05531         {
05532           public:
05533                 virtual void process_inplace(EMData * image);
05534 
05535                 virtual string get_name() const
05536                 {
05537                         return NAME;
05538                 }
05539 
05540                 static Processor *NEW()
05541                 {
05542                         return new ACFCenterProcessor();
05543                 }
05544 
05545                 virtual string get_desc() const
05546                 {
05547                         return "Center image using self-convolution.";
05548                 }
05549 
05550                 virtual TypeDict get_param_types() const
05551                 {
05552                         TypeDict d;
05553                         return d;
05554                 }
05555 
05556                 static const string NAME;
05557         };
05558 
05559 
05566         class FSCFourierProcessor:public Processor
05567         {
05568           public:
05569                 virtual EMData* process(EMData const *image);
05570                 virtual void process_inplace(EMData *image);
05571 
05572                 virtual string get_name() const
05573                 {
05574                         return NAME;
05575                 }
05576 
05577                 static Processor *NEW()
05578                 {
05579                         return new FSCFourierProcessor();
05580                 }
05581 
05582                 virtual string get_desc() const
05583                 {
05584                         return "This processor will apply a Wiener filter to a volume based on a provided FSC curve. The assumption is that the FSC curve represents \
05585 a gold standard FSC between two 1/2 sets, and that the filter is being applied to the combined average. Hence the default fscmult of 2, \
05586 since the SSNR is being computed as FSC/(1-FSC). Ie - the SSNR of the combined halves is twice as high.";
05587                 }
05588 
05589                 virtual TypeDict get_param_types() const
05590                 {
05591                         TypeDict d;
05592                         d.put("snrmult", EMObject::FLOAT, "This multiplier is applied to the computed SNR before Wiener filtration. This permits the filter to be applied to 1/2 images, etc. Default=2.0");
05593                         d.put("sscale", EMObject::FLOAT, "This rescales the S axis to produce empirical under/overfiltration. sscale=1.1 for example will extend the resolution (underfilter) by 10%. Default=1.0");
05594                         d.put("maxfreq", EMObject::FLOAT, "This acts as a high resolution limit to prevent FSC artifacts from iteratively reinforcing themselves. Above this spatial frequency, the FSC is forced to decrease monotonically. Default=1.0");
05595                         d.put("fscfile", EMObject::STRING, "filename of a file containing the FSC curve to use for the SNR computation");
05596                         return d;
05597                 }
05598 
05599                 static const string NAME;
05600         };
05601 
05602 
05607         class SNRProcessor:public Processor
05608         {
05609           public:
05610                 virtual void process_inplace(EMData * image);
05611 
05612                 virtual string get_name() const
05613                 {
05614                         return NAME;
05615                 }
05616 
05617                 static Processor *NEW()
05618                 {
05619                         return new SNRProcessor();
05620                 }
05621 
05622                 virtual string get_desc() const
05623                 {
05624                         return "Processor the images by the estimated SNR in each image.if parameter 'wiener' is 1, then wiener processor the images using the estimated SNR with CTF amplitude correction.";
05625                 }
05626 
05627                 virtual TypeDict get_param_types() const
05628                 {
05629                         TypeDict d;
05630                         d.put("wiener", EMObject::INT, "if set to 1,  then use wiener processor to process the images using the estimated SNR with CTF amplitude correction");
05631                         d.put("snrfile", EMObject::STRING, "structure factor file name");
05632                         return d;
05633                 }
05634 
05635                 static const string NAME;
05636         };
05637 
05641         class FileFourierProcessor:public Processor
05642         {
05643           public:
05644                 virtual void process_inplace(EMData * image);
05645 
05646                 virtual string get_name() const
05647                 {
05648                         return NAME;
05649                 }
05650 
05651                 virtual string get_desc() const
05652                 {
05653                         return "A fourier processor specified in a 2 column text file.";
05654                 }
05655 
05656                 static Processor *NEW()
05657                 {
05658                         return new FileFourierProcessor();
05659                 }
05660 
05661                 virtual TypeDict get_param_types() const
05662                 {
05663                         TypeDict d;
05664                         d.put("filename", EMObject::STRING, "file name for a 2 column text file which specified a radial function data array.");
05665                         return d;
05666                 }
05667 
05668                 static const string NAME;
05669         };
05670 
05681         class SymSearchProcessor:public Processor
05682         {
05683           public:
05684                 virtual void process_inplace(EMData * image);
05685 
05686                 virtual string get_name() const
05687                 {
05688                         return NAME;
05689                 }
05690 
05691                 virtual string get_desc() const
05692                 {
05693                         return "Identifiy the best symmetry in the given symmetry list for each pixel and then apply the best symmetry to each pixel.";
05694                 }
05695 
05696                 static Processor *NEW()
05697                 {
05698                         return new SymSearchProcessor();
05699                 }
05700 
05701                 virtual TypeDict get_param_types() const
05702                 {
05703                         TypeDict d;
05704                         d.put("sym", EMObject::STRINGARRAY, "the list of symmetries to search");
05705                         d.put("thresh", EMObject::FLOAT, "the minimal level of symmetry to be accepted (0-1)");
05706                         d.put("output_symlabel", EMObject::INT, "if output the symmetry label map in which the pixel value is the index of symmetry in the symmetry list");
05707                         d.put("symlabel_map", EMObject::EMDATA, "the optional return map when output_symlabel=1");
05708                         return d;
05709                 }
05710 
05711                 static const string NAME;
05712         };
05713 
05719         class StripeXYProcessor:public Processor
05720         {
05721           public:
05722                 void process_inplace(EMData * image);
05723 
05724                 virtual string get_name() const
05725                 {
05726                         return NAME;
05727                 }
05728 
05729                 static Processor *NEW()
05730                 {
05731                         return new StripeXYProcessor();
05732                 }
05733 
05734                 virtual string get_desc() const
05735                 {
05736                         return "This processor will remove localized 'striping' along the x/y axes, caused by issues with CCD/CMOS readout. In theory this should be done by dark/gain correction, but in many cases, there are residual effects that this will help eliminate. This can produce high-pass filter-like effects, so generally large length values are suggested. Integration covers +-xlen/ylen. Y and X axes are corrected sequentially, not simultaneously, Y first";
05737                 }
05738 
05739                 virtual TypeDict get_param_types() const
05740                 {
05741                         TypeDict d;
05742                         d.put("xlen", EMObject::INT, "Integration 1/2 length on x axis in pixels. Default=10");
05743                         d.put("ylen", EMObject::INT, "Integration 1/2 length on y axis in pixels. Default=10");
05744                         return d;
05745                 }
05746 
05747                 static const string NAME;
05748         };
05749 
05750 
05756         class LocalNormProcessor:public Processor
05757         {
05758           public:
05759                 void process_inplace(EMData * image);
05760 
05761                 virtual string get_name() const
05762                 {
05763                         return NAME;
05764                 }
05765 
05766                 static Processor *NEW()
05767                 {
05768                         return new LocalNormProcessor();
05769                 }
05770 
05771                 virtual string get_desc() const
05772                 {
05773                         return "This processor attempts to perform a 'local normalization' so low density and high density features will be on a more even playing field in an isosurface display. threshold is an isosurface threshold at which all desired features are visible, radius is a feature size over which to equalize.";
05774                 }
05775 
05776                 virtual TypeDict get_param_types() const
05777                 {
05778                         TypeDict d;
05779                         d.put("threshold", EMObject::FLOAT, "Only values above the threshold will be used to compute the normalization. Generally a good isosurface value.");
05780                         d.put("radius", EMObject::FLOAT, "Fourier filter radius expressed in pixels in Fourier space. cutoff_pixels in filter.lowpass.gauss");
05781                         d.put("apix", EMObject::FLOAT, "Angstroms per pixel");
05782                         return d;
05783                 }
05784 
05785                 static const string NAME;
05786         };
05787 
05792         class IndexMaskFileProcessor:public Processor
05793         {
05794           public:
05795                 virtual void process_inplace(EMData * image);
05796 
05797                 virtual string get_name() const
05798                 {
05799                         return NAME;
05800                 }
05801 
05802                 static Processor *NEW()
05803                 {
05804                         return new IndexMaskFileProcessor();
05805                 }
05806 
05807                 virtual TypeDict get_param_types() const
05808                 {
05809                         TypeDict d;
05810                         d.put("filename", EMObject::STRING, "mask image file name");
05811                         d.put("ismaskset", EMObject::INT, "If set to 1, it will take a file containing a set of masks and apply the first mask to the image");
05812                         return d;
05813                 }
05814 
05815                 virtual string get_desc() const
05816                 {
05817                         return "Multiplies the image by the specified file using pixel indices. The images must be same size. If 'ismaskset=' is 1, it will take a file containing a set of masks and apply the first mask to the image.";
05818                 }
05819 
05820                 static const string NAME;
05821         };
05822 
05826         class CoordinateMaskFileProcessor:public Processor
05827         {
05828           public:
05829                 virtual void process_inplace(EMData * image);
05830 
05831                 virtual string get_name() const
05832                 {
05833                         return NAME;
05834                 }
05835 
05836                 static Processor *NEW()
05837                 {
05838                         return new CoordinateMaskFileProcessor();
05839                 }
05840 
05841                 virtual string get_desc() const
05842                 {
05843                         return "Multiplies the image by the specified file using pixel coordinates instead of pixel indices. The images can be different size.";
05844                 }
05845 
05846                 virtual TypeDict get_param_types() const
05847                 {
05848                         TypeDict d;
05849                         d.put("filename", EMObject::STRING, "mask image file name");
05850                         return d;
05851                 }
05852 
05853                 static const string NAME;
05854         };
05855 
05866         class PaintProcessor:public Processor
05867         {
05868           public:
05869                 PaintProcessor():x(0), y(0), z(0),r1(0), v1(0.0), r2(0), v2(0.0)
05870                 {
05871                 }
05872 
05873                 virtual string get_name() const
05874                 {
05875                         return NAME;
05876                 }
05877 
05878                 static Processor *NEW()
05879                 {
05880                         return new PaintProcessor();
05881                 }
05882 
05883                 virtual string get_desc() const
05884                 {
05885                         return "Paints a circle with a decaying edge into the image. r<r1 -> v1, r1<r<r2 -> (v1,v2), r>r2 unchanged";
05886                 }
05887 
05888                 virtual TypeDict get_param_types() const
05889                 {
05890                         TypeDict d;
05891                         d.put("x", EMObject::INT, "x coordinate for Center of circle");
05892                         d.put("y", EMObject::INT, "y coordinate for Center of circle");
05893                         d.put("z", EMObject::INT, "z coordinate for Center of circle");
05894                         d.put("r1", EMObject::INT, "Inner radius");
05895                         d.put("v1", EMObject::FLOAT, "Inner value");
05896                         d.put("r2", EMObject::INT, "Outter radius");
05897                         d.put("v2", EMObject::FLOAT, "Outer Value");
05898                         return d;
05899                 }
05900 
05901                 virtual void set_params(const Dict & new_params)
05902                 {
05903                         params = new_params;
05904 
05905                         if (params.has_key("x")) x = params["x"];
05906                         if (params.has_key("y")) y = params["y"];
05907                         if (params.has_key("z")) z = params["z"];
05908                         if (params.has_key("r1")) r1 = params["r1"];
05909                         if (params.has_key("r2")) r2 = params["r2"];
05910                         if (params.has_key("v1")) v1 = params["v1"];
05911                         if (params.has_key("v2")) v2 = params["v2"];
05912                 }
05913 
05914                 static const string NAME;
05915 
05916                 protected:
05917                 virtual void process_inplace(EMData *image);
05918 
05919                 int x,y,z,r1;
05920                 float v1;
05921                 int r2;
05922                 float v2;
05923 
05924         };
05925 
05926 
05931         class DirectionalSumProcessor : public Processor
05932         {
05933           public:
05934                 virtual string get_name() const
05935                 {
05936                         return NAME;
05937                 }
05938 
05939                 static Processor *NEW()
05940                 {
05941                         return new DirectionalSumProcessor();
05942                 }
05943 
05947                 virtual EMData* process(const EMData* const image);
05948 
05952                 virtual void process_inplace(EMData*) {
05953                         throw InvalidCallException("The directional sum processor does not work inplace");
05954                 }
05955 
05956                 virtual TypeDict get_param_types() const
05957                 {
05958                         TypeDict d;
05959                         d.put("axis", EMObject::STRING,"The direction of the sum, either x,y or z. Returned axes are xy, xz or zy.");
05960                         d.put("first", EMObject::INT,"The first position along the speficied axis to use in the sum. Neg val -> nx/y/z+first (default=0)");
05961                         d.put("last", EMObject::INT,"The last position along the speficied axis to use in the sum. Neg val -> nx/y/z+last (default=-1)");
05962                         return d;
05963                 }
05964 
05965                 string get_desc() const
05966                 {
05967                         return "Calculates the projection of the image along one of the axial directions, either x, y or z";
05968                 }
05969 
05970                 static const string NAME;
05971         };
05972 
05980         class WatershedProcessor:public Processor
05981         {
05982           public:
05983                 virtual EMData* process(const EMData* const image);
05984                 virtual void process_inplace(EMData*);
05985 
05986                 virtual string get_name() const
05987                 {
05988                         return NAME;
05989                 }
05990 
05991                 static Processor *NEW()
05992                 {
05993                         return new WatershedProcessor();
05994                 }
05995 
05996                 virtual string get_desc() const
05997                 {
05998                         return "Watershed segmentation. Warning: uses up to 2.5x the map size in RAM. This will segment all voxels above threshold except for a 1-voxel wide border on all edges.";
05999                 }
06000 
06001                 virtual TypeDict get_param_types() const
06002                 {
06003                         TypeDict d;
06004                         d.put("nseg", EMObject::INT, "Number of segments to (attempt) to produce. The actual number may be fewer. (default=12)" );
06005                         d.put("thr",EMObject::FLOAT,"Isosurface threshold value. Pixels below this value will not be segmented. All voxels above this value will be segmented. (default=0.5)");
06006                         d.put("segbymerge", EMObject::INT, "If set, will achieve the specified number of segments by progressively merging the most connected segments. Can produce very different results." );
06007                         d.put("verbose", EMObject::INT, "If set, will print console output while running" );
06008                         return d;
06009                 }
06010 
06011                 static const string NAME;
06012 
06013 //        private:
06014 
06015         };
06016 
06026         template<class Type>
06027         class BinaryOperateProcessor : public Processor{
06028                 public:
06033                         virtual void process_inplace(EMData * image) {
06034                                 if ( ! params.has_key("with") ) throw InvalidParameterException("You must supply the \"with\" parameter");
06035                                 EMData* with = params["with"];
06036 
06037                                 if ( with->get_xsize() != image->get_xsize() || with->get_ysize() != image->get_ysize() || with->get_zsize() != image->get_zsize() )
06038                                         throw ImageDimensionException("The images you are operating on do not have the same dimensions");
06039 
06040                                 float* image_data = image->get_data();
06041                                 float* with_data = with->get_data();
06042 
06043                                 std::transform(image_data,image_data+image->get_size(),with_data,image_data,Type::binary_operate);
06044                                 image->update();
06045                         }
06046 
06047                         virtual string get_name() const
06048                         {
06049                                 return op.get_name();
06050                         }
06051 
06052                         virtual string get_desc() const
06053                         {
06054                                 return op.get_desc();
06055                         }
06056 
06057                         static Processor *NEW()
06058                         {
06059                                 return new BinaryOperateProcessor<Type>();
06060                         }
06061 
06062                         virtual TypeDict get_param_types() const
06063                         {
06064                                 TypeDict d;
06065                                 d.put("with", EMObject::EMDATA,"The second image");
06066                                 return d;
06067                         }
06068 
06069                         static const string NAME;
06070                 private:
06071                         Type op;
06072         };
06073 
06074         class MaxPixelOperator {
06075                 public:
06076                 string get_name() const
06077                 {
06078                         return NAME;
06079                 }
06080 
06081                 string get_desc() const
06082                 {
06083                         return "Compares pixels in two images, returning an image with the maximum pixel value in each pixel location";
06084                 }
06085 
06086                 static float binary_operate(const float& left, const float& right) {
06087                         if (left > right) return left;
06088                         return right;
06089                 }
06090 
06091                 static const string NAME;
06092         };
06093 
06094         class MinPixelOperator {
06095                 public:
06096                         string get_name() const
06097                         {
06098                                 return NAME;
06099                         }
06100 
06101                         string get_desc() const
06102                         {
06103                                 return "Compares pixels in two images, returning an image with the minimum pixel value in each pixel location";
06104                         }
06105 
06106                         static float binary_operate(const float& left, const float& right) {
06107                                 if (left < right) return left;
06108                                 return right;
06109                         }
06110 
06111                         static const string NAME;
06112         };
06113 
06117         class MatchSFProcessor:public FourierAnlProcessor
06118         {
06119           public:
06120 
06121                 virtual string get_name() const
06122                 {
06123                         return NAME;
06124                 }
06125 
06126                 virtual string get_desc() const
06127                 {
06128                         return "Filters the image so its 1-D power spectrum matches a second image";
06129                 }
06130 
06131                 static Processor *NEW()
06132                 {
06133                         return new MatchSFProcessor();
06134                 }
06135 
06136                 virtual TypeDict get_param_types() const
06137                 {
06138                         TypeDict d;
06139                         d.put("to", EMObject::EMDATA, "The image to match with. Make sure apix values are correct.");
06140                         d.put("return_radial", EMObject::BOOL, "Return the radial filter function as an attribute (filter_curve)");
06141                         d.put("interpolate", EMObject::BOOL, "Whether or not to interpolate the radial scaling function. Default=false. Prb should be true.");
06142                         return d;
06143                 }
06144 
06145                 static const string NAME;
06146 
06147           protected:
06148                 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
06149         };
06150 
06151 
06156         class SetSFProcessor:public FourierAnlProcessor
06157         {
06158           public:
06159 
06160                 virtual string get_name() const
06161                 {
06162                         return NAME;
06163                 }
06164 
06165                 virtual string get_desc() const
06166                 {
06167                         return "Filters the image so its 1-D power spectrum matches a supplied S,Y curve. If the S axis does not extend to Nyquist, only a uniform scaling will be applied beyond the end of the supplied curve. ";
06168                 }
06169 
06170                 static Processor *NEW()
06171                 {
06172                         return new SetSFProcessor();
06173                 }
06174 
06175                 virtual TypeDict get_param_types() const
06176                 {
06177                         TypeDict d;
06178                         d.put("strucfac", EMObject::XYDATA, "An XYData object contaning the curve to be imposed as a function of S");
06179                         d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
06180                         return d;
06181                 }
06182 
06183                 static const string NAME;
06184 
06185           protected:
06186                 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
06187         };
06188 
06192         class SmartMaskProcessor:public Processor
06193         {
06194           public:
06195                 virtual void process_inplace(EMData * image);
06196 
06197                 virtual string get_name() const
06198                 {
06199                         return NAME;
06200                 }
06201 
06202                 static Processor *NEW()
06203                 {
06204                         return new SmartMaskProcessor();
06205                 }
06206 
06207                 virtual string get_desc() const
06208                 {
06209                         return "Smart mask processor.";
06210                 }
06211 
06212                 virtual TypeDict get_param_types() const
06213                 {
06214                         TypeDict d;
06215                         d.put("mask", EMObject::FLOAT, "mask value");
06216                         return d;
06217                 }
06218 
06219                 static const string NAME;
06220         };
06221 
06226         class IterBinMaskProcessor:public Processor
06227         {
06228           public:
06229                 virtual void process_inplace(EMData * image);
06230 
06231                 virtual string get_name() const
06232                 {
06233                         return NAME;
06234                 }
06235 
06236                 virtual string get_desc() const
06237                 {
06238                         return "Iterative expansion of a binary mask, val1 is number of pixels to expand, if val2!=0 will make a soft Gaussian edge starting after val2 pixels.";
06239                 }
06240 
06241                 static Processor *NEW()
06242                 {
06243                         return new IterBinMaskProcessor();
06244                 }
06245 
06246                 virtual TypeDict get_param_types() const
06247                 {
06248                         TypeDict d;
06249                         d.put("val1", EMObject::FLOAT, "number of pixels to expand");
06250                         d.put("val2", EMObject::FLOAT, "number of Gaussian pixels to expand, following the first expansion");
06251                         return d;
06252                 }
06253 
06254                 static const string NAME;
06255         };
06256 
06259         class TestImageProcessor : public Processor
06260         {
06261         public:
06262                 static string get_group_desc()
06263                 {
06264                         return "Base class for a group of 'processors' used to create test image.";
06265                 }
06266 
06267         protected:
06268                 void preprocess(EMData * image);
06269                 int nx, ny, nz; //this is the size of the source image
06270         };
06271 
06280         class TestImagePureGaussian : public TestImageProcessor
06281         {
06282         public:
06283                 virtual void process_inplace(EMData * image);
06284 
06285                 virtual string get_name() const
06286                 {
06287                         return NAME;
06288                 }
06289 
06290                 virtual string get_desc() const
06291                 {
06292                         return "Replace a source image as a strict Gaussian ";
06293                 }
06294 
06295                 static Processor * NEW()
06296                 {
06297                         return new TestImagePureGaussian();
06298                 }
06299 
06300                 virtual TypeDict get_param_types() const
06301                 {
06302                         TypeDict d;
06303                         d.put("x_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on x direction");
06304                         d.put("y_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on y direction");
06305                         d.put("z_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on z direction");
06306                         d.put("x_center", EMObject::FLOAT, "center for this Gaussian blob on x direction" );
06307                         d.put("y_center", EMObject::FLOAT, "center for this Gaussian blob on y direction" );
06308                         d.put("z_center", EMObject::FLOAT, "center for this Gaussian blob on z direction" );
06309                         return d;
06310                 }
06311 
06312                 static const string NAME;
06313         };
06314 
06318         class TestImageFourierNoiseGaussian : public TestImageProcessor
06319         {
06320         public:
06321                 virtual void process_inplace(EMData * image);
06322 
06323                 virtual string get_name() const
06324                 {
06325                         return NAME;
06326                 }
06327 
06328                 virtual string get_desc() const
06329                 {
06330                         return "Replace a source image with pink Fourier noise, based on a Gaussian. Random phase.";
06331                 }
06332 
06333                 static Processor * NEW()
06334                 {
06335                         return new TestImageFourierNoiseGaussian();
06336                 }
06337 
06338                 virtual TypeDict get_param_types() const
06339                 {
06340                         TypeDict d;
06341                         d.put("sigma", EMObject::FLOAT, "sigma value");
06342                         return d;
06343                 }
06344 
06345                 static const string NAME;
06346         };
06347 
06352         class TestImageFourierNoiseProfile : public TestImageProcessor
06353         {
06354         public:
06355                 virtual void process_inplace(EMData * image);
06356 
06357                 virtual string get_name() const
06358                 {
06359                         return NAME;
06360                 }
06361 
06362                 virtual string get_desc() const
06363                 {
06364                         return "Replace a source image with Fourier noise using amplitude information that is stored in a profile.";
06365                 }
06366 
06367                 static Processor * NEW()
06368                 {
06369                         return new TestImageFourierNoiseProfile();
06370                 }
06371 
06372                 virtual TypeDict get_param_types() const
06373                 {
06374                         TypeDict d;
06375                         d.put("profile", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
06376                         return d;
06377                 }
06378 
06379                 static const string NAME;
06380         };
06381 
06382 
06387         class CTFSNRWeightProcessor : public TestImageProcessor
06388         {
06389                 public:
06390                         virtual void process_inplace(EMData * image);
06391 
06392                         virtual string get_name() const
06393                         {
06394                                 return NAME;
06395                         }
06396 
06397                         virtual string get_desc() const
06398                         {
06399                                 return "Weight the amplitudes of an image based on radial noise and snr curves ";
06400                         }
06401 
06402                         static Processor * NEW()
06403                         {
06404                                 return new CTFSNRWeightProcessor();
06405                         }
06406 
06407                         virtual TypeDict get_param_types() const
06408                         {
06409                                 TypeDict d;
06410                                 d.put("noise", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
06411                                 d.put("snr", EMObject::FLOATARRAY, "Squared amplitude divided by squared noise amplitude. As in, what is the EMAN2CTF.snr attribute");
06412                                 d.put("boost", EMObject::FLOAT, "Multiplicative signal boost");
06413                                 return d;
06414                         }
06415 
06416                         static const string NAME;
06417         };
06418 
06419 
06420 
06425         class TestImageLineWave : public TestImageProcessor
06426         {
06427                 public:
06428                         virtual void process_inplace(EMData * image);
06429 
06430                         virtual string get_name() const
06431                         {
06432                                 return NAME;
06433                         }
06434 
06435                         virtual string get_desc() const
06436                         {
06437                                 return "Insert an oscillating sine wave into the pixel data";
06438                         }
06439 
06440                         static Processor * NEW()
06441                         {
06442                                 return new TestImageLineWave();
06443                         }
06444 
06445                         virtual TypeDict get_param_types() const
06446                         {
06447                                 TypeDict d;
06448                                 d.put("period", EMObject::FLOAT, "The period of the oscillating sine wave. Default 10.");
06449                                 return d;
06450                         }
06451 
06452                         static const string NAME;
06453         };
06454 
06455 
06463         class TestTomoImage : public TestImageProcessor
06464         {
06465                 public:
06469                         virtual void process_inplace(EMData * image);
06470 
06471                         virtual string get_name() const
06472                         {
06473                                 return NAME;
06474                         }
06475 
06476                         virtual string get_desc() const
06477                         {
06478                                 return "Make an image consisting various objects, useful for tomographic testing";
06479                         }
06480 
06481                         static Processor * NEW()
06482                         {
06483                                 return new TestTomoImage();
06484                         }
06485 
06486                         static const string NAME;
06487 
06488                 private:
06489                         void insert_solid_ellipse( EMData* image, const Region& region, const float& value, const Transform& t3d  = Transform() );
06490                         void insert_hollow_ellipse( EMData* image, const Region& region, const float& value, const int& radius, const Transform& t3d = Transform() );
06491                         void insert_rectangle( EMData* image, const Region& region, const float& value, const Transform& t3d = Transform() );
06492         };
06493 
06501         class TestImageGradient : public TestImageProcessor
06502         {
06503                 public:
06504                         virtual void process_inplace(EMData * image);
06505 
06506                         virtual string get_name() const
06507                         {
06508                                 return NAME;
06509                         }
06510 
06511                         virtual string get_desc() const
06512                         {
06513                                 return "Make a gradient image of the form y=mx+b, where x is any of the image axes.";
06514                         }
06515 
06516                         static Processor * NEW()
06517                         {
06518                                 return new TestImageGradient();
06519                         }
06520 
06521                         virtual TypeDict get_param_types() const
06522                         {
06523                                 TypeDict d;
06524                                 d.put("axis", EMObject::STRING, "The axis the will be used to determine pixel values. Must be x,y or z");
06525                                 d.put("m", EMObject::FLOAT, "m in the equation m*axis+b. Default is 1.0");
06526                                 d.put("b", EMObject::FLOAT, "b in the equation m*axis+b. Default is 0.0");
06527                                 return d;
06528                         }
06529 
06530                         static const string NAME;
06531         };
06532 
06540         class TestImageAxes : public TestImageProcessor
06541         {
06542                 public:
06547                         virtual void process_inplace(EMData * image);
06548 
06549                         virtual string get_name() const
06550                         {
06551                                 return NAME;
06552                         }
06553 
06554                         virtual string get_desc() const
06555                         {
06556                                 return "Make an image consisting of a single cross";
06557                         }
06558 
06559                         static Processor * NEW()
06560                         {
06561                                 return new TestImageAxes();
06562                         }
06563 
06564                         virtual TypeDict get_param_types() const
06565                         {
06566                                 TypeDict d;
06567                                 d.put("int", EMObject::FLOAT, "radius of the lines emanating from the origin");
06568                                 d.put("fill", EMObject::FLOAT, "value to make non-zero pixels");
06569                                 return d;
06570                         }
06571 
06572                         static const string NAME;
06573         };
06574 
06580         class TestImageGaussian : public TestImageProcessor
06581         {
06582         public:
06583                 virtual void process_inplace(EMData * image);
06584 
06585                 virtual string get_name() const
06586                 {
06587                         return NAME;
06588                 }
06589 
06590                 virtual string get_desc() const
06591                 {
06592                         return "Replace a source image as a Gaussian Blob";
06593                 }
06594 
06595                 static Processor * NEW()
06596                 {
06597                         return new TestImageGaussian();
06598                 }
06599 
06600                 virtual TypeDict get_param_types() const
06601                 {
06602                         TypeDict d;
06603                         d.put("sigma", EMObject::FLOAT, "sigma value for this Gaussian blob");
06604                         d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06605                         d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06606                         return d;
06607                 }
06608 
06609                 static const string NAME;
06610         };
06611 
06614         class TestImageScurve : public TestImageProcessor
06615         {
06616         public:
06617                 virtual void process_inplace(EMData * image);
06618 
06619                 virtual string get_name() const
06620                 {
06621                         return NAME;
06622                 }
06623 
06624                 virtual string get_desc() const
06625                 {
06626                         return "Replace a source image with a lumpy S-curve used for alignment testing";
06627                 }
06628 
06629                 static Processor * NEW()
06630                 {
06631                         return new TestImageScurve();
06632                 }
06633 
06634                 virtual TypeDict get_param_types() const
06635                 {
06636                         TypeDict d;
06637                         return d;
06638                 }
06639 
06640                 static const string NAME;
06641         };
06642 
06650         class TestImageSphericalWave : public TestImageProcessor
06651         {
06652         public:
06653                 virtual void process_inplace(EMData * image);
06654 
06655                 virtual string get_name() const
06656                 {
06657                         return NAME;
06658                 }
06659 
06660                 virtual string get_desc() const
06661                 {
06662                         return "Replace a source image in 2d or 3d with a spherical wave cos(2*pi*r/wavelength+phase) also 1/r (2d) or 1/r^2 (3d)";
06663                 }
06664 
06665                 static Processor * NEW()
06666                 {
06667                         return new TestImageSphericalWave();
06668                 }
06669 
06670                 virtual TypeDict get_param_types() const
06671                 {
06672                         TypeDict d;
06673                         d.put("wavelength", EMObject::FLOAT, "cos(2*pi*r/wavelength+phase)");
06674                         d.put("phase", EMObject::FLOAT, "in radians");
06675                         d.put("x", EMObject::FLOAT, "center of the spherical wave");
06676                         d.put("y", EMObject::FLOAT, "center of the spherical wave");
06677                         d.put("z", EMObject::FLOAT, "center of the spherical wave");
06678                         return d;
06679                 }
06680 
06681                 static const string NAME;
06682         };
06683 
06684 
06693         class TestImageSinewave : public TestImageProcessor
06694         {
06695         public:
06696                 virtual void process_inplace(EMData * image);
06697 
06698                 virtual string get_name() const
06699                 {
06700                         return NAME;
06701                 }
06702 
06703                 virtual string get_desc() const
06704                 {
06705                         return "Replace a source image as a sine wave in specified wave length";
06706                 }
06707 
06708                 static Processor * NEW()
06709                 {
06710                         return new TestImageSinewave();
06711                 }
06712 
06713                 virtual TypeDict get_param_types() const
06714                 {
06715                         TypeDict d;
06716                         d.put("wavelength", EMObject::FLOAT, "wavelength in equation sin(x*2*PI/wavelength - phase*180/PI)");
06717                         d.put("axis", EMObject::STRING, "(optional) specify a major axis for asymmetric features, default x axis");
06718                         d.put("phase", EMObject::FLOAT, "(optional) the phase in radians");
06719                         d.put("az", EMObject::FLOAT, "(optional) angle in degree. for 2D image, this is the rotated angle of the image, \
06720                                                                                                 in 3D image, it's az for euler angle. default is zero");
06721                         d.put("alt", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, alt for euler angle, default is zero");
06722                         d.put("phi", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, phi for euler angle, default is zero");
06723                         return d;
06724                 }
06725 
06726                 static const string NAME;
06727         };
06728 
06735         class TestImageSinewaveCircular : public TestImageProcessor
06736         {
06737         public:
06738                 virtual void process_inplace(EMData * image);
06739 
06740                 virtual string get_name() const
06741                 {
06742                         return NAME;
06743                 }
06744 
06745                 virtual string get_desc() const
06746                 {
06747                         return "Replace a source image as a circular sine wave in specified wave length";
06748                 }
06749 
06750                 static Processor * NEW()
06751                 {
06752                         return new TestImageSinewaveCircular();
06753                 }
06754 
06755                 virtual TypeDict get_param_types() const
06756                 {
06757                         TypeDict d;
06758                         d.put("wavelength", EMObject::FLOAT, "(required)this value is the d in function |sin(x/d)|, unit: pixel");
06759                         d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06760                         d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06761                         d.put("phase", EMObject::FLOAT, "(optional)phase for sine wave, default is 0");
06762                         return d;
06763                 }
06764 
06765                 static const string NAME;