Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

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                         return d;
00354                 }
00355 
00356           protected:
00357                   virtual void preprocess(EMData *image) {
00358                         if(params.has_key("apix")) {
00359                                 image->set_attr("apix_x", (float)params["apix"]);
00360                                 image->set_attr("apix_y", (float)params["apix"]);
00361                                 image->set_attr("apix_z", (float)params["apix"]);
00362                         }
00363 
00364                         const Dict dict = image->get_attr_dict();
00365                         if( params.has_key("sigma")) {
00366                                 params["cutoff_abs"] = (float)params["sigma"];
00367                         }
00368                         else if( params.has_key("cutoff_abs") ) {
00369                                 params["sigma"] = (float)params["cutoff_abs"];
00370                         }
00371                         else if( params.has_key("cutoff_freq") ) {
00372                                 float val =  (float)params["cutoff_freq"] * (float)dict["apix_x"];
00373                                 params["cutoff_abs"] = val;
00374                                 params["sigma"] = val;
00375                         }
00376                         else if( params.has_key("cutoff_pixels") ) {
00377                                 float val = (0.5f*(float)params["cutoff_pixels"] / (float)dict["nx"]);
00378                                 params["cutoff_abs"] = val;
00379                                 params["sigma"] = val;
00380                         }
00381 
00382                         }
00383                   virtual void create_radial_func(vector < float >&radial_mask) const = 0;
00384         };
00385 
00393         class FourierAnlProcessor:public Processor
00394         {
00395           public:
00396                 void process_inplace(EMData * image);
00397 
00398                 static string get_group_desc()
00399                 {
00400                         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]. ";
00401                 }
00402 
00403                 TypeDict get_param_types() const
00404                 {
00405                         TypeDict d;
00406                         d.put("cutoff_abs", EMObject::FLOAT, "Processor radius in terms of Nyquist (0-.5)");
00407                         d.put("cutoff_pixels", EMObject::FLOAT, " Width in Fourier pixels (0 - size()/2)");
00408                         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");
00409                         d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
00410                         return d;
00411                 }
00412 
00413           protected:
00414                   virtual void preprocess(EMData *) {}
00415                   virtual void create_radial_func(vector < float >&radial_mask,EMData *image) const = 0;
00416         };
00417 
00420         class SNREvalProcessor:public Processor
00421         {
00422                 public:
00423                 string get_name() const
00424                 {
00425                         return NAME;
00426                 }
00427 
00428                 void process_inplace(EMData * image);
00429 
00430                 void set_params(const Dict & new_params)
00431                 {
00432                         params = new_params;
00433 //                      sum = params["sum"];
00434 //                      dosqrt = params["sqrt"];
00435 //                      printf("%s %f\n",params.keys()[0].c_str(),lowpass);
00436                 }
00437 
00438                 TypeDict get_param_types() const
00439                 {
00440                         TypeDict d;
00441 //                      d.put("sum", EMObject::EMDATA, "Adds the weights to sum for normalization");
00442 //                      d.put("sqrt", EMObject::INT, "Weights using sqrt of the amplitude if set");
00443                         return d;
00444                 }
00445 
00446                 static Processor *NEW()
00447                 {
00448                         return new SNREvalProcessor();
00449                 }
00450 
00451                 string get_desc() const
00452                 {
00453                         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";
00454                 }
00455                 
00456                 static const string NAME;
00457 
00458                 protected:
00459                 EMData *sum;
00460                 int dosqrt;
00461         };
00462 
00463 
00468         class AmpweightFourierProcessor: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                         sum = params["sum"];
00482                         dosqrt = params["sqrt"];
00483 //                      printf("%s %f\n",params.keys()[0].c_str(),lowpass);
00484                 }
00485 
00486                 TypeDict get_param_types() const
00487                 {
00488                         TypeDict d;
00489                         d.put("sum", EMObject::EMDATA, "Adds the weights to sum for normalization");
00490                         d.put("sqrt", EMObject::INT, "Weights using sqrt of the amplitude if set");
00491                         return d;
00492                 }
00493 
00494                 static Processor *NEW()
00495                 {
00496                         return new AmpweightFourierProcessor();
00497                 }
00498 
00499                 string get_desc() const
00500                 {
00501                         return "Multiplies each Fourier pixel by its amplitude";
00502                 }
00503 
00504                 static const string NAME;
00505 
00506                 protected:
00507                 EMData *sum;
00508                 int dosqrt;
00509         };
00516         class ConvolutionProcessor : public Processor
00517         {
00518                 public:
00519                         ConvolutionProcessor() {}
00520 
00521                         string get_name() const
00522                         {
00523                                 return NAME;
00524                         }
00525 
00526                         void process_inplace(EMData *image);
00527 
00528                         static Processor *NEW()
00529                         {
00530                                 return new ConvolutionProcessor();
00531                         }
00532 
00533                         string get_desc() const
00534                         {
00535                                 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.";
00536                         }
00537 
00538                         TypeDict get_param_types() const
00539                         {
00540                                 TypeDict d;
00541                                 d.put("with", EMObject::EMDATA, "The image that will convolute the other image");
00542                                 return d;
00543                         }
00544 
00545                         static const string NAME;
00546         };
00547 
00554         class XGradientProcessor : public Processor
00555         {
00556          public:
00557                 XGradientProcessor() {}
00558 
00559                 string get_name() const
00560                 {
00561                         return NAME;
00562                 }
00563 
00564                 void process_inplace(EMData *image);
00565 
00566                 static Processor *NEW()
00567                 {
00568                         return new XGradientProcessor();
00569                 }
00570 
00571                 string get_desc() const
00572                 {
00573                         return "Determines the image gradient in the x direction";
00574                 }
00575 
00576                 TypeDict get_param_types() const
00577                 {
00578                         TypeDict d;
00579                         return d;
00580                 }
00581 
00582                 static const string NAME;
00583         };
00584 
00585         class YGradientProcessor : public Processor
00586         {
00587                 public:
00588                         YGradientProcessor() {}
00589 
00590                         string get_name() const
00591                         {
00592                                 return NAME;
00593                         }
00594 
00595                         void process_inplace(EMData *image);
00596 
00597                         static Processor *NEW()
00598                         {
00599                                 return new YGradientProcessor();
00600                         }
00601 
00602                         string get_desc() const
00603                         {
00604                                 return "Determines the image gradient in the y direction";
00605                         }
00606 
00607 
00608                         TypeDict get_param_types() const
00609                         {
00610                                 TypeDict d;
00611                                 return d;
00612                         }
00613 
00614                         static const string NAME;
00615         };
00616 
00617         class ZGradientProcessor : public Processor
00618         {
00619                 public:
00620                         ZGradientProcessor() {}
00621 
00622                         string get_name() const
00623                         {
00624                                 return NAME;
00625                         }
00626 
00627                         void process_inplace(EMData *image);
00628 
00629                         static Processor *NEW()
00630                         {
00631                                 return new ZGradientProcessor();
00632                         }
00633 
00634                         string get_desc() const
00635                         {
00636                                 return "Determines the image gradient in the z direction";
00637                         }
00638 
00639                         TypeDict get_param_types() const
00640                         {
00641                                 TypeDict d;
00642                                 return d;
00643                         }
00644 
00645                         static const string NAME;
00646         };
00647 
00656         class Wiener2DAutoAreaProcessor:public Processor
00657         {
00658           public:
00659                 string get_name() const
00660                 {
00661                         return NAME;
00662                 }
00663 
00664                 virtual EMData* process(const EMData * const image);
00665 
00666                 void process_inplace(EMData *image);
00667 
00668                 void set_params(const Dict & new_params)
00669                 {
00670                         params = new_params;
00671                         bgsize = params["size"];
00672 //                      printf("%s %f\n",params.keys()[0].c_str(),lowpass);
00673                 }
00674 
00675                 TypeDict get_param_types() const
00676                 {
00677                         TypeDict d;
00678                         d.put("size", EMObject::INT, "Size in pixels of the boxes to chop the image into");
00679                         return d;
00680                 }
00681 
00682                 static Processor *NEW()
00683                 {
00684                         return new Wiener2DAutoAreaProcessor();
00685                 }
00686 
00687                 string get_desc() const
00688                 {
00689                         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";
00690                 }
00691 
00692                 static const string NAME;
00693 
00694                 protected:
00695                 int bgsize;
00696         };
00697 
00704         class DistanceSegmentProcessor:public Processor
00705         {
00706           public:
00707                 string get_name() const
00708                 {
00709                         return NAME;
00710                 }
00711 
00712                 virtual EMData* process(const EMData * const image);
00713                 void process_inplace( EMData * image);
00714 
00715                 TypeDict get_param_types() const
00716                 {
00717                         TypeDict d ;
00718                         d.put("thr",EMObject::FLOAT,"Optional : Isosurface threshold value. Pixels below this will not be segment centers (default = 0.9)");
00719                         d.put("minsegsep",EMObject::FLOAT,"Required: Minimum segment separation in pixels. Segments too close will trigger a reseed");
00720                         d.put("maxsegsep",EMObject::FLOAT,"Required: Maximum segment separation in pixels. Segments too close will trigger a reseed");
00721                         d.put("verbose",EMObject::INT,"Be verbose while running");
00722                         return d;
00723                 }
00724 
00725                 static Processor *NEW()
00726                 {
00727                         return new DistanceSegmentProcessor();
00728                 }
00729 
00730                 string get_desc() const
00731                 {
00732                         return "Segments a volume into pieces separated by distances in the specified range.";
00733                 }
00734 
00735                 static const string NAME;
00736 
00737         };
00738 
00745         class KmeansSegmentProcessor:public Processor
00746         {
00747           public:
00748                 string get_name() const
00749                 {
00750                         return NAME;
00751                 }
00752 
00753                 virtual EMData* process(const EMData * const image);
00754                 void process_inplace( EMData * image);
00755 
00756                 TypeDict get_param_types() const
00757                 {
00758                         TypeDict d ;
00759                         d.put("nseg", EMObject::INT, "Number of segments to divide the image into. default=12" );
00760                         d.put("thr",EMObject::FLOAT,"Isosurface threshold value. Pixels below this will not be segmented");
00761                         d.put("ampweight",EMObject::INT,"If set, will weight centers by voxel amplitude. default = 1");
00762                         d.put("maxsegsize",EMObject::FLOAT,"Maximum radial distance from segment center to member voxel. Default=10000");
00763                         d.put("minsegsep",EMObject::FLOAT,"Minimum segment separation. Segments too close will trigger a reseed");
00764                         d.put("maxiter",EMObject::FLOAT,"Maximum number of iterations to run before stopping. Default=100");
00765                         d.put("maxvoxmove",EMObject::FLOAT,"Maximum number of voxels that can move before quitting. Default=25");
00766                         d.put("verbose",EMObject::INT,"Be verbose while running");
00767                         return d;
00768                 }
00769 
00770                 static Processor *NEW()
00771                 {
00772                         return new KmeansSegmentProcessor();
00773                 }
00774 
00775                 string get_desc() const
00776                 {
00777                         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.";
00778                 }
00779 
00780                 static const string NAME;
00781 
00782         };
00783 
00797         class CtfSimProcessor:public Processor
00798         {
00799           public:
00800                 string get_name() const                 
00801                 {
00802                         return NAME;
00803                 }
00804 
00805                 virtual EMData* process(const EMData * const image);
00806 
00807                 void process_inplace(EMData *image);
00808 
00809                 TypeDict get_param_types() const
00810                 {
00811                         TypeDict d;
00812                         d.put("defocus", EMObject::FLOAT, "Defocus in microns (underfocus positive)");
00813                         d.put("ampcont", EMObject::FLOAT, "% amplitude contrast (0-100)");
00814                         d.put("bfactor", EMObject::FLOAT, "B-factor in A^2, uses MRC convention rather than EMAN1 convention");
00815                         d.put("noiseamp", EMObject::FLOAT, "Amplitude of the added empirical pink noise");
00816                         d.put("noiseampwhite", EMObject::FLOAT, "Amplitude of added white noise");
00817                         d.put("voltage", EMObject::FLOAT, "Microscope voltage in KV");
00818                         d.put("cs", EMObject::FLOAT, "Cs of microscope in mm");
00819                         d.put("apix", EMObject::FLOAT, "A/pix of data");
00820                         return d;
00821                 }
00822 
00823                 static Processor *NEW()
00824                 {
00825                         return new CtfSimProcessor();
00826                 }
00827 
00828                 string get_desc() const
00829                 {
00830                         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. ";
00831                 }
00832 
00833                 static const string NAME;
00834 
00835 //              protected:
00836         };
00837 
00838 
00845         class Wiener2DFourierProcessor:public Processor
00846         {
00847           public:
00848                 string get_name() const                 
00849                 {
00850                         return NAME;
00851                 }
00852 
00853                 virtual EMData* process(const EMData * const image);
00854 
00855                 void process_inplace(EMData *image);
00856 
00857                 void set_params(const Dict & new_params)
00858                 {
00859                         params = new_params;
00860                         ctf = params["ctf"];
00861 //                      printf("%s %f\n",params.keys()[0].c_str(),lowpass);
00862                 }
00863 
00864                 TypeDict get_param_types() const
00865                 {
00866                         TypeDict d;
00867                         d.put("ctf", EMObject::EMDATA, "Ctf object to use for Wiener filter parameters");
00868                         return d;
00869                 }
00870 
00871                 static Processor *NEW()
00872                 {
00873                         return new Wiener2DFourierProcessor();
00874                 }
00875 
00876                 string get_desc() const
00877                 {
00878                         return "Applies a 2-D Wiener filter to an image based on its Ctf parameters";
00879                 }
00880 
00881                 static const string NAME;
00882 
00883                 protected:
00884                 Ctf *ctf;
00885         };
00886 
00887         class LinearRampFourierProcessor:public FourierProcessor
00888         {
00889                 public:
00890                         virtual string get_name() const
00891                         {
00892                                 return NAME;
00893                         }
00894 
00895                         virtual string get_desc() const
00896                         {
00897                                 return "";
00898                         }
00899 
00900                         static Processor *NEW()
00901                         {
00902                                 return new LinearRampFourierProcessor();
00903                         }
00904 
00905                         static const string NAME;
00906 
00907                 protected:
00908                         virtual void create_radial_func(vector < float >&radial_mask) const ;
00909         };
00910 
00911 
00914         class LowpassRandomPhaseProcessor:public FourierProcessor
00915         {
00916           public:
00917                 string get_name() const
00918                 { return NAME; }
00919                 static Processor *NEW() { return new LowpassRandomPhaseProcessor(); }
00920                 string get_desc() const
00921                 {
00922                         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.";
00923                 }
00924                                 void process_inplace(EMData * image);
00925                                 void create_radial_func(vector < float >&radial_mask) const;
00926 
00927                 static const string NAME;
00928         };
00929 
00930 
00933         class LowpassAutoBProcessor:public FourierAnlProcessor
00934         {
00935           public:
00936                 string get_name() const
00937                 {
00938                         return NAME;
00939                 }
00940 
00941                 static Processor *NEW()
00942                 {
00943                         return new LowpassAutoBProcessor();
00944                 }
00945 
00946                 string get_desc() const
00947                 {
00948                         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.";
00949                 }
00950 
00951                 static const string NAME;
00952 
00953                 virtual TypeDict get_param_types() const
00954                 {
00955                         TypeDict d = FourierAnlProcessor::get_param_types();
00956                         d.put("bfactor", EMObject::FLOAT, "B-factor in terms of e^-(B s^2/4)");
00957                         d.put("noisecutoff", EMObject::FLOAT, "Spatial frequency past which inverse-B will not be applied");
00958 //                      d.put("adaptnoise", EMObject::INT, "Dual linear fit separating lower resolution signal from higher resolution noise. Noise region not upweighted.");
00959                         d.put("verbose", EMObject::INT, "Print information about the determined B-factor");
00960                         return d;
00961                 }
00962 
00963           protected:
00964                 virtual void preprocess(EMData * image) {
00965                         if(params.has_key("apix")) {
00966                                 image->set_attr("apix_x", (float)params["apix"]);
00967                                 image->set_attr("apix_y", (float)params["apix"]);
00968                                 image->set_attr("apix_z", (float)params["apix"]);
00969                         }
00970                         float apix=(float)image->get_attr("apix_x");
00971 
00972                         const Dict dict = image->get_attr_dict();
00973                         if (params.has_key("cutoff_abs")) {
00974                                 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00975                         }
00976                         else if( params.has_key("cutoff_freq") ) {
00977                                 float val =  (float)params["cutoff_freq"] * apix;
00978                                 params["cutoff_abs"] = val;
00979                                 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00980                         }
00981                         else if( params.has_key("cutoff_pixels") ) {
00982                                 float val = 0.5f*(float)params["cutoff_pixels"] / (float)dict["nx"];
00983                                 params["cutoff_abs"] = val;
00984                                 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00985                         }
00986                 }
00987 
00988                 void create_radial_func(vector < float >&radial_mask,EMData *image) const;
00989         };
00990 
00993         class HighpassAutoPeakProcessor:public FourierAnlProcessor
00994         {
00995           public:
00996                 string get_name() const
00997                 {
00998                         return NAME;
00999                 }
01000                 static Processor *NEW()
01001                 {
01002                         return new HighpassAutoPeakProcessor();
01003                 }
01004 
01005                 string get_desc() const
01006                 {
01007                         return "Attempts to automatically remove the low resolution peak present in virtually all cryoEM data.";
01008                 }
01009 
01010                 static const string NAME;
01011 
01012           protected:
01013                 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
01014                   virtual void preprocess(EMData * image);
01015                   float highpass;
01016         };
01017 
01022         class LinearRampProcessor:public FourierProcessor
01023         {
01024           public:
01025                 LinearRampProcessor():intercept(0), slope(0)
01026                 {
01027                 }
01028 
01029                 string get_name() const
01030                 {
01031                         return NAME;
01032                 }
01033                 static Processor *NEW()
01034                 {
01035                         return new LinearRampProcessor();
01036                 }
01037 
01038                 string get_desc() const
01039                 {
01040                         return "processor radial function: f(x) = slope * x + intercept;";
01041                 }
01042 
01043                 void set_params(const Dict & new_params)
01044                 {
01045                         params = new_params;
01046                         intercept = params["intercept"];
01047                         slope = params["slope"];
01048                 }
01049 
01050                 TypeDict get_param_types() const
01051                 {
01052                         TypeDict d;
01053                         d.put("intercept", EMObject::FLOAT, "intercept in 'f(x) = slope * x + intercept'");
01054                         d.put("slope", EMObject::FLOAT, "slope in 'f(x) = slope * x + intercept'");
01055                         return d;
01056                 }
01057 
01058                 static const string NAME;
01059 
01060           protected:
01061                 void create_radial_func(vector < float >&radial_mask) const;
01062 
01063           private:
01064                 float intercept;
01065                 float slope;
01066         };
01067 
01071         class LoGFourierProcessor:public FourierProcessor
01072         {
01073           public:
01074                 LoGFourierProcessor():sigma(0)
01075                 {
01076                 }
01077 
01078                 string get_name() const
01079                 {
01080                         return NAME;
01081                 }
01082                 static Processor *NEW()
01083                 {
01084                         return new LoGFourierProcessor();
01085                 }
01086 
01087                 string get_desc() const
01088                 {
01089                         return "processor radial function: f(x) = ((x^2 - s^2)/s^4)e^-(x^2/2s^2)";
01090                 }
01091 
01092                 void set_params(const Dict & new_params)
01093                 {
01094                         params = new_params;
01095                         sigma = params["sigma"];
01096                 }
01097 
01098                 TypeDict get_param_types() const
01099                 {
01100                         TypeDict d;
01101                         d.put("sigma", EMObject::FLOAT, "LoG sigma");
01102                         return d;
01103                 }
01104 
01105                 static const string NAME;
01106 
01107           protected:
01108                 void create_radial_func(vector < float >&radial_mask) const;
01109 
01110           private:
01111                 float sigma;
01112         };
01113         
01118         class DoGFourierProcessor:public FourierProcessor
01119         {
01120           public:
01121                 DoGFourierProcessor():sigma1(0), sigma2(0)
01122                 {
01123                 }
01124 
01125                 string get_name() const
01126                 {
01127                         return NAME;
01128                 }
01129                 static Processor *NEW()
01130                 {
01131                         return new DoGFourierProcessor();
01132                 }
01133 
01134                 string get_desc() const
01135                 {
01136                         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)]";
01137                 }
01138 
01139                 void set_params(const Dict & new_params)
01140                 {
01141                         params = new_params;
01142                         sigma1 = params["sigma1"];
01143                         sigma2 = params["sigma2"];
01144                 }
01145 
01146                 TypeDict get_param_types() const
01147                 {
01148                         TypeDict d;
01149                         d.put("sigma1", EMObject::FLOAT, "DoG sigma1");
01150                         d.put("sigma2", EMObject::FLOAT, "DoG sigma2");
01151                         return d;
01152                 }
01153 
01154                 static const string NAME;
01155 
01156           protected:
01157                 void create_radial_func(vector < float >&radial_mask) const;
01158 
01159           private:
01160                 float sigma1;
01161                 float sigma2;
01162         };
01163         
01166         class RealPixelProcessor:public Processor
01167         {
01168           public:
01169                 RealPixelProcessor():value(0), maxval(1), mean(0), sigma(0)
01170                 {
01171                 }
01172                 void process_inplace(EMData * image);
01173 
01174                 virtual void set_params(const Dict & new_params)
01175                 {
01176                         params = new_params;
01177                         if (params.size() == 1) {
01178                                 vector < EMObject > dict_values = params.values();
01179                                 value = dict_values[0];
01180                         }
01181                 }
01182 
01183                 static string get_group_desc()
01184                 {
01185                         return "The base class for real space processor working on individual pixels. The processor won't consider the pixel's coordinates and neighbors.";
01186                 }
01187 
01188           protected:
01189                 virtual void process_pixel(float *x) const = 0;
01190                 virtual void calc_locals(EMData *)
01191                 {
01192                 }
01193                 virtual void normalize(EMData *) const
01194                 {
01195                 }
01196 
01197                 float value;
01198                 float maxval;
01199                 float mean;
01200                 float sigma;
01201         };
01202 
01205         class AbsoluateValueProcessor:public RealPixelProcessor
01206         {
01207           public:
01208                 string get_name() const
01209                 {
01210                         return NAME;
01211                 }
01212                 static Processor *NEW()
01213                 {
01214                         return new AbsoluateValueProcessor();
01215                 }
01216 
01217                 static const string NAME;
01218 
01219           protected:
01220                 void process_pixel(float *x) const
01221                 {
01222                         *x = fabs(*x);
01223                 }
01224 
01225                 string get_desc() const
01226                 {
01227                         return "f(x) = |x|";
01228                 }
01229         };
01230 
01233         class FloorValueProcessor:public RealPixelProcessor
01234         {
01235           public:
01236                 string get_name() const
01237                 {
01238                         return NAME;
01239                 }
01240                 static Processor *NEW()
01241                 {
01242                         return new FloorValueProcessor();
01243                 }
01244 
01245                 static const string NAME;
01246 
01247           protected:
01248                 void process_pixel(float *x) const
01249                 {
01250                         *x = floor(*x);
01251                 }
01252 
01253                 string get_desc() const
01254                 {
01255                         return "f(x) = floor(x)";
01256                 }
01257         };
01258 
01259 
01262         class BooleanProcessor:public RealPixelProcessor
01263         {
01264           public:
01265                 string get_name() const
01266                 {
01267                         return NAME;
01268                 }
01269                 static Processor *NEW()
01270                 {
01271                         return new BooleanProcessor();
01272                 }
01273 
01274                 string get_desc() const
01275                 {
01276                         return "f(x) = 0 if x = 0; f(x) = 1 if x != 0;";
01277                 }
01278 
01279                 static const string NAME;
01280 
01281           protected:
01282                 void process_pixel(float *x) const
01283                 {
01284                         if (*x != 0)
01285                         {
01286                                 *x = 1.0;
01287                         }
01288                 }
01289         };
01290 
01294         class RecipCarefullyProcessor:public RealPixelProcessor
01295         {
01296                 public:
01297                         string get_name() const
01298                         {
01299                                 return NAME;
01300                         }
01301                         static Processor *NEW()
01302                         {
01303                                 return new RecipCarefullyProcessor();
01304                         }
01305 
01306                         void set_params(const Dict & new_params)
01307                         {
01308                                 params = new_params;
01309                                 zero_to = params.set_default("zero_to",0.0f);
01310                         }
01311 
01312                         TypeDict get_param_types() const
01313                         {
01314                                 TypeDict d;
01315                                 d.put("zero_to", EMObject::FLOAT, "Inverted zero values are set to this value, default is 0.");
01316                                 return d;
01317                         }
01318 
01319                         string get_desc() const
01320                         {
01321                                 return "if f(x) != 0: f(x) = 1/f(x) else: f(x) = zero_to";
01322                         }
01323 
01324                         static const string NAME;
01325 
01326                 protected:
01327                         void process_pixel(float *x) const
01328                         {
01329                                 if (*x == 0.0) *x = zero_to;
01330                                 else *x = 1.0f/(*x);
01331                         }
01332                 private:
01333                         float zero_to;
01334         };
01335 
01339         class ValuePowProcessor:public RealPixelProcessor
01340         {
01341           public:
01342                 string get_name() const
01343                 {
01344                         return NAME;
01345                 }
01346                 static Processor *NEW()
01347                 {
01348                         return new ValuePowProcessor();
01349                 }
01350 
01351                 void set_params(const Dict & new_params)
01352                 {
01353                         params = new_params;
01354                         pwr = params["pow"];
01355                 }
01356 
01357                 TypeDict get_param_types() const
01358                 {
01359                         TypeDict d;
01360                         d.put("pow", EMObject::FLOAT, "Each pixel is raised to this power");
01361                         return d;
01362                 }
01363 
01364                 string get_desc() const
01365                 {
01366                         return "f(x) = x ^ pow;";
01367                 }
01368 
01369                 static const string NAME;
01370 
01371           protected:
01372                 void process_pixel(float *x) const
01373                 {
01374                         if (*x<0 && pwr!=(int)pwr) *x=0;
01375                         else (*x) = pow(*x,pwr);
01376                 }
01377           private:
01378                 float pwr;
01379         };
01380 
01383         class ValueSquaredProcessor:public RealPixelProcessor
01384         {
01385           public:
01386                 string get_name() const
01387                 {
01388                         return NAME;
01389                 }
01390                 static Processor *NEW()
01391                 {
01392                         return new ValueSquaredProcessor();
01393                 }
01394 
01395 
01396                 string get_desc() const
01397                 {
01398                         return "f(x) = x * x;";
01399                 }
01400 
01401                 static const string NAME;
01402 
01403           protected:
01404                 void process_pixel(float *x) const
01405                 {
01406                         (*x) *= (*x);
01407                 }
01408         };
01409 
01412         class ValueSqrtProcessor:public RealPixelProcessor
01413         {
01414           public:
01415                 string get_name() const
01416                 {
01417                         return NAME;
01418                 }
01419                 static Processor *NEW()
01420                 {
01421                         return new ValueSqrtProcessor();
01422                 }
01423 
01424                 string get_desc() const
01425                 {
01426                         return "f(x) = sqrt(x)";
01427                 }
01428 
01429                 static const string NAME;
01430 
01431           protected:
01432                 void process_pixel(float *x) const
01433                 {
01434                         *x = sqrt(*x);
01435                 }
01436         };
01437 
01441         class ToZeroProcessor:public RealPixelProcessor
01442         {
01443                 public:
01444                         string get_name() const
01445                         {
01446                                 return NAME;
01447                         }
01448                         static Processor *NEW()
01449                         {
01450                                 return new ToZeroProcessor();
01451                         }
01452                         TypeDict get_param_types() const
01453                         {
01454                                 TypeDict d;
01455                                 d.put("minval", EMObject::FLOAT, "Everything below this value is set to zero");
01456                                 return d;
01457                         }
01458 
01459                         string get_desc() const
01460                         {
01461                                 return "f(x) = x if x >= minval; f(x) = 0 if x < minval.";
01462                         }
01463 
01464                         static const string NAME;
01465 
01466                 protected:
01467                         inline void process_pixel(float *x) const
01468                         {
01469                                 if (*x < value) {
01470                                         *x = 0;
01471                                 }
01472                         }
01473         };
01474 
01480         class Rotate180Processor:public Processor
01481         {
01482                 public:
01483                         string get_name() const
01484                         {
01485                                 return NAME;
01486                         }
01487                         static Processor *NEW()
01488                         {
01489                                 return new Rotate180Processor();
01490                         }
01491 
01495                         void process_inplace(EMData* image);
01496 
01497                         string get_desc() const
01498                         {
01499                                 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.";
01500                         }
01501 
01502                         static const string NAME;
01503         };
01504 
01511         class TransformProcessor:public Processor
01512         {
01513                 public:
01514                         virtual string get_name() const
01515                         {
01516                                 return NAME;
01517                         }
01518                         static Processor *NEW()
01519                         {
01520                                 return new TransformProcessor();
01521                         }
01522 
01527                         virtual void process_inplace(EMData* image);
01528 
01533                         virtual EMData* process(const EMData* const image);
01534 
01535                         virtual TypeDict get_param_types() const
01536                         {
01537                                 TypeDict d;
01538                                 d.put("transform", EMObject::TRANSFORM, "The Transform object that will be applied to the image" );
01539                                 return d;
01540                         }
01541 
01542                         virtual string get_desc() const
01543                         {
01544                                 return "The image is transformed using Transform parameter.";
01545                         }
01546 
01547                         static const string NAME;
01548 
01549                         float* transform(const EMData* const image, const Transform& t) const;
01550                 private:
01551                         // This function became redundant if favor of EMData::scale_pixel
01552                         //void update_emdata_attributes(EMData* const image, const Dict& attr_dict, const float& scale) const;
01553 
01554 
01555                         void assert_valid_aspect(const EMData* const image) const;
01556         };
01557 
01565         class IntTranslateProcessor:public Processor
01566         {
01567                 public:
01568                         virtual string get_name() const
01569                         {
01570                                 return NAME;
01571                         }
01572 
01573                         static Processor *NEW()
01574                         {
01575                                 return new IntTranslateProcessor();
01576                         }
01577 
01582                         virtual void process_inplace(EMData* image);
01583 
01588                         virtual EMData* process(const EMData* const image);
01589 
01590                         virtual TypeDict get_param_types() const
01591                         {
01592                                 TypeDict d;
01593                                 d.put("trans", EMObject::INTARRAY, "The displacement array, can be length 1-3" );
01594                                 return d;
01595                         }
01596 
01597                         virtual string get_desc() const
01598                         {
01599                                 return "The image is translated an integer amount";
01600                         }
01601 
01602                         static const string NAME;
01603 
01604                 private:
01608                         void assert_valid_aspect(const vector<int>& translation, const EMData* const image) const;
01609 
01615                         Region get_clip_region(vector<int>& translation, const EMData* const image) const;
01616         };
01617         
01623         class ApplySymProcessor:public Processor
01624         {
01625                 public:
01626                         virtual string get_name() const
01627                         {
01628                                 return NAME;
01629                         }
01630 
01631                         static Processor *NEW()
01632                         {
01633                                 return new ApplySymProcessor();
01634                         }
01635 
01636                         virtual void process_inplace(EMData* image);
01637 
01638                         virtual EMData* process(const EMData* const image);
01639 
01640                         virtual TypeDict get_param_types() const
01641                         {
01642                                 TypeDict d;
01643                                 d.put("sym", EMObject::STRING, "The symmetry under which to do the alignment, Default=c1" );
01644                                 return d;
01645                         }
01646 
01647                         virtual string get_desc() const
01648                         {
01649                                 return "Symmetry is applied to the 3D EM object";
01650                         }
01651 
01652                         static const string NAME;
01653                 
01654         };
01655         
01662         class ScaleTransformProcessor:public Processor
01663         {
01664                 public:
01665                         virtual string get_name() const
01666                         {
01667                                 return NAME;
01668                         }
01669                         static Processor *NEW()
01670                         {
01671                                 return new ScaleTransformProcessor();
01672                         }
01677                         virtual void process_inplace(EMData* image);
01678 
01683                         virtual EMData* process(const EMData* const image);
01684 
01685                         virtual TypeDict get_param_types() const
01686                         {
01687                                 TypeDict d;
01688                                 d.put("scale", EMObject::FLOAT, "The amount by which to scale" );
01689                                 d.put("clip", EMObject::INT, "The length of each output dimension. Non sophisticated, output dimensions can't be different" );
01692                                 return d;
01693                         }
01694 
01695                         virtual string get_desc() const
01696                         {
01697                                 return "The image is scaled with the clip variable in mind, being sure to preserve as much pixel information as possible.";
01698                         }
01699 
01700                         static const string NAME;
01701         };
01702 
01709         class ClampingProcessor :public Processor
01710         {
01711           public:
01712                 ClampingProcessor() : default_max(1.0), default_min(0.0) {}
01713 
01714                 string get_name() const
01715                 {
01716                         return NAME;
01717                 }
01718                 static Processor *NEW()
01719                 {
01720                         return new ClampingProcessor();
01721                 }
01722 
01723                 void process_inplace(EMData *image);
01724 
01725                 TypeDict get_param_types() const
01726                 {
01727                         TypeDict d;
01728                         d.put("minval", EMObject::FLOAT, "The pixel values that bounds the smallest pixel value in the output image" );
01729                         d.put("maxval", EMObject::FLOAT, "The pixel values that bounds the largest pixel value in the output image" );
01730                         d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01731                         d.put("tozero", EMObject::BOOL, "Replace outlying pixels values with zero" );
01732                         return d;
01733                 }
01734 
01735                 string get_desc() const
01736                 {
01737                         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.";
01738                 }
01739 
01740                 static const string NAME;
01741 
01742           protected:
01743                 float default_max, default_min;
01744         };
01745 
01751         class NSigmaClampingProcessor : public ClampingProcessor
01752         {
01753                 public:
01754                         NSigmaClampingProcessor() : default_sigma(2.0) {}
01755 
01756                         string get_name() const
01757                         {
01758                                 return NAME;
01759                         }
01760 
01761                         static Processor *NEW()
01762                         {
01763                                 return new NSigmaClampingProcessor();
01764                         }
01765 
01766                         TypeDict get_param_types() const
01767                         {
01768                                 TypeDict d;
01769                                 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" );
01770                                 d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01771                                 d.put("tozero", EMObject::BOOL, "Replace outlying pixels values with zero" );
01772                                 return d;
01773                         }
01774 
01775                         void process_inplace(EMData *image);
01776 
01777                         string get_desc() const
01778                         {
01779                                 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.";
01780                         }
01781 
01782                         static const string NAME;
01783 
01784                 protected:
01785                         float default_sigma;
01786         };
01787 
01791         class ToMinvalProcessor:public Processor
01792         {
01793           public:
01794                 string get_name() const
01795                 {
01796                         return NAME;
01797                 }
01798                 static Processor *NEW()
01799                 {
01800                         return new ToMinvalProcessor();
01801                 }
01802 
01803                 void process_inplace(EMData *image);
01804 
01805                 TypeDict get_param_types() const
01806                 {
01807                         TypeDict d;
01808                         d.put("minval", EMObject::FLOAT, "Everything below this value is set to this value");
01809                         d.put("newval", EMObject::FLOAT, "If set, values below minval will be set to newval instead of minval ");
01810                         return d;
01811                 }
01812 
01813                 string get_desc() const
01814                 {
01815                         return "f(x) = x if x >= minval; f(x) = minval|newval if x < minval.";
01816                 }
01817 
01818                 static const string NAME;
01819 
01820         protected:
01821 
01822         };
01823 
01824 
01825 
01829         class CutToZeroProcessor:public RealPixelProcessor
01830         {
01831           public:
01832                 string get_name() const
01833                 {
01834                         return NAME;
01835                 }
01836                 static Processor *NEW()
01837                 {
01838                         return new CutToZeroProcessor();
01839                 }
01840                 TypeDict get_param_types() const
01841                 {
01842                         TypeDict d;
01843                         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" );
01844                         return d;
01845                 }
01846 
01847                 string get_desc() const
01848                 {
01849                         return "f(x) = x-minval if x >= minval; f(x) = 0 if x < minval.";
01850                 }
01851 
01852                 static const string NAME;
01853 
01854           protected:
01855                 void process_pixel(float *x) const
01856                 {
01857                         *x = *x - value;
01858                         if (*x < 0) {
01859                                 *x = 0;
01860                         }
01861                 }
01862         };
01863 
01867         class BinarizeProcessor:public RealPixelProcessor
01868         {
01869           public:
01870                 string get_name() const
01871                 {
01872                         return NAME;
01873                 }
01874                 static Processor *NEW()
01875                 {
01876                         return new BinarizeProcessor();
01877                 }
01878                 TypeDict get_param_types() const
01879                 {
01880                         TypeDict d;
01881                         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" );
01882                         return d;
01883                 }
01884 
01885                 string get_desc() const
01886                 {
01887                         return "f(x) = 0 if x < value; f(x) = 1 if x >= value.";
01888                 }
01889 
01890                 static const string NAME;
01891 
01892           protected:
01893                 void process_pixel(float *x) const
01894                 {
01895                         if (*x < value)
01896                         {
01897                                 *x = 0;
01898                         }
01899                         else
01900                         {
01901                                 *x = 1;
01902                         }
01903                 }
01904         };
01905 
01913         class BinarizeFourierProcessor:public Processor
01914                 {
01915                   public:
01916                         virtual string get_name() const
01917                         {
01918                                 return NAME;
01919                         }
01920                         static Processor *NEW()
01921                         {
01922                                 return new BinarizeFourierProcessor();
01923                         }
01924 
01929                         virtual void process_inplace(EMData* image);
01930 
01931                         virtual TypeDict get_param_types() const
01932                         {
01933                                 TypeDict d;
01934                                 d.put("value", EMObject::FLOAT, "The Fourier amplitude threshold cutoff" );
01935                                 return d;
01936                         }
01937 
01938                         virtual string get_desc() const
01939                         {
01940                                 return "f(k) = 0 + 0i if ||f(k)|| < value; f(k) = a + bi if ||f(k)|| >= value.";
01941                         }
01942 
01943                         static const string NAME;
01944                 };
01945 
01950         class CollapseProcessor:public RealPixelProcessor
01951         {
01952           public:
01953                 string get_name() const
01954                 {
01955                         return NAME;
01956                 }
01957                 static Processor *NEW()
01958                 {
01959                         return new CollapseProcessor();
01960                 }
01961 
01962                 void set_params(const Dict & new_params)
01963                 {
01964                         params = new_params;
01965                         range = params["range"];
01966                         value = params["value"];
01967                 }
01968 
01969                 TypeDict get_param_types() const
01970                 {
01971                         TypeDict d;
01972                         d.put("range", EMObject::FLOAT, "The range about 'value' which will be collapsed to 'value'");
01973                         d.put("value", EMObject::FLOAT, "The pixel value where the focus of the collapse operation is");
01974                         return d;
01975                 }
01976 
01977                 string get_desc() const
01978                 {
01979                         return "f(x): if v-r<x<v+r -> v; if x>v+r -> x-r; if x<v-r -> x+r";
01980                 }
01981 
01982                 static const string NAME;
01983 
01984           protected:
01985                 void process_pixel(float *x) const
01986                 {
01987                         if (*x>value+range) *x-=range;
01988                         else if (*x<value-range) *x+=range;
01989                         else *x=value;
01990                 }
01991                 float range;
01992         };
01993 
01998         class LinearXformProcessor:public RealPixelProcessor
01999         {
02000           public:
02001                 LinearXformProcessor():shift(0), scale(0)
02002                 {
02003                 }
02004 
02005                 string get_name() const
02006                 {
02007                         return NAME;
02008                 }
02009                 static Processor *NEW()
02010                 {
02011                         return new LinearXformProcessor();
02012                 }
02013 
02014                 void set_params(const Dict & new_params)
02015                 {
02016                         params = new_params;
02017                         shift = params.get("shift");
02018                         scale = params.get("scale");
02019                 }
02020 
02021                 TypeDict get_param_types() const
02022                 {
02023                         TypeDict d;
02024                         d.put("shift", EMObject::FLOAT, "The amount to shift pixel values by before scaling");
02025                         d.put("scale", EMObject::FLOAT, "The scaling factor to be applied to pixel values");
02026                         return d;
02027                 }
02028 
02029                 string get_desc() const
02030                 {
02031                         return "linear transform processor: f(x) = x * scale + shift. This is equivalent to a regular contrast stretching operation";
02032                 }
02033 
02034                 static const string NAME;
02035 
02036           protected:
02037                 void process_pixel(float *x) const
02038                 {
02039                         *x = (*x) * scale + shift;
02040                 }
02041 
02042           private:
02043                 float shift;
02044                 float scale;
02045         };
02046 
02051         class ExpProcessor:public RealPixelProcessor
02052         {
02053           public:
02054                 ExpProcessor():low(0), high(0)
02055                 {
02056                 }
02057 
02058                 string get_name() const
02059                 {
02060                         return NAME;
02061                 }
02062 
02063                 static Processor *NEW()
02064                 {
02065                         return new ExpProcessor();
02066                 }
02067 
02068                 void set_params(const Dict & new_params)
02069                 {
02070                         params = new_params;
02071                         low = params.get("low");
02072                         high = params.get("high");
02073                 }
02074 
02075                 TypeDict get_param_types() const
02076                 {
02077                         TypeDict d;
02078                         d.put("low", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
02079                         d.put("high", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
02080                         return d;
02081                 }
02082 
02083                 string get_desc() const
02084                 {
02085                         return "f(x) = exp( x / low - high)";
02086                 }
02087 
02088                 static const string NAME;
02089 
02090           protected:
02094                 void process_pixel(float *x) const
02095                 {
02096                         float v = *x / low - high;
02097                         if (v > 40) {
02098                                 v = 40;
02099                         }
02100                         *x = exp(v);
02101                 }
02102 
02103           private:
02104                 float low;
02105                 float high;
02106         };
02107 
02111         class FiniteProcessor:public RealPixelProcessor
02112         {
02113                 public:
02114                         FiniteProcessor():to(0)
02115                         {
02116                         }
02117 
02118                         string get_name() const
02119                         {
02120                                 return NAME;
02121                         }
02122 
02123                         static Processor *NEW()
02124                         {
02125                                 return new FiniteProcessor();
02126                         }
02127 
02128                         void set_params(const Dict & new_params)
02129                         {
02130                                 if (new_params.has_key("to") )
02131                                         to = params["to"];
02132                         }
02133 
02134                         TypeDict get_param_types() const
02135                         {
02136                                 TypeDict d;
02137                                 d.put("to", EMObject::FLOAT, "Pixels which are not finite will be set to this value");
02138                                 return d;
02139                         }
02140 
02141                         string get_desc() const
02142                         {
02143                                 return "f(x) = f(x) if f(x) is finite | to if f(x) is not finite";
02144                         }
02145 
02146                         static const string NAME;
02147 
02148                 protected:
02152                         void process_pixel(float *x) const;
02153                 private:
02154                         float to;
02155         };
02156 
02161         class RangeThresholdProcessor:public RealPixelProcessor
02162         {
02163           public:
02164                 RangeThresholdProcessor():low(0), high(0)
02165                 {
02166                 }
02167 
02168                 string get_name() const
02169                 {
02170                         return NAME;
02171                 }
02172                 static Processor *NEW()
02173                 {
02174                         return new RangeThresholdProcessor();
02175                 }
02176 
02177                 void set_params(const Dict & new_params)
02178                 {
02179                         params = new_params;
02180                         low = params.get("low");
02181                         high = params.get("high");
02182                 }
02183 
02184                 TypeDict get_param_types() const
02185                 {
02186                         TypeDict d;
02187                         d.put("low", EMObject::FLOAT, "The lower limit of the range that will be set to 1");
02188                         d.put("high", EMObject::FLOAT, "The upper limit of the range that will be set to 1");
02189                         return d;
02190                 }
02191 
02192                 string get_desc() const
02193                 {
02194                         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";
02195                 }
02196 
02197                 static const string NAME;
02198 
02199           protected:
02200                 void process_pixel(float *x) const
02201                 {
02202                         if (*x >= low && *x <= high) {
02203                                 *x = 1;
02204                         }
02205                         else {
02206                                 *x = 0;
02207                         }
02208                 }
02209           private:
02210                 float low;
02211                 float high;
02212 
02213         };
02214 
02219         class SigmaProcessor:public RealPixelProcessor
02220         {
02221           public:
02222                 string get_name() const
02223                 {
02224                         return NAME;
02225                 }
02226                 static Processor *NEW()
02227                 {
02228                         return new SigmaProcessor();
02229                 }
02230 
02231                 void set_params(const Dict & new_params)
02232                 {
02233                         params = new_params;
02234                         value1 = params.get("value1");
02235                         value2 = params.get("value2");
02236                 }
02237 
02238                 TypeDict get_param_types() const
02239                 {
02240                         TypeDict d;
02241                         d.put("value1", EMObject::FLOAT, "A number reflecting total standard deviations in the right direction");
02242                         d.put("value2", EMObject::FLOAT, "A number reflecting total standard deviations in the left direction");
02243                         return d;
02244                 }
02245 
02246                 string get_desc() const
02247                 {
02248                         return "f(x) = mean if x<(mean-v2*sigma) or x>(mean+v1*sigma); else f(x) = x;";
02249                 }
02250 
02251                 static const string NAME;
02252 
02253           protected:
02254                 void process_pixel(float *x) const
02255                 {
02256                         if (*x < (mean - value2 * sigma) || *x > (mean + value1 * sigma))
02257                         {
02258                                 *x = mean;
02259                         }
02260                 }
02261 
02262           private:
02263                 float value1;
02264                 float value2;
02265         };
02266 
02269         class LogProcessor:public RealPixelProcessor
02270         {
02271           public:
02272                 string get_name() const
02273                 {
02274                         return NAME;
02275                 }
02276                 static Processor *NEW()
02277                 {
02278                         return new LogProcessor();
02279                 }
02280 
02281                 string get_desc() const
02282                 {
02283                         return "f(x) = log10(x) if x > 0; else f(x) = 0;";
02284                 }
02285 
02286                 static const string NAME;
02287 
02288           protected:
02289                 void process_pixel(float *x) const
02290                 {
02291                         if (*x > 0)
02292                         {
02293                                 *x = log10(*x);
02294                         }
02295                         else
02296                         {
02297                                 *x = 0;
02298                         }
02299                 }
02300         };
02301 
02304         class CoordinateProcessor:public Processor
02305         {
02306           public:
02307                 CoordinateProcessor():nx(0), ny(0), nz(0), mean(0), sigma(0), maxval(0), is_complex(false)
02308                 {
02309                 }
02310                 void process_inplace(EMData * image);
02311 
02312                 static string get_group_desc()
02313                 {
02314                         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().";
02315                 }
02316 
02317           protected:
02318                 virtual void process_pixel(float *pixel, int xi, int yi, int zi) const = 0;
02319                 virtual void calc_locals(EMData *)
02320                 {
02321                 }
02322                 virtual bool is_valid() const
02323                 {
02324                         return true;
02325                 }
02326 
02327                 int nx;
02328                 int ny;
02329                 int nz;
02330                 float mean;
02331                 float sigma;
02332                 float maxval;
02333 
02334                 bool is_complex;
02335         };
02336 
02344         class CircularMaskProcessor:public CoordinateProcessor
02345         {
02346           public:
02347                 CircularMaskProcessor():inner_radius(0), outer_radius(0), inner_radius_square(0),
02348                         outer_radius_square(0), dx(0), dy(0), dz(0), xc(0), yc(0), zc(0)
02349                 {
02350                 }
02351 
02352                 void set_params(const Dict & new_params)
02353                 {
02354                         params = new_params;
02355 
02356                         if (params.has_key("inner_radius")) {
02357                                 inner_radius = params["inner_radius"];
02358                                 inner_radius_square = inner_radius * inner_radius;
02359                         }
02360                         else {
02361                                 inner_radius = -1;
02362                                 inner_radius_square = -1;
02363                         }
02364 
02365                         if (params.has_key("outer_radius")) {
02366                                 outer_radius = params["outer_radius"];
02367                                 outer_radius_square = outer_radius * outer_radius;
02368                         }
02369                         else {
02370                                 outer_radius = INT_MAX;
02371                                 outer_radius_square = INT_MAX;
02372                         }
02373 
02374                         if (params.has_key("xc")) xc = params["xc"];
02375                         if (params.has_key("yc")) yc = params["yc"];
02376                         if (params.has_key("zc")) zc = params["zc"];
02377                         if (params.has_key("dx")) dx = params["dx"];
02378                         if (params.has_key("dy")) dy = params["dy"];
02379                         if (params.has_key("dz")) dz = params["dz"];
02380                 }
02381 
02382                 string get_desc() const
02383                 {
02384                         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().";
02385                 }
02386 
02387                 TypeDict get_param_types() const
02388                 {
02389                         TypeDict d;
02390 
02391                         d.put("inner_radius", EMObject::INT, "inner mask radius. optional");
02392                         d.put("outer_radius", EMObject::INT, "outer mask radius. Negative value -> box radius + outer_radius +1");
02393 
02394                         d.put("dx", EMObject::FLOAT,
02395                                   "Modify mask center by dx relative to the default center nx/2");
02396                         d.put("dy", EMObject::FLOAT,
02397                                   "Modify mask center by dy relative to the default center ny/2");
02398                         d.put("dz", EMObject::FLOAT,
02399                                   "Modify mask center by dz relative to the default center nz/2");
02400 
02401                         return d;
02402                 }
02403           protected:
02404                 void calc_locals(EMData * image);
02405 
02406                 bool is_valid() const
02407                 {
02408                         return (!is_complex);
02409                 }
02410 
02411                 void process_pixel(float *pixel, int xi, int yi, int zi) const
02412                 {
02413                         float dist = (xi - xc) * (xi - xc) + (yi - yc) * (yi - yc) + (zi - zc) * (zi - zc);
02414                         process_dist_pixel(pixel, dist);
02415                 }
02416 
02417                 virtual void process_dist_pixel(float *pixel, float dist) const = 0;
02418 
02419                 int inner_radius;
02420                 int outer_radius;
02421                 int inner_radius_square;
02422                 int outer_radius_square;
02423                 float dx, dy, dz;
02424                 float xc, yc, zc;
02425         };
02426 
02430         class MaskSharpProcessor:public CircularMaskProcessor
02431         {
02432           public:
02433                 MaskSharpProcessor():value(0)
02434                 {
02435                 }
02436 
02437                 string get_name() const
02438                 {
02439                         return NAME;
02440                 }
02441                 static Processor *NEW()
02442                 {
02443                         return new MaskSharpProcessor();
02444                 }
02445 
02446                 void set_params(const Dict & new_params)
02447                 {
02448                         CircularMaskProcessor::set_params(new_params);
02449                         value = params.set_default("value",0.0f);
02450                 }
02451 
02452                 TypeDict get_param_types() const
02453                 {
02454                         TypeDict d = CircularMaskProcessor::get_param_types();
02455                         d.put("value", EMObject::FLOAT, "step cutoff to this value. Default is 0.");
02456                         return d;
02457                 }
02458 
02459                 string get_desc() const
02460                 {
02461                         return "step cutoff to a user-given value in both inner and outer circles.";
02462                 }
02463 
02464                 static const string NAME;
02465 
02466           protected:
02467                 void process_dist_pixel(float *pixel, float dist) const
02468                 {
02469                         if (dist >= outer_radius_square || dist < inner_radius_square)
02470                         {
02471                                 *pixel = value;
02472                         }
02473                 }
02474 
02475                 float value;
02476         };
02477 
02478 
02482         class MaskEdgeMeanProcessor:public CircularMaskProcessor
02483         {                                                       // 6
02484           public:
02485                 string get_name() const
02486                 {
02487                         return NAME;
02488                 }
02489                 static Processor *NEW()
02490                 {
02491                         return new MaskEdgeMeanProcessor();
02492                 }
02493 
02494                 void set_params(const Dict & new_params)
02495                 {
02496                         CircularMaskProcessor::set_params(new_params);
02497                         ring_width = params["ring_width"];
02498                         if (ring_width == 0) {
02499                                 ring_width = 1;
02500                         }
02501                 }
02502 
02503                 TypeDict get_param_types() const
02504                 {
02505                         TypeDict d = CircularMaskProcessor::get_param_types();
02506                         d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02507                         return d;
02508                 }
02509 
02510                 string get_desc() const
02511                 {
02512                         return "A step cutoff to the the mean value in a ring centered on the outer radius";
02513                 }
02514 
02515                 static const string NAME;
02516 
02517           protected:
02518                 void calc_locals(EMData * image);
02519 
02520 
02521                 void process_dist_pixel(float *pixel, float dist) const
02522                 {
02523                         if (dist >= outer_radius_square || dist < inner_radius_square){
02524                                 *pixel = ring_avg;
02525                         }
02526                 }
02527 
02528           private:
02529                 int ring_width;
02530                 float ring_avg;
02531         };
02532 
02535         class MaskNoiseProcessor:public CircularMaskProcessor
02536         {
02537           public:
02538                 string get_name() const
02539                 {
02540                         return NAME;
02541                 }
02542                 static Processor *NEW()
02543                 {
02544                         return new MaskNoiseProcessor();
02545                 }
02546 
02547                 string get_desc() const
02548                 {
02549                         return "fills masked region";
02550                 }
02551 
02552                 static const string NAME;
02553 
02554           protected:
02555                 void process_dist_pixel(float *pixel, float dist) const
02556                 {
02557                         if (dist >= outer_radius_square || dist < inner_radius_square)
02558                         {
02559                                 *pixel = Util::get_gauss_rand(mean, sigma);
02560                         }
02561                 }
02562         };
02563 
02566         class MaskGaussProcessor:public CircularMaskProcessor
02567         {
02568           public:
02569                 string get_name() const
02570                 {
02571                         return NAME;
02572                 }
02573                 static Processor *NEW()
02574                 {
02575                         return new MaskGaussProcessor();
02576                 }
02577 
02578                 void set_params(const Dict & new_params)
02579                 {
02580                         CircularMaskProcessor::set_params(new_params);
02581                         exponent = params["exponent"];
02582                         if (exponent <= 0.0) {
02583                                 exponent = 2.0;
02584                         }
02585                 }
02586 
02587                 TypeDict get_param_types() const
02588                 {
02589                         TypeDict d = CircularMaskProcessor::get_param_types();
02590                         d.put("exponent", EMObject::FLOAT, "The exponent, f in e^-Bs^f. default 2.0, producing a Gaussian");
02591                         return d;
02592                 }
02593 
02594                 string get_desc() const
02595                 {
02596                         return "a gaussian falloff to zero, radius is the 1/e of the width. If inner_radius>0, then \
02597 outer radius specifies width of Gaussian starting at inner_radius rather than total radius.";
02598                 }
02599 
02600                 static const string NAME;
02601 
02602           protected:
02603                 float exponent;
02604                 void process_dist_pixel(float *pixel, float dist) const
02605                 {
02606                         if (inner_radius_square>0) {
02607                                 if (dist>inner_radius_square) {
02608                                         if (exponent==2.0f) (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,2.0f) / outer_radius_square);
02609                                         else (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,exponent) / pow((float)outer_radius_square,exponent/2.0f));
02610                                 }
02611                         }
02612                         else {
02613                                 if (exponent==2.0f) (*pixel) *= exp(-dist / outer_radius_square);
02614                                 else (*pixel) *= exp(-pow(dist,exponent/2.0f) / pow((float)outer_radius_square,exponent/2.0f));
02615                         }
02616                 }
02617         };
02618 
02625         class MaskGaussNonuniformProcessor:public CoordinateProcessor
02626         {
02627           public:
02628                 MaskGaussNonuniformProcessor():radius_x(0), radius_y(0), radius_z(0), gauss_width(0)
02629                 {
02630                 }
02631 
02632                 void set_params(const Dict & new_params)
02633                 {
02634                         params = new_params;
02635 
02636                         if (params.has_key("radius_x")) radius_x=params["radius_x"];
02637                         else radius_x=5.0;
02638 
02639                         if (params.has_key("radius_y")) radius_y=params["radius_y"];
02640                         else radius_y=5.0;
02641 
02642                         if (params.has_key("radius_z")) radius_z=params["radius_z"];
02643                         else radius_z=5.0;
02644 
02645                         if (params.has_key("gauss_width")) gauss_width=params["gauss_width"];
02646                         else gauss_width=0.05f;
02647                 }
02648 
02649                 TypeDict get_param_types() const
02650                 {
02651                         TypeDict d;
02652 
02653                         d.put("radius_x", EMObject::INT, "x-axis radius");
02654                         d.put("radius_y", EMObject::INT, "y-axis radius");
02655                         d.put("radius_z", EMObject::INT, "z-axis radius");
02656                         d.put("gauss_width", EMObject::FLOAT, "Gaussian falloff width, relative to each radius, default 0.05");
02657 
02658                         return d;
02659                 }
02660 
02661                 string get_name() const
02662                 {
02663                         return NAME;
02664                 }
02665                 static Processor *NEW()
02666                 {
02667                         return new MaskGaussNonuniformProcessor();
02668                 }
02669 
02670                 string get_desc() const
02671                 {
02672                         return "A Gaussian falloff to zero. Nonisotropic, specify inner radius for x,y,z and Gaussian falloff width. Falloff \
02673 width is also nonisotropic and relative to the radii, with 1 being equal to the radius on that axis.";
02674                 }
02675 
02676                 static const string NAME;
02677 
02678           protected:
02679                 void process_pixel(float *pixel, int xi, int yi, int zi) const
02680                 {
02681                         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);
02682                         if (dist>1.0) (*pixel)*=exp(-pow((sqrt(dist)-1.0f)/gauss_width,2.0f));
02683                 }
02684 
02685                 float radius_x,radius_y,radius_z,gauss_width;
02686         };
02687 
02692         class MaskGaussInvProcessor:public CircularMaskProcessor
02693         {
02694           public:
02695                 TypeDict get_param_types() const
02696                 {
02697                         TypeDict d = CircularMaskProcessor::get_param_types();
02698                         d.put("gauss_width", EMObject::FLOAT, "Used to calculate the constant factor - gauss_width / (ny*ny)" );
02699                         d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02700                         return d;
02701                 }
02702 
02703                 string get_name() const
02704                 {
02705                         return NAME;
02706                 }
02707 
02708                 static Processor *NEW()
02709                 {
02710                         return new MaskGaussInvProcessor();
02711                 }
02712 
02713                 string get_desc() const
02714                 {
02715                         return "f(x) = f(x) / exp(-radius*radius * gauss_width / (ny*ny))";
02716                 }
02717 
02718                 static const string NAME;
02719 
02720           protected:
02721                 void calc_locals(EMData *)
02722                 {
02723                         float gauss_width = params["gauss_width"];
02724                         slice_value = gauss_width / (ny * ny);
02725                 }
02726 
02727                 void process_dist_pixel(float *pixel, float dist) const
02728                 {
02729                         (*pixel) /= exp(-dist * slice_value);
02730                 }
02731           private:
02732                 float slice_value;
02733         };
02734 
02735 
02740         class LinearPyramidProcessor:public Processor
02741         {
02742           public:
02743                 string get_name() const
02744                 {
02745                         return NAME;
02746                 }
02747 
02748                 void process_inplace(EMData *image);
02749 
02750                 static Processor *NEW()
02751                 {
02752                         return new LinearPyramidProcessor();
02753                 }
02754 
02755                 string get_desc() const
02756                 {
02757                         return "Multiplies image by a 'linear pyramid', 1-(|x-xsize/2|*|y-ysize/2|*4/(xsize*ysize))";
02758                 }
02759 
02760                 static const string NAME;
02761         };
02762 
02763 
02766         class MakeRadiusSquaredProcessor:public CircularMaskProcessor
02767         {
02768           public:
02769                 string get_name() const
02770                 {
02771                         return NAME;
02772                 }
02773                 static Processor *NEW()
02774                 {
02775                         return new MakeRadiusSquaredProcessor();
02776                 }
02777 
02778                 string get_desc() const
02779                 {
02780                         return "overwrites input, f(x) = radius * radius";
02781                 }
02782 
02783                 static const string NAME;
02784 
02785           protected:
02786                 void process_dist_pixel(float *pixel, float dist) const
02787                 {
02788                         *pixel = dist;
02789                 }
02790         };
02791 
02794         class MakeRadiusProcessor:public CircularMaskProcessor
02795         {
02796           public:
02797                 string get_name() const
02798                 {
02799                         return NAME;
02800                 }
02801                 static Processor *NEW()
02802                 {
02803                         return new MakeRadiusProcessor();
02804                 }
02805 
02806                 string get_desc() const
02807                 {
02808                         return "overwrites input, f(x) = radius;";
02809                 }
02810 
02811                 static const string NAME;
02812 
02813           protected:
02814                 void process_dist_pixel(float *pixel, float dist) const
02815                 {
02816                         *pixel = sqrt(dist);
02817                 }
02818         };
02819 
02822         class ComplexPixelProcessor:public Processor
02823         {
02824           public:
02825                 void process_inplace(EMData * image);
02826 
02827                 static string get_group_desc()
02828                 {
02829                         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.";
02830                 }
02831 
02832           protected:
02833                 virtual void process_pixel(float *x) const = 0;
02834         };
02835 
02838         class ComplexNormPixel:public ComplexPixelProcessor
02839         {
02840           public:
02841                 string get_name() const
02842                 {
02843                         return NAME;
02844                 }
02845                 static Processor *NEW()
02846                 {
02847                         return new ComplexNormPixel();
02848                 }
02849 
02850                 string get_desc() const
02851                 {
02852                         return "Each Fourier pixel will be normalized. ie - amp=1, phase=unmodified. Useful for performing phase-residual-like computations with dot products.";
02853                 }
02854 
02855                 static const string NAME;
02856 
02857           protected:
02858                 void process_pixel(float *x) const
02859                 {
02860                         *x=1.0;
02861                 }
02862         };
02863 
02867         class AreaProcessor:public Processor
02868         {
02869           public:
02870                 AreaProcessor():areasize(0), kernel(0), nx(0), ny(0), nz(0)
02871                 {
02872                 }
02873 
02874                 void process_inplace(EMData * image);
02875 
02876                 void set_params(const Dict & new_params)
02877                 {
02878                         params = new_params;
02879                         areasize = params["areasize"];
02880                 }
02881 
02882                 TypeDict get_param_types() const
02883                 {
02884                         TypeDict d;
02885                         d.put("areasize", EMObject::INT, "The width of the area to process (not radius)");
02886                         return d;
02887                 }
02888 
02889                 string get_desc() const
02890                 {
02891                         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().";
02892                 }
02893 
02894           protected:
02895                 virtual void process_pixel(float *pixel, float, float, float, float *area_matrix) const
02896                 {
02897                         for (int i = 0; i < matrix_size; i++)
02898                         {
02899                                 *pixel += area_matrix[i] * kernel[i];
02900                         }
02901                 }
02902 
02903                 virtual void create_kernel() const = 0;
02904 
02905                 int areasize;
02906                 int matrix_size;
02907                 float *kernel;
02908                 int nx;
02909                 int ny;
02910                 int nz;
02911         };
02912 
02915         class LaplacianProcessor:public AreaProcessor
02916         {
02917           public:
02918                 string get_name() const
02919                 {
02920                         return NAME;
02921                 }
02922                 static Processor *NEW()
02923                 {
02924                         return new LaplacianProcessor();
02925                 }
02926 
02927                 string get_desc() const
02928                 {
02929                         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).";
02930                 }
02931 
02932                 static const string NAME;
02933 
02934           protected:
02935                 void create_kernel() const;
02936 
02937         };
02938 
02941         class ZeroConstantProcessor:public AreaProcessor
02942         {
02943           public:
02944                 string get_name() const
02945                 {
02946                         return NAME;
02947                 }
02948                 static Processor *NEW()
02949                 {
02950                         return new ZeroConstantProcessor();
02951                 }
02952 
02953                 string get_desc() const
02954                 {
02955                         return "Contraction of data, if any nearest neighbor is 0, value -> 0, generally used iteratively";
02956                 }
02957 
02958                 static const string NAME;
02959 
02960           protected:
02961                 void process_pixel(float *pixel, float, float, float, float *matrix) const
02962                 {
02963                         if (*pixel != 0)
02964                         {
02965                                 if (*pixel == matrix[1] || *pixel == matrix[3] || *pixel == matrix[5] ||
02966                                         *pixel == matrix[7] || matrix[1] == 0 || matrix[3] == 0 ||
02967                                         matrix[5] == 0 || matrix[7] == 0) {
02968                                         *pixel = 0;
02969                                 }
02970                         }
02971                 }
02972 
02973                 void create_kernel() const
02974                 {
02975                 }
02976         };
02977 
02986         class BoxStatProcessor:public Processor
02987         {
02988           public:
02989                 void process_inplace(EMData * image);
02990 
02991                 static string get_group_desc()
02992                 {
02993                         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).";
02994                 }
02995 
02996                 TypeDict get_param_types() const
02997                 {
02998                         TypeDict d;
02999                         d.put("radius", EMObject::INT, "The radius of the search box, default is 1 which results in a 3x3 box (3 = 2xradius + 1)");
03000                         return d;
03001                 }
03002 
03003           protected:
03004                 virtual void process_pixel(float *pixel, const float *array, int n) const = 0;
03005         };
03006 
03007 
03010         class BoxMedianProcessor:public BoxStatProcessor
03011         {
03012           public:
03013                 string get_name() const
03014                 {
03015                         return NAME;
03016                 }
03017                 static Processor *NEW()
03018                 {
03019                         return new BoxMedianProcessor();
03020                 }
03021 
03022                 string get_desc() const
03023                 {
03024                         return "A processor for noise reduction. pixel = median of values surrounding pixel.";
03025                 }
03026 
03027                 static const string NAME;
03028 
03029           protected:
03030                 void process_pixel(float *pixel, const float *array, int n) const
03031                 {
03032                         float *data = new float[n];
03033                         memcpy(data, array, sizeof(float) * n);
03034 
03035                         for (int i = 0; i <= n / 2; i++)
03036                         {
03037                                 for (int j = i + 1; j < n; j++)
03038                                 {
03039                                         if (data[i] < data[j]) {
03040                                                 float t = data[i];
03041                                                 data[i] = data[j];
03042                                                 data[j] = t;
03043                                         }
03044                                 }
03045                         }
03046 
03047                         if (n % 2 != 0)
03048                         {
03049                                 *pixel = data[n / 2];
03050                         }
03051                         else {
03052                                 *pixel = (data[n / 2] + data[n / 2 - 1]) / 2;
03053                         }
03054                         if( data )
03055                         {
03056                                 delete[]data;
03057                                 data = 0;
03058                         }
03059                 }
03060         };
03061 
03064         class BoxSigmaProcessor:public BoxStatProcessor
03065         {
03066           public:
03067                 string get_name() const
03068                 {
03069                         return NAME;
03070                 }
03071                 static Processor *NEW()
03072                 {
03073                         return new BoxSigmaProcessor();
03074                 }
03075 
03076                 string get_desc() const
03077                 {
03078                         return "pixel = standard deviation of values surrounding pixel.";
03079                 }
03080 
03081                 static const string NAME;
03082 
03083           protected:
03084                 void process_pixel(float *pixel, const float *data, int n) const
03085                 {
03086                         float sum = 0;
03087                         float square_sum = 0;
03088                         for (int i = 0; i < n; i++)
03089                         {
03090                                 sum += data[i];
03091                                 square_sum += data[i] * data[i];
03092                         }
03093 
03094                         float mean = sum / n;
03095                         *pixel = sqrt(square_sum / n - mean * mean);
03096                 }
03097         };
03098 
03101         class BoxMaxProcessor:public BoxStatProcessor
03102         {
03103           public:
03104                 string get_name() const
03105                 {
03106                         return NAME;
03107                 }
03108                 static Processor *NEW()
03109                 {
03110                         return new BoxMaxProcessor();
03111                 }
03112 
03113                 string get_desc() const
03114                 {
03115                         return "peak processor: pixel = max of values surrounding pixel.";
03116                 }
03117 
03118                 static const string NAME;
03119 
03120           protected:
03121                 void process_pixel(float *pixel, const float *data, int n) const
03122                 {
03123                         float maxval = -FLT_MAX;
03124                         for (int i = 0; i < n; i++)
03125                         {
03126                                 if (data[i] > maxval) {
03127                                         maxval = data[i];
03128                                 }
03129                         }
03130                          *pixel = maxval;
03131                 }
03132         };
03133 
03136         class MinusPeakProcessor:public BoxStatProcessor
03137         {
03138           public:
03139                 string get_name() const
03140                 {
03141                         return NAME;
03142                 }
03143                 static Processor *NEW()
03144                 {
03145                         return new MinusPeakProcessor();
03146                 }
03147 
03148                 string get_desc() const
03149                 {
03150                         return "peak processor: pixel = pixel - max of values surrounding pixel. This is a sort of positive peak-finding algorithm.";
03151                 }
03152 
03153                 static const string NAME;
03154 
03155           protected:
03156                 void process_pixel(float *pixel, const float *data, int n) const
03157                 {
03158                         float maxval = -FLT_MAX;
03159                         for (int i = 0; i < n; i++)
03160                         {
03161                                 if (data[i] > maxval) {
03162                                         maxval = data[i];
03163                                 }
03164                         }
03165                          *pixel -= maxval;
03166                 }
03167         };
03168 
03172         class PeakOnlyProcessor:public BoxStatProcessor
03173         {
03174           public:
03175                 string get_name() const
03176                 {
03177                         return NAME;
03178                 }
03179                 static Processor *NEW()
03180                 {
03181                         return new PeakOnlyProcessor();
03182                 }
03183                 void set_params(const Dict & new_params)
03184                 {
03185                         params = new_params;
03186                         npeaks = params["npeaks"];
03187                         if (npeaks == 0) {
03188                                 npeaks = 1;
03189                         }
03190                 }
03191 
03192                 TypeDict get_param_types() const
03193                 {
03194                         TypeDict d;
03195                         d.put("npeaks", EMObject::INT, "the number of surrounding peaks allow to >= pixel values");
03196                         return d;
03197                 }
03198 
03199                 string get_desc() const
03200                 {
03201                         return "peak processor -> if npeaks or more surrounding values >= value, value->0";
03202                 }
03203 
03204                 static const string NAME;
03205 
03206           protected:
03207                 void process_pixel(float *pixel, const float *data, int n) const
03208                 {
03209                         int r = 0;
03210 
03211                         for (int i = 0; i < n; i++)
03212                         {
03213                                 if (data[i] >= *pixel) {
03214                                         r++;
03215                                 }
03216                         }
03217 
03218                         if (r > npeaks)
03219                         {
03220                                 *pixel = 0;
03221                         }
03222                 }
03223           private:
03224                 int npeaks;
03225         };
03226 
03231         class DiffBlockProcessor:public Processor
03232         {
03233           public:
03234                 void process_inplace(EMData * image);
03235 
03236                 string get_name() const
03237                 {
03238                         return NAME;
03239                 }
03240                 static Processor *NEW()
03241                 {
03242                         return new DiffBlockProcessor();
03243                 }
03244 
03245                 string get_desc() const
03246                 {
03247                         return "averages over cal_half_width, then sets the value in a local block";
03248                 }
03249 
03250                 TypeDict get_param_types() const
03251                 {
03252                         TypeDict d;
03253                         d.put("cal_half_width", EMObject::FLOAT, "cal_half_width is dx/dy for calculating an average");
03254                         d.put("fill_half_width", EMObject::FLOAT, "fill_half_width is dx/dy for fill/step");
03255                         return d;
03256                 }
03257 
03258                 static const string NAME;
03259         };
03260 
03265         class CutoffBlockProcessor:public Processor
03266         {
03267           public:
03268                 void process_inplace(EMData * image);
03269 
03270                 string get_name() const
03271                 {
03272                         return NAME;
03273                 }
03274                 static Processor *NEW()
03275                 {
03276                         return new CutoffBlockProcessor();
03277                 }
03278 
03279                 TypeDict get_param_types() const
03280                 {
03281                         TypeDict d;
03282                         d.put("value1", EMObject::FLOAT, "val1 is dx/dy");
03283                         d.put("value2", EMObject::FLOAT, "val2 is lowpass freq cutoff in pixels");
03284                         return d;
03285                 }
03286 
03287                 string get_desc() const
03288                 {
03289                         return "Block processor, val1 is dx/dy, val2 is lp freq cutoff in pixels. Mystery processor.";
03290                 }
03291 
03292                 static const string NAME;
03293         };
03294 
03300         class BooleanShrinkProcessor
03301         {
03302                 protected:
03310                         template<class LogicOp>
03311                         EMData* process(const EMData *const image, Dict& params);
03312 
03319                         template<class LogicOp>
03320                         void process_inplace(EMData * image, Dict& params);
03321 
03322         };
03323 
03332         class MaxShrinkProcessor:public BooleanShrinkProcessor, public Processor
03333         {
03334                 public:
03341                         virtual EMData* process(const EMData *const image)
03342                         {
03343                                 return BooleanShrinkProcessor::process<GreaterThan>(image, params);
03344                         }
03345 
03346                         // resizes the image
03347                         virtual void process_inplace(EMData * image)
03348                         {
03349                                 BooleanShrinkProcessor::process_inplace<GreaterThan>(image, params);
03350                         }
03351 
03352                         string get_desc() const
03353                         {
03354                                 return "Shrink an image by a given amount (default 2), using the maximum value found in the pixel neighborhood.";
03355                         }
03356 
03357                         string get_name() const
03358                         {
03359                                 return NAME;
03360                         }
03361                         static Processor *NEW()
03362                         {
03363                                 return new MaxShrinkProcessor();
03364                         }
03365 
03366                         TypeDict get_param_types() const
03367                         {
03368                                 TypeDict d;
03369                                 d.put("n", EMObject::INT, "The shrink factor");
03370                                 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03371                                 return d;
03372                         }
03373 
03374                         static const string NAME;
03375 
03376                 private:
03377                         struct GreaterThan
03378                         {
03379                                 inline bool operator()(float left,float right) const { return left > right; }
03380                                 inline float get_start_val() { return -10000000; }
03381                         };
03382         };
03383 
03392         class MinShrinkProcessor:public BooleanShrinkProcessor, public Processor
03393         {
03394                 public:
03401                         virtual EMData* process(const EMData *const image)
03402                         {
03403                                 return BooleanShrinkProcessor::process<LessThan>(image, params);
03404                         }
03405 
03406                         // resizes the image
03407                         virtual void process_inplace(EMData * image)
03408                         {
03409                                 BooleanShrinkProcessor::process_inplace<LessThan>(image, params);
03410                         }
03411                         string get_desc() const
03412                         {
03413                                 return "Shrink an image by a given amount (default 2), using the minimum value found in the pixel neighborhood.";
03414                         }
03415 
03416                         string get_name() const
03417                         {
03418                                 return NAME;
03419                         }
03420                         static Processor *NEW()
03421                         {
03422                                 return new MinShrinkProcessor();
03423                         }
03424 
03425                         TypeDict get_param_types() const
03426                         {
03427                                 TypeDict d;
03428                                 d.put("n", EMObject::INT, "The shrink factor");
03429                                 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03430                                 return d;
03431                         }
03432 
03433                         static const string NAME;
03434 
03435                 private:
03436                 struct LessThan
03437                 {
03438                         inline bool operator()(float left,float right) const { return left < right; }
03439                         inline float get_start_val() { return 9999999999.0f; }
03440                 };
03441         };
03442 
03449         class MeanShrinkProcessor : public Processor
03450         {
03451                 public:
03462                         virtual EMData* process(const EMData *const image);
03463 
03470                         virtual void process_inplace(EMData * image);
03471 
03472                         string get_desc() const
03473                         {
03474                                 return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
03475                         }
03476 
03477                         virtual string get_name() const
03478                         {
03479                                 return NAME;
03480                         }
03481                         static Processor *NEW()
03482                         {
03483                                 return new MeanShrinkProcessor();
03484                         }
03485 
03486                         virtual TypeDict get_param_types() const
03487                         {
03488                                 TypeDict d;
03489                                 d.put("n", EMObject::FLOAT, "The shrink factor");
03490                                 return d;
03491                         }
03492 
03493                         static const string NAME;
03494 
03495                 private:
03503                         void accrue_mean(EMData* to, const EMData *const from, const int shrinkfactor);
03504 
03511                         void accrue_mean_one_p_five(EMData* to, const EMData * const from);
03512         };
03513 
03514 
03521         class MedianShrinkProcessor : public Processor
03522         {
03523         public:
03534                 virtual EMData* process(const EMData *const image);
03535 
03542                 virtual void process_inplace(EMData * image);
03543 
03544                 string get_desc() const
03545                 {
03546                         return "Shrink an image by a given amount , using the median value found in the pixel neighborhood.";
03547                 }
03548 
03549                 virtual string get_name() const
03550                 {
03551                         return NAME;
03552                 }
03553                 static Processor *NEW()
03554                 {
03555                         return new MedianShrinkProcessor();
03556                 }
03557 
03558                 virtual TypeDict get_param_types() const
03559                 {
03560                         TypeDict d;
03561                         d.put("n", EMObject::INT, "The shrink factor");
03562                         return d;
03563                 }
03564 
03565                 static const string NAME;
03566 
03567         private:
03575                 void accrue_median(EMData* to, const EMData* const from,const int shrink_factor);
03576         };
03577 
03578 
03587         class FFTResampleProcessor : public Processor
03588         {
03589                 public:
03590                         virtual EMData* process(const EMData *const image);
03591 
03592                         virtual void process_inplace(EMData * image);
03593 
03594                         string get_desc() const
03595                         {
03596                                 return "Robust resampling of an image by clipping its Fourier transform.";
03597                         }
03598 
03599                         string get_name() const
03600                         {
03601                                 return NAME;
03602                         }
03603                         static Processor *NEW()
03604                         {
03605                                 return new FFTResampleProcessor();
03606                         }
03607 
03608                         TypeDict get_param_types() const
03609                         {
03610                                 TypeDict d;
03611                                 d.put("n", EMObject::FLOAT, "The sample rate. Less than one enlarges the image, greater than one shrinks it.");
03612                                 return d;
03613                         }
03614 
03615                         static const string NAME;
03616 
03617                 private:
03624                         void fft_resample(EMData* to, const EMData *const from, const float& sample_rate);
03625 
03626         };
03627 
03630         class GradientRemoverProcessor:public Processor
03631         {
03632           public:
03633                 void process_inplace(EMData * image);
03634 
03635                 string get_name() const
03636                 {
03637                         return NAME;
03638                 }
03639                 static Processor *NEW()
03640                 {
03641                         return new GradientRemoverProcessor();
03642                 }
03643 
03644                 string get_desc() const
03645                 {
03646                         return "Gradient remover, does a rough plane fit to find linear gradients.";
03647                 }
03648 
03649                 static const string NAME;
03650         };
03651 
03660         class GradientPlaneRemoverProcessor:public Processor
03661     {
03662           public:
03663                 void process_inplace(EMData * image);
03664 
03665                 string get_name() const
03666                 {
03667                         return NAME;
03668                 }
03669                 static Processor *NEW()
03670                 {
03671                         return new GradientPlaneRemoverProcessor();
03672                 }
03673 
03674                 string get_desc() const
03675                 {
03676                         return "Remove gradient by least square plane fit";
03677                 }
03678 
03679                 TypeDict get_param_types() const
03680                 {
03681                         TypeDict d;
03682                         d.put("mask", EMObject::EMDATA, "mask object: nonzero pixel positions will be used to fit plane. default = 0");
03683                         d.put("changeZero", EMObject::INT, "if zero pixels are modified when removing gradient. default = 0");
03684                         d.put("planeParam", EMObject::FLOATARRAY, "fitted plane parameters output");
03685                         return d;
03686                 }
03687 
03688                 static const string NAME;
03689         };
03690 
03696         class NonConvexProcessor:public Processor
03697     {
03698           public:
03699                 void process_inplace(EMData * image);
03700 
03701                 string get_name() const
03702                 {
03703                         return NAME;
03704                 }
03705                 static Processor *NEW()
03706                 {
03707                         return new NonConvexProcessor();
03708                 }
03709 
03710                 string get_desc() const
03711                 {
03712                         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).";
03713                 }
03714 
03715                 TypeDict get_param_types() const
03716                 {
03717                         TypeDict d;
03718 /*                      d.put("mask", EMObject::EMDATA, "mask object: nonzero pixel positions will be used to fit plane. default = 0");
03719                         d.put("changeZero", EMObject::INT, "if zero pixels are modified when removing gradient. default = 0");
03720                         d.put("planeParam", EMObject::FLOATARRAY, "fitted plane parameters output");*/
03721                         return d;
03722                 }
03723 
03724                 static const string NAME;
03725         };
03726 
03733         class FlattenBackgroundProcessor:public Processor
03734         {
03735                 public:
03736                         void process_inplace(EMData * image);
03737 
03738                         string get_name() const
03739                         {
03740                                 return NAME;
03741                         }
03742 
03743                         static Processor *NEW()
03744                         {
03745                                 return new FlattenBackgroundProcessor();
03746                         }
03747 
03748                         string get_desc() const
03749                         {
03750                                 return "Flattens the background by subtracting the local mean";
03751                         }
03752 
03753                         TypeDict get_param_types() const
03754                         {
03755                                 TypeDict d;
03756                                 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");
03757                                 d.put("radius", EMObject::INT, "The radius of circle/sphere that defines the local neighborhood. Exclusive of the mask argument");
03758                                 return d;
03759                         }
03760 
03761                         static const string NAME;
03762         };
03763 
03764 
03767         class RampProcessor:public Processor
03768     {
03769           public:
03770                 void process_inplace(EMData * image);
03771 
03772                 string get_name() const
03773                 {
03774                         return NAME;
03775                 }
03776                 static Processor *NEW()
03777                 {
03778                         return new RampProcessor();
03779                 }
03780 
03781                 string get_desc() const
03782                 {
03783                         return "Ramp processor -- Fits a least-squares plane "
03784                                    "to the picture, and subtracts the plane from "
03785                                    "the picture.  A wedge-shaped overall density "
03786                                    "profile can thus be removed from the picture.";
03787                 }
03788 
03789                 static const string NAME;
03790         };
03791 
03794         class VerticalStripeProcessor:public Processor
03795         {
03796           public:
03797                 void process_inplace(EMData * image);
03798 
03799                 string get_name() const
03800                 {
03801                         return NAME;
03802                 }
03803 
03804                 static Processor *NEW()
03805                 {
03806                         return new VerticalStripeProcessor();
03807                 }
03808 
03809                 string get_desc() const
03810                 {
03811                         return "Tries to fix images scanned on the zeiss for poor ccd normalization.";
03812                 }
03813 
03814                 static const string NAME;
03815         };
03816 
03819         class RealToFFTProcessor:public Processor
03820         {
03821                 public:
03822                 void process_inplace(EMData *image);
03823 
03824                 string get_name() const
03825                 {
03826                         return NAME;
03827                 }
03828 
03829                 static Processor *NEW()
03830                 {
03831                         return new RealToFFTProcessor();
03832                 }
03833 
03834                 string get_desc() const
03835                 {
03836                         return "This will replace the image with a full-circle 2D fft amplitude rendering. Note that this renders amplitude, when intensity is more common.";
03837                 }
03838 
03839                 static const string NAME;
03840         };
03841 
03842 
03845         class SigmaZeroEdgeProcessor:public Processor
03846         {
03847           public:
03848                 void process_inplace(EMData * image);
03849 
03850                 string get_name() const
03851                 {
03852                         return NAME;
03853                 }
03854                 static Processor *NEW()
03855                 {
03856                         return new SigmaZeroEdgeProcessor();
03857                 }
03858 
03859                 string get_desc() const
03860                 {
03861                         return "Fill zeroes at edges with nearest horizontal/vertical value.";
03862                 }
03863 
03864                 static const string NAME;
03865         };
03866 
03872         class BeamstopProcessor:public Processor
03873         {
03874           public:
03875                 void process_inplace(EMData * image);
03876 
03877                 string get_name() const
03878                 {
03879                         return NAME;
03880                 }
03881 
03882                 static Processor *NEW()
03883                 {
03884                         return new BeamstopProcessor();
03885                 }
03886 
03887                 string get_desc() const
03888                 {
03889                         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.";
03890                 }
03891 
03892                 TypeDict get_param_types() const
03893                 {
03894                         TypeDict d;
03895                         d.put("value1", EMObject::FLOAT, "sig multiplier");
03896                         d.put("value2", EMObject::FLOAT, "x of center");
03897                         d.put("value3", EMObject::FLOAT, "y of center");
03898                         return d;
03899                 }
03900 
03901                 static const string NAME;
03902         };
03903 
03906         class MeanZeroEdgeProcessor:public Processor
03907         {
03908           public:
03909                 void process_inplace(EMData * image);
03910 
03911                 string get_name() const
03912                 {
03913                         return NAME;
03914                 }
03915 
03916                 static Processor *NEW()
03917                 {
03918                         return new MeanZeroEdgeProcessor();
03919                 }
03920 
03921                 string get_desc() const
03922                 {
03923                         return "Fill zeroes at edges with nearest horizontal/vertical value damped towards Mean2.";
03924                 }
03925 
03926                 static const string NAME;
03927         };
03928 
03929 
03932         class AverageXProcessor:public Processor
03933         {
03934           public:
03935                 void process_inplace(EMData * image);
03936 
03937                 string get_name() const
03938                 {
03939                         return NAME;
03940                 }
03941 
03942                 static Processor *NEW()
03943                 {
03944                         return new AverageXProcessor();
03945                 }
03946 
03947                 string get_desc() const
03948                 {
03949                         return "Average along Y and replace with average";
03950                 }
03951 
03952                 static const string NAME;
03953         };
03954 
03958         class DecayEdgeProcessor:public Processor
03959         {
03960           public:
03961                 void process_inplace(EMData * image);
03962                 string get_name() const
03963                 {
03964                         return NAME;
03965                 }
03966 
03967                 static Processor *NEW()
03968                 {
03969                         return new DecayEdgeProcessor();
03970                 }
03971 
03972                 string get_desc() const
03973                 {
03974                         return "Decay edges of image to zero";
03975                 }
03976 
03977                 TypeDict get_param_types() const
03978                 {
03979                         TypeDict d;
03980                         d.put("width", EMObject::INT, "Width of the decay region around the edge of the image in pixels");
03981                         return d;
03982                 }
03983 
03984                 static const string NAME;
03985         };
03986 
03993         class ZeroEdgeRowProcessor:public Processor
03994         {
03995           public:
03996                 void process_inplace(EMData * image);
03997                 string get_name() const
03998                 {
03999                         return NAME;
04000                 }
04001 
04002                 static Processor *NEW()
04003                 {
04004                         return new ZeroEdgeRowProcessor();
04005                 }
04006 
04007                 string get_desc() const
04008                 {
04009                         return "zero edges of image on top and bottom, and on left and right.";
04010                 }
04011 
04012                 TypeDict get_param_types() const
04013                 {
04014                         TypeDict d;
04015                         d.put("x0", EMObject::INT, "The number of columns to zero from left");
04016                         d.put("x1", EMObject::INT, "The number of columns to zero from right");
04017                         d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
04018                         d.put("y1", EMObject::INT, "The number of rows to zero from the top");
04019                         return d;
04020                 }
04021 
04022                 static const string NAME;
04023         };
04024 
04033         class ZeroEdgePlaneProcessor:public Processor
04034         {
04035           public:
04036                 void process_inplace(EMData * image);
04037                 string get_name() const
04038                 {
04039                         return NAME;
04040                 }
04041 
04042                 static Processor *NEW()
04043                 {
04044                         return new ZeroEdgePlaneProcessor();
04045                 }
04046 
04047                 string get_desc() const
04048                 {
04049                         return "zero edges of volume on all sides";
04050                 }
04051 
04052                 TypeDict get_param_types() const
04053                 {
04054                         TypeDict d;
04055                         d.put("x0", EMObject::INT, "The number of columns to zero from left");
04056                         d.put("x1", EMObject::INT, "The number of columns to zero from right");
04057                         d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
04058                         d.put("y1", EMObject::INT, "The number of rows to zero from the top");
04059                         d.put("z0", EMObject::INT, "The number of slices to zero from the bottom");
04060                         d.put("z1", EMObject::INT, "The number of slices to zero from the top");
04061                         return d;
04062                 }
04063 
04064                 static const string NAME;
04065         };
04066 
04067 
04074         class BilateralProcessor:public Processor
04075         {
04076           public:
04077                 void process_inplace(EMData * image);
04078                 string get_name() const
04079                 {
04080                         return NAME;
04081                 }
04082 
04083                 string get_desc() const
04084                 {
04085                         return "Bilateral processing on 2D or 3D volume data. Bilateral processing does non-linear weighted averaging processing within a certain window. ";
04086                 }
04087 
04088                 static Processor *NEW()
04089                 {
04090                         return new BilateralProcessor();
04091                 }
04092 
04093                 TypeDict get_param_types() const
04094                 {
04095                         TypeDict d;
04096                         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.");
04097                         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.");
04098                         d.put("niter", EMObject::INT, "how many times to apply this processing on your data.");
04099                         d.put("half_width", EMObject::INT, "processing window size = (2 * half_widthh + 1) ^ 3.");
04100                         return d;
04101                 }
04102 
04103                 static const string NAME;
04104         };
04105 
04108         class NormalizeProcessor:public Processor
04109         {
04110           public:
04111                 void process_inplace(EMData * image);
04112 
04113                 static string get_group_desc()
04114                 {
04115                         return "Base class for normalization processors. Each specific normalization processor needs to define how to calculate mean and how to calculate sigma.";
04116                 }
04117 
04118           protected:
04119                 virtual float calc_sigma(EMData * image) const;
04120                 virtual float calc_mean(EMData * image) const = 0;
04121         };
04122 
04125         class NormalizeUnitProcessor:public NormalizeProcessor
04126         {
04127           public:
04128                 string get_name() const
04129                 {
04130                         return NAME;
04131                 }
04132 
04133                 static Processor *NEW()
04134                 {
04135                         return new NormalizeUnitProcessor();
04136                 }
04137 
04138                 string get_desc() const
04139                 {
04140                         return "Normalize an image so its vector length is 1.0.";
04141                 }
04142 
04143                 static const string NAME;
04144 
04145           protected:
04146                 float calc_sigma(EMData * image) const;
04147                 float calc_mean(EMData * image) const;
04148         };
04149 
04150         inline float NormalizeUnitProcessor::calc_mean(EMData *) const { return 0; }
04151 
04154         class NormalizeUnitSumProcessor:public NormalizeProcessor
04155         {
04156           public:
04157                 string get_name() const
04158                 {
04159                         return NAME;
04160                 }
04161 
04162                 static Processor *NEW()
04163                 {
04164                         return new NormalizeUnitSumProcessor();
04165                 }
04166 
04167                 string get_desc() const
04168                 {
04169                         return "Normalize an image so its elements sum to 1.0 (fails if mean=0)";
04170                 }
04171 
04172                 static const string NAME;
04173 
04174           protected:
04175                 float calc_sigma(EMData * image) const;
04176                 float calc_mean(EMData * image) const;
04177         };
04178 
04179         inline float NormalizeUnitSumProcessor::calc_mean(EMData *) const { return 0; }
04180 
04181 
04184         class NormalizeStdProcessor:public NormalizeProcessor
04185         {
04186           public:
04187                 string get_name() const
04188                 {
04189                         return NAME;
04190                 }
04191 
04192                 static Processor *NEW()
04193                 {
04194                         return new NormalizeStdProcessor();
04195                 }
04196 
04197                 string get_desc() const
04198                 {
04199                         return "do a standard normalization on an image.";
04200                 }
04201 
04202                 static const string NAME;
04203 
04204           protected:
04205                 float calc_mean(EMData * image) const;
04206         };
04207 
04212         class NormalizeMaskProcessor:public NormalizeProcessor
04213         {
04214           public:
04215                 string get_name() const
04216                 {
04217                         return NAME;
04218                 }
04219 
04220                 string get_desc() const
04221                 {
04222                         return "Uses a 1/0 mask defining a region to use for the zero-normalization.if no_sigma is 1, standard deviation not modified.";
04223                 }
04224 
04225                 static Processor *NEW()
04226                 {
04227                         return new NormalizeMaskProcessor();
04228                 }
04229 
04230                 TypeDict get_param_types() const
04231                 {
04232                         TypeDict d;
04233                         d.put("mask", EMObject::EMDATA, "the 1/0 mask defining a region to use for the zero-normalization");
04234                         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");
04235                         return d;
04236                 }
04237 
04238                 static const string NAME;
04239 
04240           protected:
04241                 float calc_sigma(EMData * image) const;
04242                 float calc_mean(EMData * image) const;
04243         };
04244 
04250         class NormalizeRampNormVar: public Processor
04251         {
04252                 public:
04253                         string get_name() const
04254                         {
04255                                 return NAME;
04256                         }
04257 
04258                         static Processor *NEW()
04259                         {
04260                                 return new NormalizeRampNormVar();
04261                         }
04262 
04263                         string get_desc() const
04264                         {
04265                                 return "First call filter.ramp on the image, then make the mean 0 and norm 1";
04266                         }
04267 
04268                         void process_inplace(EMData * image);
04269 
04270                         static const string NAME;
04271         };
04272 
04281         class NormalizeByMassProcessor: public Processor
04282         {
04283                 public:
04284                         string get_name() const
04285                         {
04286                                 return NAME;
04287                         }
04288 
04289                         static Processor *NEW()
04290                         {
04291                                 return new NormalizeByMassProcessor();
04292                         }
04293 
04294                         string get_desc() const
04295                         {
04296                                 return "Normalize the mass of the image assuming a density of 1.35 g/ml (0.81 Da/A^3) (3D only)";
04297                         }
04298 
04299                         TypeDict get_param_types() const
04300                         {
04301                                 TypeDict d;
04302                                 d.put("apix", EMObject::FLOAT,"Angstrom per pixel of the image. If not set will use the apix_x attribute of the image");
04303                                 d.put("mass", EMObject::FLOAT,"The approximate mass of protein/structure in kilodaltons");
04304                                 d.put("thr", EMObject::FLOAT,"The isosurface threshold which encapsulates the structure");
04305                                 return d;
04306                         }
04307 
04308                         void process_inplace(EMData * image);
04309 
04310                         static const string NAME;
04311         };
04312 
04313 
04316         class NormalizeEdgeMeanProcessor:public NormalizeProcessor
04317         {
04318           public:
04319                 string get_name() const
04320                 {
04321                         return NAME;
04322                 }
04323 
04324                 static Processor *NEW()
04325                 {
04326                         return new NormalizeEdgeMeanProcessor();
04327                 }
04328 
04329                 string get_desc() const
04330                 {
04331                         return "normalizes an image, mean value equals to edge mean.";
04332                 }
04333 
04334                 static const string NAME;
04335 
04336           protected:
04337                 float calc_mean(EMData * image) const;
04338         };
04339 
04342         class NormalizeCircleMeanProcessor:public NormalizeProcessor
04343         {
04344           public:
04345                 string get_name() const
04346                 {
04347                         return NAME;
04348                 }
04349 
04350                 static Processor *NEW()
04351                 {
04352                         return new NormalizeCircleMeanProcessor();
04353                 }
04354 
04355                 string get_desc() const
04356                 {
04357                         return "normalizes an image, mean value equals to mean of 2 pixel circular border.";
04358                 }
04359 
04360                 static const string NAME;
04361 
04362           protected:
04363                 float calc_mean(EMData * image) const;
04364         };
04365 
04368         class NormalizeLREdgeMeanProcessor:public NormalizeProcessor
04369         {
04370           public:
04371                 string get_name() const
04372                 {
04373                         return NAME;
04374                 }
04375 
04376                 static Processor *NEW()
04377                 {
04378                         return new NormalizeLREdgeMeanProcessor();
04379                 }
04380 
04381                 string get_desc() const
04382                 {
04383                         return "normalizes an image, uses 2 pixels on left and right edge";
04384                 }
04385 
04386                 static const string NAME;
04387 
04388           protected:
04389                 float calc_mean(EMData * image) const;
04390         };
04391 
04394         class NormalizeMaxMinProcessor:public NormalizeProcessor
04395         {
04396           public:
04397                 string get_name() const
04398                 {
04399                         return NAME;
04400                 }
04401 
04402                 static Processor *NEW()
04403                 {
04404                         return new NormalizeMaxMinProcessor();
04405                 }
04406 
04407                 string get_desc() const
04408                 {
04409                         return "normalizes an image. mean -> (maxval-minval)/2; std dev = (maxval+minval)/2;";
04410                 }
04411 
04412                 static const string NAME;
04413 
04414           protected:
04415                 float calc_sigma(EMData * image) const;
04416                 float calc_mean(EMData * image) const;
04417         };
04418 
04421         class NormalizeRowProcessor:public Processor
04422         {
04423           public:
04424                 string get_name() const
04425                 {
04426                         return NAME;
04427                 }
04428 
04429                 static Processor *NEW()
04430                 {
04431                         return new NormalizeRowProcessor();
04432                 }
04433 
04434                 string get_desc() const
04435                 {
04436                         return "normalizes each row in the image individually";
04437                 }
04438 
04439                 static const string NAME;
04440 
04441                 void process_inplace(EMData * image);
04442         };
04443 
04449         class NormalizeToLeastSquareProcessor:public Processor
04450         {
04451           public:
04452                 void process_inplace(EMData * image);
04453 
04454                 string get_name() const
04455                 {
04456                         return NAME;
04457                 }
04458 
04459                 static Processor *NEW()
04460                 {
04461                         return new NormalizeToLeastSquareProcessor();
04462                 }
04463 
04464                 TypeDict get_param_types() const
04465                 {
04466                         TypeDict d;
04467                         d.put("to", EMObject::EMDATA, "reference image normalize to");
04468                         d.put("ignore_zero", EMObject::BOOL, "If set, ignores any pixels which are exactly zero in either image. Defaut = True.");
04469                         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)");
04470                         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)");
04471                         return d;
04472                 }
04473 
04474                 string get_desc() const
04475                 {
04476                         return "use least square method to normalize";
04477                 }
04478 
04479                 static const string NAME;
04480         };
04481 
04484         class RotationalAverageProcessor:public Processor
04485         {
04486           public:
04487                 void process_inplace(EMData * image);
04488 
04489                 string get_name() const
04490                 {
04491                         return NAME;
04492                 }
04493 
04494                 static Processor *NEW()
04495                 {
04496                         return new RotationalAverageProcessor();
04497                 }
04498 
04499                 string get_desc() const
04500                 {
04501                         return "Makes image circularly/spherically symmetric.";
04502                 }
04503 
04504                 static const string NAME;
04505         };
04506 
04509         class RotationalSubstractProcessor:public Processor
04510         {
04511           public:
04512                 virtual void process_inplace(EMData * image);
04513 
04514                 virtual string get_name() const
04515                 {
04516                         return NAME;
04517                 }
04518 
04519                 static Processor *NEW()
04520                 {
04521                         return new RotationalSubstractProcessor();
04522                 }
04523 
04524                 virtual string get_desc() const
04525                 {
04526                         return "subtracts circularly/spherically symmetric part of an image.";
04527                 }
04528 
04529                 static const string NAME;
04530         };
04531 
04537         class TransposeProcessor:public Processor
04538         {
04539           public:
04540 
04545                 virtual void process_inplace(EMData * image);
04546 
04551                 virtual EMData* process(const EMData * const image);
04552 
04553                 virtual string get_name() const
04554                 {
04555                         return NAME;
04556                 }
04557 
04558                 static Processor *NEW()
04559                 {
04560                         return new TransposeProcessor();
04561                 }
04562 
04563                 virtual TypeDict get_param_types() const
04564                 {
04565                         TypeDict d;
04566                         return d;
04567                 }
04568 
04569                 virtual string get_desc() const
04570                 {
04571                         return "Get the transpose of an image. Works for 2D only";
04572                 }
04573 
04574                 static const string NAME;
04575         };
04576 
04577 
04581         class FlipProcessor:public Processor
04582         {
04583           public:
04584                 virtual void process_inplace(EMData * image);
04585 
04586                 virtual string get_name() const
04587                 {
04588                         return NAME;
04589                 }
04590 
04591                 static Processor *NEW()
04592                 {
04593                         return new FlipProcessor();
04594                 }
04595 
04596                 virtual TypeDict get_param_types() const
04597                 {
04598                         TypeDict d;
04599                         d.put("axis", EMObject::STRING, "'x', 'y', or 'z' axis.");
04600                         return d;
04601                 }
04602 
04603                 virtual string get_desc() const
04604                 {
04605                         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.";
04606                 }
04607 
04608                 static const string NAME;
04609         };
04610 
04611         /*class FlipProcessor1:public Processor
04612         {
04613           public:
04614                 void process_inplace(EMData * image);
04615 
04616                 string get_name() const
04617                 {
04618                         return "xform.flip1";
04619                 }
04620 
04621                 static Processor *NEW()
04622                 {
04623                         return new FlipProcessor1();
04624                 }
04625 
04626                 TypeDict get_param_types() const
04627                 {
04628                         TypeDict d;
04629                         d.put("axis", EMObject::STRING, "'x', 'y', or 'z' axis. 'x' means horizonal flip; 'y' means vertical flip;");
04630                         return d;
04631                 }
04632 
04633                 string get_desc() const
04634                 {
04635                         return "flip an image around an axis.";
04636                 }
04637 
04638         };*/
04639 
04644         class AddNoiseProcessor:public Processor
04645         {
04646           public:
04647                 virtual void process_inplace(EMData * image);
04648 
04649                 virtual string get_name() const
04650                 {
04651                         return NAME;
04652                 }
04653 
04654                 static Processor *NEW()
04655                 {
04656                         return new AddNoiseProcessor();
04657                 }
04658 
04659                 virtual TypeDict get_param_types() const
04660                 {
04661                         TypeDict d;
04662                         d.put("noise", EMObject::FLOAT, "noise factor used to generate Gaussian distribution random noise");
04663                         d.put("seed", EMObject::INT, "seed for random number generator");
04664                         return d;
04665                 }
04666 
04667                 virtual string get_desc() const
04668                 {
04669                         return "add noise to an image, image multiply by noise then add a random value";
04670                 }
04671 
04672                 static const string NAME;
04673 
04674           protected:
04675                 virtual float get_sigma(EMData *)
04676                 {
04677                         return 1.0;
04678                 }
04679         };
04680 
04683         class AddSigmaNoiseProcessor:public AddNoiseProcessor
04684         {
04685           public:
04686                 virtual string get_name() const
04687                 {
04688                         return NAME;
04689                 }
04690 
04691                 static Processor *NEW()
04692                 {
04693                         return new AddSigmaNoiseProcessor();
04694                 }
04695 
04696                 virtual string get_desc() const
04697                 {
04698                         return "add sigma noise.";
04699                 }
04700 
04701                 static const string NAME;
04702 
04703           protected:
04704                 float get_sigma(EMData * image);
04705         };
04706 
04715         class AddRandomNoiseProcessor:public Processor
04716         {
04717           public:
04718                 virtual void process_inplace(EMData * image);
04719 
04720                 virtual string get_name() const
04721                 {
04722                         return NAME;
04723                 }
04724 
04725                 static Processor *NEW()
04726                 {
04727                         return new AddRandomNoiseProcessor();
04728                 }
04729 
04730                 virtual TypeDict get_param_types() const
04731                 {
04732                         TypeDict d;
04733                         d.put("n", EMObject::INT);
04734                         d.put("x0", EMObject::FLOAT);
04735                         d.put("dx", EMObject::FLOAT);
04736                         d.put("y", EMObject::FLOATARRAY);
04737                         d.put("interpolation", EMObject::INT);
04738                         d.put("seed", EMObject::INT, "seed for random number generator");
04739                         return d;
04740                 }
04741 
04742                 virtual string get_desc() const
04743                 {
04744                         return "add spectral noise to a complex image.";
04745                 }
04746 
04747                 static const string NAME;
04748         };
04749 
04755         class FourierToCornerProcessor:public Processor
04756         {
04757                 public:
04763                         virtual void process_inplace(EMData * image);
04764 
04765                         virtual string get_name() const
04766                         {
04767                                 return NAME;
04768                         }
04769 
04770                         static Processor *NEW()
04771                         {
04772                                 return new FourierToCornerProcessor();
04773                         }
04774 
04775                         virtual string get_desc() const
04776                         {
04777                                 return "Undoes the xform.fourierorigin.tocenter processor";
04778                         }
04779 
04780                         static const string NAME;
04781         };
04782 
04783 
04795         class FourierToCenterProcessor:public Processor
04796         {
04797                 public:
04803                         virtual void process_inplace(EMData * image);
04804 
04805                         virtual string get_name() const
04806                         {
04807                                 return NAME;
04808                         }
04809 
04810                         static Processor *NEW()
04811                         {
04812                                 return new FourierToCenterProcessor();
04813                         }
04814 
04815                         virtual string get_desc() const
04816                         {
04817                                 return "Translates the origin in Fourier space from the corner to the center in y and z - works in 2D and 3D";
04818                         }
04819 
04820                         static const string NAME;
04821         };
04822 
04832         class Phase180Processor:public Processor
04833         {
04834                 protected:
04847                         void swap_corners_180(EMData * image);
04848 
04860                         void swap_central_slices_180(EMData * image);
04861 
04868                         void fourier_phaseshift180(EMData * image);
04869 
04870         };
04871 
04881         class PhaseToCenterProcessor:public Phase180Processor
04882         {
04883                 public:
04884                         virtual void process_inplace(EMData * image);
04885 
04886                         virtual string get_name() const
04887                         {
04888                                 return NAME;
04889                         }
04890 
04891                         static Processor *NEW()
04892                         {
04893                                 return new PhaseToCenterProcessor();
04894                         }
04895 
04896                         virtual string get_desc() const
04897                         {
04898                                 return "Undoes the effect of the xform.phaseorigin.tocorner processor";
04899                         }
04900 
04901                         static const string NAME;
04902         };
04903 
04911         class PhaseToCornerProcessor:public Phase180Processor
04912         {
04913                 public:
04914                         virtual void process_inplace(EMData * image);
04915 
04916                         virtual string get_name() const
04917                         {
04918                                 return NAME;
04919                         }
04920 
04921                         static Processor *NEW()
04922                         {
04923                                 return new PhaseToCornerProcessor();
04924                         }
04925 
04926                         virtual string get_desc() const
04927                         {
04928                                 return "Translates a centered image to the corner in a forward fashion";
04929                         }
04930 
04931                         static const string NAME;
04932         };
04933 
04938         class AutoMask2DProcessor:public Processor
04939         {
04940           public:
04941                 virtual void process_inplace(EMData * image);
04942 
04943                 virtual string get_name() const
04944                 {
04945                         return NAME;
04946                 }
04947 
04948                 static Processor *NEW()
04949                 {
04950                         return new AutoMask2DProcessor();
04951                 }
04952 
04953                 virtual TypeDict get_param_types() const
04954                 {
04955                         TypeDict d;
04956                         d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
04957                         d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
04958                         d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
04959                         d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
04960                         d.put("nshells", EMObject::INT, "The number of dilation operations");
04961                         d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
04962                         d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
04963                         d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
04964                         return d;
04965                 }
04966 
04967                 virtual string get_desc() const
04968                 {
04969                         return "2D version of mask.auto3d";
04970                 }
04971 
04972                 static const string NAME;
04973         };
04974 
04975 
04982         class AutoMaskAsymUnit:public Processor
04983         {
04984                 public:
04985                         virtual void process_inplace(EMData * image);
04986 
04987                         virtual string get_name() const
04988                         {
04989                                 return NAME;
04990                         }
04991 
04992                         static Processor *NEW()
04993                         {
04994                                 return new AutoMaskAsymUnit();
04995                         }
04996 
04997                         virtual TypeDict get_param_types() const
04998                         {
04999                                 TypeDict d;
05000                                 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.");
05001                                 d.put("sym", EMObject::STRING, "The symmetry, for example, d7");
05002                                 return d;
05003                         }
05004 
05005                         virtual string get_desc() const
05006                         {
05007                                 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.";
05008                         }
05009 
05010                         static const string NAME;
05011         };
05012 
05017         class AutoMask3DProcessor:public Processor
05018         {
05019           public:
05020                 virtual void process_inplace(EMData * image);
05021 
05022                 virtual string get_name() const
05023                 {
05024                         return NAME;
05025                 }
05026 
05027                 static Processor *NEW()
05028                 {
05029                         return new AutoMask3DProcessor();
05030                 }
05031 
05032                 virtual TypeDict get_param_types() const
05033                 {
05034                         TypeDict d;
05035                         d.put("threshold1", EMObject::FLOAT);
05036                         d.put("threshold2", EMObject::FLOAT);
05037                         return d;
05038                 }
05039 
05040                 virtual string get_desc() const
05041                 {
05042                         return "Tries to mask out only interesting density";
05043                 }
05044 
05045                 static void search_nearby(float *dat, float *dat2, int nx, int ny, int nz, float thr);
05046                 static void fill_nearby(float *dat2, int nx, int ny, int nz);
05047 
05048                 static const string NAME;
05049         };
05050 
05058         class AutoMask3D2Processor:public Processor
05059         {
05060           public:
05061                 virtual void process_inplace(EMData * image);
05062 
05063                 virtual string get_name() const
05064                 {
05065                         return NAME;
05066                 }
05067 
05068                 static Processor *NEW()
05069                 {
05070                         return new AutoMask3D2Processor();
05071                 }
05072 
05073                 virtual string get_desc() const
05074                 {
05075                         return "This will mask a 3-D volume using a 'flood filling' approach. It begins with a seed generated either as a sphere with \
05076 specified 'radius' or with the 'nmaxseed' highest values. It then includes any mass connected to the seed with value higher than 'threshold'.\
05077 Next, the mask is expanded by 'nshells'+'nshellsgauss'/2 voxels. Finally a gaussian low-pass filter is applied with a width of 'nshellsgauss'.";
05078                 }
05079 
05080                 virtual TypeDict get_param_types() const
05081                 {
05082                         TypeDict d;
05083                         d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
05084                         d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
05085                         d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
05086                         d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
05087                         d.put("nshells", EMObject::INT, "Number of 1-voxel shells to expand the mask by.");
05088                         d.put("nshellsgauss", EMObject::INT, "Width in voxels of a Gaussian decay at the edge of the mask.");
05089                         d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
05090                         d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
05091                         return d;
05092                 }
05093 
05094                 static const string NAME;
05095         };
05096 
05100         class AddMaskShellProcessor:public Processor
05101         {
05102           public:
05103                 virtual void process_inplace(EMData * image);
05104 
05105                 virtual string get_name() const
05106                 {
05107                         return NAME;
05108                 }
05109 
05110                 virtual string get_desc() const
05111                 {
05112                         return "Add additional shells/rings to an existing 1/0 mask image";
05113                 }
05114 
05115                 static Processor *NEW()
05116                 {
05117                         return new AddMaskShellProcessor();
05118                 }
05119 
05120                 virtual TypeDict get_param_types() const
05121                 {
05122                         TypeDict d;
05123                         d.put("nshells", EMObject::INT, "number of shells to add");
05124                         return d;
05125                 }
05126 
05127                 static const string NAME;
05128         };
05129 
05134         class PhaseToMassCenterProcessor:public Processor
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 PhaseToMassCenterProcessor();
05147                         }
05148 
05149                         virtual string get_desc() const
05150                         {
05151                                 return "centers the image the center of mass, which is calculated using Fourier phases, ignores old dx, dy.";
05152                         }
05153 
05154                         virtual TypeDict get_param_types() const
05155                         {
05156                                 TypeDict d;
05157                                 d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05158                                 return d;
05159                         }
05160 
05161                         static const string NAME;
05162         };
05163 
05168         class ToMassCenterProcessor:public Processor
05169         {
05170           public:
05171                 virtual void process_inplace(EMData * image);
05172 
05173                 virtual string get_name() const
05174                 {
05175                         return NAME;
05176                 }
05177 
05178                 static Processor *NEW()
05179                 {
05180                         return new ToMassCenterProcessor();
05181                 }
05182 
05183                 virtual string get_desc() const
05184                 {
05185                         return "ToMassCenterProcessor centers image at center of mass, with a threshold. Only values higher than the threshold are considered.";
05186                 }
05187 
05188                 virtual TypeDict get_param_types() const
05189                 {
05190                         TypeDict d;
05191                         d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05192                         d.put("threshold", EMObject::FLOAT, "Only values larger than the threshold are included in the center of mass computation. Default is 0.");
05193 //                      d.put("positive", EMObject::INT, "uses only densities >0 for the calculatton");
05194                         return d;
05195                 }
05196 
05197                 static const string NAME;
05198         };
05199 
05203         class ACFCenterProcessor:public Processor
05204         {
05205           public:
05206                 virtual void process_inplace(EMData * image);
05207 
05208                 virtual string get_name() const
05209                 {
05210                         return NAME;
05211                 }
05212 
05213                 static Processor *NEW()
05214                 {
05215                         return new ACFCenterProcessor();
05216                 }
05217 
05218                 virtual string get_desc() const
05219                 {
05220                         return "Center image using self-convolution.";
05221                 }
05222 
05223                 virtual TypeDict get_param_types() const
05224                 {
05225                         TypeDict d;
05226                         return d;
05227                 }
05228 
05229                 static const string NAME;
05230         };
05231 
05236         class SNRProcessor:public Processor
05237         {
05238           public:
05239                 virtual void process_inplace(EMData * image);
05240 
05241                 virtual string get_name() const
05242                 {
05243                         return NAME;
05244                 }
05245 
05246                 static Processor *NEW()
05247                 {
05248                         return new SNRProcessor();
05249                 }
05250 
05251                 virtual string get_desc() const
05252                 {
05253                         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.";
05254                 }
05255 
05256                 virtual TypeDict get_param_types() const
05257                 {
05258                         TypeDict d;
05259                         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");
05260                         d.put("snrfile", EMObject::STRING, "structure factor file name");
05261                         return d;
05262                 }
05263 
05264                 static const string NAME;
05265         };
05266 
05270         class FileFourierProcessor: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                 virtual string get_desc() const
05281                 {
05282                         return "A fourier processor specified in a 2 column text file.";
05283                 }
05284 
05285                 static Processor *NEW()
05286                 {
05287                         return new FileFourierProcessor();
05288                 }
05289 
05290                 virtual TypeDict get_param_types() const
05291                 {
05292                         TypeDict d;
05293                         d.put("filename", EMObject::STRING, "file name for a 2 column text file which specified a radial function data array.");
05294                         return d;
05295                 }
05296 
05297                 static const string NAME;
05298         };
05299 
05310         class SymSearchProcessor: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                 virtual string get_desc() const
05321                 {
05322                         return "Identifiy the best symmetry in the given symmetry list for each pixel and then apply the best symmetry to each pixel.";
05323                 }
05324 
05325                 static Processor *NEW()
05326                 {
05327                         return new SymSearchProcessor();
05328                 }
05329 
05330                 virtual TypeDict get_param_types() const
05331                 {
05332                         TypeDict d;
05333                         d.put("sym", EMObject::STRINGARRAY, "the list of symmetries to search");
05334                         d.put("thresh", EMObject::FLOAT, "the minimal level of symmetry to be accepted (0-1)");
05335                         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");
05336                         d.put("symlabel_map", EMObject::EMDATA, "the optional return map when output_symlabel=1");
05337                         return d;
05338                 }
05339 
05340                 static const string NAME;
05341         };
05342 
05348         class StripeXYProcessor:public Processor
05349         {
05350           public:
05351                 void process_inplace(EMData * image);
05352 
05353                 virtual string get_name() const
05354                 {
05355                         return NAME;
05356                 }
05357 
05358                 static Processor *NEW()
05359                 {
05360                         return new StripeXYProcessor();
05361                 }
05362 
05363                 virtual string get_desc() const
05364                 {
05365                         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";
05366                 }
05367 
05368                 virtual TypeDict get_param_types() const
05369                 {
05370                         TypeDict d;
05371                         d.put("xlen", EMObject::INT, "Integration 1/2 length on x axis in pixels. Default=10");
05372                         d.put("ylen", EMObject::INT, "Integration 1/2 length on y axis in pixels. Default=10");
05373                         return d;
05374                 }
05375 
05376                 static const string NAME;
05377         };
05378 
05379         
05385         class LocalNormProcessor:public Processor
05386         {
05387           public:
05388                 void process_inplace(EMData * image);
05389 
05390                 virtual string get_name() const
05391                 {
05392                         return NAME;
05393                 }
05394 
05395                 static Processor *NEW()
05396                 {
05397                         return new LocalNormProcessor();
05398                 }
05399 
05400                 virtual string get_desc() const
05401                 {
05402                         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.";
05403                 }
05404 
05405                 virtual TypeDict get_param_types() const
05406                 {
05407                         TypeDict d;
05408                         d.put("threshold", EMObject::FLOAT, "Only values above the threshold will be used to compute the normalization. Generally a good isosurface value.");
05409                         d.put("radius", EMObject::FLOAT, "Fourier filter radius expressed in pixels in Fourier space. cutoff_pixels in filter.lowpass.gauss");
05410                         d.put("apix", EMObject::FLOAT, "Angstroms per pixel");
05411                         return d;
05412                 }
05413 
05414                 static const string NAME;
05415         };
05416 
05421         class IndexMaskFileProcessor:public Processor
05422         {
05423           public:
05424                 virtual void process_inplace(EMData * image);
05425 
05426                 virtual string get_name() const
05427                 {
05428                         return NAME;
05429                 }
05430 
05431                 static Processor *NEW()
05432                 {
05433                         return new IndexMaskFileProcessor();
05434                 }
05435 
05436                 virtual TypeDict get_param_types() const
05437                 {
05438                         TypeDict d;
05439                         d.put("filename", EMObject::STRING, "mask image file name");
05440                         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");
05441                         return d;
05442                 }
05443 
05444                 virtual string get_desc() const
05445                 {
05446                         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.";
05447                 }
05448 
05449                 static const string NAME;
05450         };
05451 
05455         class CoordinateMaskFileProcessor:public Processor
05456         {
05457           public:
05458                 virtual void process_inplace(EMData * image);
05459 
05460                 virtual string get_name() const
05461                 {
05462                         return NAME;
05463                 }
05464 
05465                 static Processor *NEW()
05466                 {
05467                         return new CoordinateMaskFileProcessor();
05468                 }
05469 
05470                 virtual string get_desc() const
05471                 {
05472                         return "Multiplies the image by the specified file using pixel coordinates instead of pixel indices. The images can be different size.";
05473                 }
05474 
05475                 virtual TypeDict get_param_types() const
05476                 {
05477                         TypeDict d;
05478                         d.put("filename", EMObject::STRING, "mask image file name");
05479                         return d;
05480                 }
05481 
05482                 static const string NAME;
05483         };
05484 
05495         class PaintProcessor:public Processor
05496         {
05497           public:
05498                 PaintProcessor():x(0), y(0), z(0),r1(0), v1(0.0), r2(0), v2(0.0)
05499                 {
05500                 }
05501 
05502                 virtual string get_name() const
05503                 {
05504                         return NAME;
05505                 }
05506 
05507                 static Processor *NEW()
05508                 {
05509                         return new PaintProcessor();
05510                 }
05511 
05512                 virtual string get_desc() const
05513                 {
05514                         return "Paints a circle with a decaying edge into the image. r<r1 -> v1, r1<r<r2 -> (v1,v2), r>r2 unchanged";
05515                 }
05516 
05517                 virtual TypeDict get_param_types() const
05518                 {
05519                         TypeDict d;
05520                         d.put("x", EMObject::INT, "x coordinate for Center of circle");
05521                         d.put("y", EMObject::INT, "y coordinate for Center of circle");
05522                         d.put("z", EMObject::INT, "z coordinate for Center of circle");
05523                         d.put("r1", EMObject::INT, "Inner radius");
05524                         d.put("v1", EMObject::FLOAT, "Inner value");
05525                         d.put("r2", EMObject::INT, "Outter radius");
05526                         d.put("v2", EMObject::FLOAT, "Outer Value");
05527                         return d;
05528                 }
05529 
05530                 virtual void set_params(const Dict & new_params)
05531                 {
05532                         params = new_params;
05533 
05534                         if (params.has_key("x")) x = params["x"];
05535                         if (params.has_key("y")) y = params["y"];
05536                         if (params.has_key("z")) z = params["z"];
05537                         if (params.has_key("r1")) r1 = params["r1"];
05538                         if (params.has_key("r2")) r2 = params["r2"];
05539                         if (params.has_key("v1")) v1 = params["v1"];
05540                         if (params.has_key("v2")) v2 = params["v2"];
05541                 }
05542 
05543                 static const string NAME;
05544 
05545                 protected:
05546                 virtual void process_inplace(EMData *image);
05547 
05548                 int x,y,z,r1;
05549                 float v1;
05550                 int r2;
05551                 float v2;
05552 
05553         };
05554 
05555 
05560         class DirectionalSumProcessor : public Processor
05561         {
05562           public:
05563                 virtual string get_name() const
05564                 {
05565                         return NAME;
05566                 }
05567 
05568                 static Processor *NEW()
05569                 {
05570                         return new DirectionalSumProcessor();
05571                 }
05572 
05576                 virtual EMData* process(const EMData* const image);
05577 
05581                 virtual void process_inplace(EMData*) {
05582                         throw InvalidCallException("The directional sum processor does not work inplace");
05583                 }
05584 
05585                 virtual TypeDict get_param_types() const
05586                 {
05587                         TypeDict d;
05588                         d.put("axis", EMObject::STRING,"The direction of the sum, either x,y or z. Returned axes are xy, xz or zy.");
05589                         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)");
05590                         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)");
05591                         return d;
05592                 }
05593 
05594                 string get_desc() const
05595                 {
05596                         return "Calculates the projection of the image along one of the axial directions, either x, y or z";
05597                 }
05598 
05599                 static const string NAME;
05600         };
05601 
05609         class WatershedProcessor:public Processor
05610         {
05611           public:
05612                 virtual void process_inplace(EMData * image);
05613 
05614                 virtual string get_name() const
05615                 {
05616                         return NAME;
05617                 }
05618 
05619                 static Processor *NEW()
05620                 {
05621                         return new WatershedProcessor();
05622                 }
05623 
05624                 virtual string get_desc() const
05625                 {
05626                         return "Does a watershed";
05627                 }
05628 
05629                 virtual TypeDict get_param_types() const
05630                 {
05631                         TypeDict d;
05632                         d.put("xpoints", EMObject::FLOATARRAY,"x coordinates");
05633                         d.put("ypoints", EMObject::FLOATARRAY,"y coordinates");
05634                         d.put("zpoints", EMObject::FLOATARRAY,"z coordinates");
05635                         d.put("minval", EMObject::FLOAT,"min value");
05636                         return d;
05637                 }
05638 
05639                 static const string NAME;
05640 
05641           private:
05642                   vector<Vec3i > watershed(EMData* mask, EMData* image, const float& threshold, const Vec3i& cordinate, const int mask_value);
05643                   vector<Vec3i > find_region(EMData* mask,const vector<Vec3i >& coords, const int mask_value, vector<Vec3i >& region);
05644 
05645         };
05646 
05656         template<class Type>
05657         class BinaryOperateProcessor : public Processor{
05658                 public:
05663                         virtual void process_inplace(EMData * image) {
05664                                 if ( ! params.has_key("with") ) throw InvalidParameterException("You must supply the \"with\" parameter");
05665                                 EMData* with = params["with"];
05666 
05667                                 if ( with->get_xsize() != image->get_xsize() || with->get_ysize() != image->get_ysize() || with->get_zsize() != image->get_zsize() )
05668                                         throw ImageDimensionException("The images you are operating on do not have the same dimensions");
05669 
05670                                 float* image_data = image->get_data();
05671                                 float* with_data = with->get_data();
05672 
05673                                 std::transform(image_data,image_data+image->get_size(),with_data,image_data,Type::binary_operate);
05674                                 image->update();
05675                         }
05676 
05677                         virtual string get_name() const
05678                         {
05679                                 return op.get_name();
05680                         }
05681 
05682                         virtual string get_desc() const
05683                         {
05684                                 return op.get_desc();
05685                         }
05686 
05687                         static Processor *NEW()
05688                         {
05689                                 return new BinaryOperateProcessor<Type>();
05690                         }
05691 
05692                         virtual TypeDict get_param_types() const
05693                         {
05694                                 TypeDict d;
05695                                 d.put("with", EMObject::EMDATA,"The second image");
05696                                 return d;
05697                         }
05698 
05699                         static const string NAME;
05700                 private:
05701                         Type op;
05702         };
05703 
05704         class MaxPixelOperator {
05705                 public:
05706                 string get_name() const
05707                 {
05708                         return NAME;
05709                 }
05710 
05711                 string get_desc() const
05712                 {
05713                         return "Compares pixels in two images, returning an image with the maximum pixel value in each pixel location";
05714                 }
05715 
05716                 static float binary_operate(const float& left, const float& right) {
05717                         if (left > right) return left;
05718                         return right;
05719                 }
05720 
05721                 static const string NAME;
05722         };
05723 
05724         class MinPixelOperator {
05725                 public:
05726                         string get_name() const
05727                         {
05728                                 return NAME;
05729                         }
05730 
05731                         string get_desc() const
05732                         {
05733                                 return "Compares pixels in two images, returning an image with the minimum pixel value in each pixel location";
05734                         }
05735 
05736                         static float binary_operate(const float& left, const float& right) {
05737                                 if (left < right) return left;
05738                                 return right;
05739                         }
05740 
05741                         static const string NAME;
05742         };
05743 
05747         class MatchSFProcessor:public FourierAnlProcessor
05748         {
05749           public:
05750 
05751                 virtual string get_name() const
05752                 {
05753                         return NAME;
05754                 }
05755 
05756                 virtual string get_desc() const
05757                 {
05758                         return "Filters the image so its 1-D power spectrum matches a second image";
05759                 }
05760 
05761                 static Processor *NEW()
05762                 {
05763                         return new MatchSFProcessor();
05764                 }
05765 
05766                 virtual TypeDict get_param_types() const
05767                 {
05768                         TypeDict d;
05769                         d.put("to", EMObject::EMDATA, "The image to match with. Make sure apix values are correct.");
05770                         return d;
05771                 }
05772 
05773                 static const string NAME;
05774 
05775           protected:
05776                 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05777         };
05778 
05779 
05784         class SetSFProcessor:public FourierAnlProcessor
05785         {
05786           public:
05787 
05788                 virtual string get_name() const
05789                 {
05790                         return NAME;
05791                 }
05792 
05793                 virtual string get_desc() const
05794                 {
05795                         return "Filters the image so its 1-D power spectrum matches a supplied X-Y curve";
05796                 }
05797 
05798                 static Processor *NEW()
05799                 {
05800                         return new SetSFProcessor();
05801                 }
05802 
05803                 virtual TypeDict get_param_types() const
05804                 {
05805                         TypeDict d;
05806                         d.put("strucfac", EMObject::XYDATA, "An XYData object contaning the curve to be imposed as a function of S");
05807                         d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
05808                         return d;
05809                 }
05810 
05811                 static const string NAME;
05812 
05813           protected:
05814                 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05815         };
05816 
05820         class SmartMaskProcessor:public Processor
05821         {
05822           public:
05823                 virtual void process_inplace(EMData * image);
05824 
05825                 virtual string get_name() const
05826                 {
05827                         return NAME;
05828                 }
05829 
05830                 static Processor *NEW()
05831                 {
05832                         return new SmartMaskProcessor();
05833                 }
05834 
05835                 virtual string get_desc() const
05836                 {
05837                         return "Smart mask processor.";
05838                 }
05839 
05840                 virtual TypeDict get_param_types() const
05841                 {
05842                         TypeDict d;
05843                         d.put("mask", EMObject::FLOAT, "mask value");
05844                         return d;
05845                 }
05846 
05847                 static const string NAME;
05848         };
05849 
05854         class IterBinMaskProcessor:public Processor
05855         {
05856           public:
05857                 virtual void process_inplace(EMData * image);
05858 
05859                 virtual string get_name() const
05860                 {
05861                         return NAME;
05862                 }
05863 
05864                 virtual string get_desc() const
05865                 {
05866                         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.";
05867                 }
05868 
05869                 static Processor *NEW()
05870                 {
05871                         return new IterBinMaskProcessor();
05872                 }
05873 
05874                 virtual TypeDict get_param_types() const
05875                 {
05876                         TypeDict d;
05877                         d.put("val1", EMObject::FLOAT, "number of pixels to expand");
05878                         d.put("val2", EMObject::FLOAT, "number of Gaussian pixels to expand, following the first expansion");
05879                         return d;
05880                 }
05881 
05882                 static const string NAME;
05883         };
05884 
05887         class TestImageProcessor : public Processor
05888         {
05889         public:
05890                 static string get_group_desc()
05891                 {
05892                         return "Base class for a group of 'processors' used to create test image.";
05893                 }
05894 
05895         protected:
05896                 void preprocess(EMData * image);
05897                 int nx, ny, nz; //this is the size of the source image
05898         };
05899 
05908         class TestImagePureGaussian : public TestImageProcessor
05909         {
05910         public:
05911                 virtual void process_inplace(EMData * image);
05912 
05913                 virtual string get_name() const
05914                 {
05915                         return NAME;
05916                 }
05917 
05918                 virtual string get_desc() const
05919                 {
05920                         return "Replace a source image as a strict Gaussian ";
05921                 }
05922 
05923                 static Processor * NEW()
05924                 {
05925                         return new TestImagePureGaussian();
05926                 }
05927 
05928                 virtual TypeDict get_param_types() const
05929                 {
05930                         TypeDict d;
05931                         d.put("x_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on x direction");
05932                         d.put("y_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on y direction");
05933                         d.put("z_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on z direction");
05934                         d.put("x_center", EMObject::FLOAT, "center for this Gaussian blob on x direction" );
05935                         d.put("y_center", EMObject::FLOAT, "center for this Gaussian blob on y direction" );
05936                         d.put("z_center", EMObject::FLOAT, "center for this Gaussian blob on z direction" );
05937                         return d;
05938                 }
05939 
05940                 static const string NAME;
05941         };
05942 
05946         class TestImageFourierNoiseGaussian : public TestImageProcessor
05947         {
05948         public:
05949                 virtual void process_inplace(EMData * image);
05950 
05951                 virtual string get_name() const
05952                 {
05953                         return NAME;
05954                 }
05955 
05956                 virtual string get_desc() const
05957                 {
05958                         return "Replace a source image with pink Fourier noise, based on a Gaussian. Random phase.";
05959                 }
05960 
05961                 static Processor * NEW()
05962                 {
05963                         return new TestImageFourierNoiseGaussian();
05964                 }
05965 
05966                 virtual TypeDict get_param_types() const
05967                 {
05968                         TypeDict d;
05969                         d.put("sigma", EMObject::FLOAT, "sigma value");
05970                         return d;
05971                 }
05972 
05973                 static const string NAME;
05974         };
05975 
05980         class TestImageFourierNoiseProfile : public TestImageProcessor
05981         {
05982         public:
05983                 virtual void process_inplace(EMData * image);
05984 
05985                 virtual string get_name() const
05986                 {
05987                         return NAME;
05988                 }
05989 
05990                 virtual string get_desc() const
05991                 {
05992                         return "Replace a source image with Fourier noise using amplitude information that is stored in a profile.";
05993                 }
05994 
05995                 static Processor * NEW()
05996                 {
05997                         return new TestImageFourierNoiseProfile();
05998                 }
05999 
06000                 virtual TypeDict get_param_types() const
06001                 {
06002                         TypeDict d;
06003                         d.put("profile", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
06004                         return d;
06005                 }
06006 
06007                 static const string NAME;
06008         };
06009 
06010 
06015         class CTFSNRWeightProcessor : public TestImageProcessor
06016         {
06017                 public:
06018                         virtual void process_inplace(EMData * image);
06019 
06020                         virtual string get_name() const
06021                         {
06022                                 return NAME;
06023                         }
06024 
06025                         virtual string get_desc() const
06026                         {
06027                                 return "Weight the amplitudes of an image based on radial noise and snr curves ";
06028                         }
06029 
06030                         static Processor * NEW()
06031                         {
06032                                 return new CTFSNRWeightProcessor();
06033                         }
06034 
06035                         virtual TypeDict get_param_types() const
06036                         {
06037                                 TypeDict d;
06038                                 d.put("noise", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
06039                                 d.put("snr", EMObject::FLOATARRAY, "Squared amplitude divided by squared noise amplitude. As in, what is the EMAN2CTF.snr attribute");
06040                                 d.put("boost", EMObject::FLOAT, "Multiplicative signal boost");
06041                                 return d;
06042                         }
06043 
06044                         static const string NAME;
06045         };
06046 
06047 
06048 
06053         class TestImageLineWave : public TestImageProcessor
06054         {
06055                 public:
06056                         virtual void process_inplace(EMData * image);
06057 
06058                         virtual string get_name() const
06059                         {
06060                                 return NAME;
06061                         }
06062 
06063                         virtual string get_desc() const
06064                         {
06065                                 return "Insert an oscillating sine wave into the pixel data";
06066                         }
06067 
06068                         static Processor * NEW()
06069                         {
06070                                 return new TestImageLineWave();
06071                         }
06072 
06073                         virtual TypeDict get_param_types() const
06074                         {
06075                                 TypeDict d;
06076                                 d.put("period", EMObject::FLOAT, "The period of the oscillating sine wave. Default 10.");
06077                                 return d;
06078                         }
06079 
06080                         static const string NAME;
06081         };
06082 
06083 
06091         class TestTomoImage : public TestImageProcessor
06092         {
06093                 public:
06097                         virtual void process_inplace(EMData * image);
06098 
06099                         virtual string get_name() const
06100                         {
06101                                 return NAME;
06102                         }
06103 
06104                         virtual string get_desc() const
06105                         {
06106                                 return "Make an image consisting various objects, useful for tomographic testing";
06107                         }
06108 
06109                         static Processor * NEW()
06110                         {
06111                                 return new TestTomoImage();
06112                         }
06113 
06114                         static const string NAME;
06115 
06116                 private:
06117                         void insert_solid_ellipse( EMData* image, const Region& region, const float& value, const Transform& t3d  = Transform() );
06118                         void insert_hollow_ellipse( EMData* image, const Region& region, const float& value, const int& radius, const Transform& t3d = Transform() );
06119                         void insert_rectangle( EMData* image, const Region& region, const float& value, const Transform& t3d = Transform() );
06120         };
06121 
06129         class TestImageGradient : public TestImageProcessor
06130         {
06131                 public:
06132                         virtual void process_inplace(EMData * image);
06133 
06134                         virtual string get_name() const
06135                         {
06136                                 return NAME;
06137                         }
06138 
06139                         virtual string get_desc() const
06140                         {
06141                                 return "Make a gradient image of the form y=mx+b, where x is any of the image axes.";
06142                         }
06143 
06144                         static Processor * NEW()
06145                         {
06146                                 return new TestImageGradient();
06147                         }
06148 
06149                         virtual TypeDict get_param_types() const
06150                         {
06151                                 TypeDict d;
06152                                 d.put("axis", EMObject::STRING, "The axis the will be used to determine pixel values. Must be x,y or z");
06153                                 d.put("m", EMObject::FLOAT, "m in the equation m*axis+b. Default is 1.0");
06154                                 d.put("b", EMObject::FLOAT, "b in the equation m*axis+b. Default is 0.0");
06155                                 return d;
06156                         }
06157 
06158                         static const string NAME;
06159         };
06160 
06168         class TestImageAxes : public TestImageProcessor
06169         {
06170                 public:
06175                         virtual void process_inplace(EMData * image);
06176 
06177                         virtual string get_name() const
06178                         {
06179                                 return NAME;
06180                         }
06181 
06182                         virtual string get_desc() const
06183                         {
06184                                 return "Make an image consisting of a single cross";
06185                         }
06186 
06187                         static Processor * NEW()
06188                         {
06189                                 return new TestImageAxes();
06190                         }
06191 
06192                         virtual TypeDict get_param_types() const
06193                         {
06194                                 TypeDict d;
06195                                 d.put("int", EMObject::FLOAT, "radius of the lines emanating from the origin");
06196                                 d.put("fill", EMObject::FLOAT, "value to make non-zero pixels");
06197                                 return d;
06198                         }
06199 
06200                         static const string NAME;
06201         };
06202 
06208         class TestImageGaussian : public TestImageProcessor
06209         {
06210         public:
06211                 virtual void process_inplace(EMData * image);
06212 
06213                 virtual string get_name() const
06214                 {
06215                         return NAME;
06216                 }
06217 
06218                 virtual string get_desc() const
06219                 {
06220                         return "Replace a source image as a Gaussian Blob";
06221                 }
06222 
06223                 static Processor * NEW()
06224                 {
06225                         return new TestImageGaussian();
06226                 }
06227 
06228                 virtual TypeDict get_param_types() const
06229                 {
06230                         TypeDict d;
06231                         d.put("sigma", EMObject::FLOAT, "sigma value for this Gaussian blob");
06232                         d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06233                         d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06234                         return d;
06235                 }
06236 
06237                 static const string NAME;
06238         };
06239 
06242         class TestImageScurve : public TestImageProcessor
06243         {
06244         public:
06245                 virtual void process_inplace(EMData * image);
06246 
06247                 virtual string get_name() const
06248                 {
06249                         return NAME;
06250                 }
06251 
06252                 virtual string get_desc() const
06253                 {
06254                         return "Replace a source image with a lumpy S-curve used for alignment testing";
06255                 }
06256 
06257                 static Processor * NEW()
06258                 {
06259                         return new TestImageScurve();
06260                 }
06261 
06262                 virtual TypeDict get_param_types() const
06263                 {
06264                         TypeDict d;
06265                         return d;
06266                 }
06267 
06268                 static const string NAME;
06269         };
06270 
06278         class TestImageSphericalWave : public TestImageProcessor
06279         {
06280         public:
06281                 virtual void process_inplace(EMData * image);
06282 
06283                 virtual string get_name() const
06284                 {
06285                         return NAME;
06286                 }
06287 
06288                 virtual string get_desc() const
06289                 {
06290                         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)";
06291                 }
06292 
06293                 static Processor * NEW()
06294                 {
06295                         return new TestImageSphericalWave();
06296                 }
06297 
06298                 virtual TypeDict get_param_types() const
06299                 {
06300                         TypeDict d;
06301                         d.put("wavelength", EMObject::FLOAT, "cos(2*pi*r/wavelength+phase)");
06302                         d.put("phase", EMObject::FLOAT, "in radians");
06303                         d.put("x", EMObject::FLOAT, "center of the spherical wave");
06304                         d.put("y", EMObject::FLOAT, "center of the spherical wave");
06305                         d.put("z", EMObject::FLOAT, "center of the spherical wave");
06306                         return d;
06307                 }
06308 
06309                 static const string NAME;
06310         };
06311 
06312 
06321         class TestImageSinewave : public TestImageProcessor
06322         {
06323         public:
06324                 virtual void process_inplace(EMData * image);
06325 
06326                 virtual string get_name() const
06327                 {
06328                         return NAME;
06329                 }
06330 
06331                 virtual string get_desc() const
06332                 {
06333                         return "Replace a source image as a sine wave in specified wave length";
06334                 }
06335 
06336                 static Processor * NEW()
06337                 {
06338                         return new TestImageSinewave();
06339                 }
06340 
06341                 virtual TypeDict get_param_types() const
06342                 {
06343                         TypeDict d;
06344                         d.put("wavelength", EMObject::FLOAT, "wavelength in equation sin(x*2*PI/wavelength - phase*180/PI)");
06345                         d.put("axis", EMObject::STRING, "(optional) specify a major axis for asymmetric features, default x axis");
06346                         d.put("phase", EMObject::FLOAT, "(optional) the phase in radians");
06347                         d.put("az", EMObject::FLOAT, "(optional) angle in degree. for 2D image, this is the rotated angle of the image, \
06348                                                                                                 in 3D image, it's az for euler angle. default is zero");
06349                         d.put("alt", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, alt for euler angle, default is zero");
06350                         d.put("phi", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, phi for euler angle, default is zero");
06351                         return d;
06352                 }
06353 
06354                 static const string NAME;
06355         };
06356 
06363         class TestImageSinewaveCircular : public TestImageProcessor
06364         {
06365         public:
06366                 virtual void process_inplace(EMData * image);
06367 
06368                 virtual string get_name() const
06369                 {
06370                         return NAME;
06371                 }
06372 
06373                 virtual string get_desc() const
06374                 {
06375                         return "Replace a source image as a circular sine wave in specified wave length";
06376                 }
06377 
06378                 static Processor * NEW()
06379                 {
06380                         return new TestImageSinewaveCircular();
06381                 }
06382 
06383                 virtual TypeDict get_param_types() const
06384                 {
06385                         TypeDict d;
06386                         d.put("wavelength", EMObject::FLOAT, "(required)this value is the d in function |sin(x/d)|, unit: pixel");
06387                         d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06388                         d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06389                         d.put("phase", EMObject::FLOAT, "(optional)phase for sine wave, default is 0");
06390                         return d;
06391                 }
06392 
06393                 static const string NAME;
06394         };
06395 
06402         class TestImageSquarecube : public TestImageProcessor
06403         {
06404         public:
06405                 virtual void process_inplace(EMData * image);
06406 
06407                 virtual string get_name() const
06408                 {
06409                         return NAME;
06410                 }
06411 
06412                 virtual string get_desc() const
06413                 {
06414                         return "Replace a source image as a square or cube depends on 2D or 3D of the source image";
06415                 }
06416 
06417                 static Processor * NEW()
06418                 {
06419                         return new TestImageSquarecube();
06420                 }
06421 
06422                 virtual TypeDict get_param_types() const
06423                 {
06424                         TypeDict d;
06425                         d.put("edge_length", EMObject::FLOAT, "edge length of the square or cube, unit: pixel");
06426                         d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06427                         d.put("odd_edge", EMObject::FLOAT, "edge length for the asymmetric axis");
06428                         d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank");
06429                         return d;
06430                 }
06431 
06432                 static const string NAME;
06433         };
06434 
06442         class TestImageEllipse : public TestImageProcessor
06443         {
06444         public:
06445                 virtual void process_inplace(EMData * image);
06446 
06447                 virtual string get_name() const
06448                 {
06449                         return NAME;
06450                 }
06451 
06452                 virtual string get_desc() const
06453                 {
06454                         return "Insert an ellipse into the image.";
06455                 }
06456 
06457                 static Processor * NEW()
06458                 {
06459                         return new TestImageEllipse();
06460                 }
06461 
06462                 virtual TypeDict get_param_types() const
06463                 {
06464                         TypeDict d;
06465                         d.put("a", EMObject::FLOAT, "equatorial radius along x axes (major semiaxes)");
06466                         d.put("b", EMObject::FLOAT, "equatorial radius along y axes (minor semiaxes)");
06467                         d.put("c", EMObject::FLOAT, "polar radius for ellipsoid (x^2/a^2+y^2/b^2+z^2/c^2=1)");
06468                         d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06469                         d.put("fill", EMObject::FLOAT, "value you want to fill in ellipse, default to 1.0");
06470                         return d;
06471                 }
06472 
06473                 static const string NAME;
06474         };
06475 
06487         class TestImageHollowEllipse : public TestImageProcessor
06488                 {
06489                 public:
06490                         virtual void process_inplace(EMData * image);
06491 
06492                         virtual string get_name() const
06493                         {
06494                                 return NAME;
06495                         }
06496 
06497                         virtual string get_desc() const
06498                         {
06499                                 return "Insert a hollow ellipse into the image.";
06500                         }
06501 
06502                         static Processor * NEW()
06503                         {
06504                                 return new TestImageHollowEllipse();
06505                         }
06506 
06507                         virtual TypeDict get_param_types() const
06508                         {
06509                                 TypeDict d;
06510                                 d.put("xwidth", EMObject::FLOAT, "inner equatorial radii along x axes");
06511                                 d.put("ywidth", EMObject::FLOAT, "inner equatorial radii along y axes");
06512                                 d.put("zwidth", EMObject::FLOAT, "inner polar radius");
06513                                 d.put("a", EMObject::FLOAT, "outter equatorial radii along x axes");
06514                                 d.put("b", EMObject::FLOAT, "outter equatorial radii along y axes");
06515                                 d.put("c", EMObject::FLOAT, "outter polar radius");
06516                                 d.put("width",EMObject::FLOAT, "width - specify the width or specify each width explicitly - xwidth, ywidth, zwidth");
06517                                 d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06518                                 d.put("fill", EMObject::FLOAT, "value you want to fill in hollow ellipse, default to 1.0");
06519                                 return d;
06520                         }
06521 
06522                         static const string NAME;
06523                 };
06524 
06531         class TestImageCirclesphere : public TestImageProcessor
06532         {
06533         public:
06534                 virtual void process_inplace(EMData * image);
06535 
06536                 virtual string get_name() const
06537                 {
06538                         return NAME;
06539                 }
06540 
06541                 virtual string get_desc() const
06542                 {
06543                         return "Replace a source image as a circle or sphere depends on 2D or 3D of the source image";
06544                 }
06545 
06546                 static Processor * NEW()
06547                 {
06548                         return new TestImageCirclesphere();
06549                 }
06550 
06551                 virtual TypeDict get_param_types() const
06552                 {
06553                         TypeDict d;
06554                         d.put("radius", EMObject::FLOAT, "radius of circle or sphere, unit: pixel");
06555                         d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06556                         d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06557                         d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank.");
06558                         return d;
06559                 }
06560 
06561                 static const string NAME;
06562         };
06563 
06568         class TestImageNoiseUniformRand : public TestImageProcessor
06569         {
06570         public:
06571                 virtual void process_inplace(EMData * image);
06572 
06573                 virtual string get_name() const
06574                 {
06575                         return NAME;
06576                 }
06577 
06578                 virtual string get_desc() const
06579                 {
06580                         return "Replace a source image as a uniform random noise, random number generated from gsl_rng_mt19937, the pixel value is [0, 1)";
06581                 }
06582 
06583                 static Processor * NEW()
06584                 {
06585                         return new TestImageNoiseUniformRand();
06586                 }
06587 
06588                 virtual TypeDict get_param_types() const
06589                 {
06590                         TypeDict d;
06591                         d.put("seed", EMObject::INT, "seed for random number generator");
06592                         return d;
06593                 }
06594 
06595                 static const string NAME;
06596         };
06597 
06608         class TestImageNoiseGauss : public TestImageProcessor
06609         {
06610         public:
06611                 virtual void process_inplace(EMData * image);
06612 
06613                 virtual string get_name() const
06614                 {
06615                         return NAME;
06616                 }
06617 
06618                 virtual string get_desc() const
06619                 {
06620                         return "Replace a source image as a random noise, the random value is gaussian distributed";
06621                 }
06622 
06623                 static Processor * NEW()
06624                 {
06625                         return new TestImageNoiseGauss();
06626                 }
06627 
06628                 virtual TypeDict get_param_types() const
06629                 {
06630                         TypeDict d;
06631                         d.put("sigma", EMObject::FLOAT, "sigma value of gausian distributed noise, default is 0.5");
06632                         d.put("mean", EMObject::FLOAT, "mean value of gausian distributed noise, default is zero.");
06633                         d.put("seed", EMObject::INT, "the seed for random number generator, default is not to reseed.");
06634 
06635                         return d;
06636                 }
06637 
06638                 static const string NAME;
06639         };
06640 
06645         class TestImageCylinder : public TestImageProcessor
06646         {
06647         public:
06648                 virtual void process_inplace(EMData * image);
06649 
06650                 virtual string get_name() const
06651                 {
06652                         return NAME;
06653                 }
06654 
06655                 virtual string get_desc() const
06656                 {
06657                         return "Replace a source image as a cylinder";
06658                 }
06659 
06660                 static Processor * NEW()
06661                 {
06662                         return new TestImageCylinder();
06663                 }
06664 
06665                 virtual TypeDict get_param_types() const
06666                 {
06667                         TypeDict d;
06668                         d.put("radius", EMObject::FLOAT, "radius for the cylinder");
06669                         d.put("height", EMObject::FLOAT, "height for the cylinder, by default it's the nz");
06670 
06671                         return d;
06672                 }
06673 
06674                 static const string NAME;
06675         };
06676 
06682         class CCDNormProcessor:public Processor
06683         {
06684           public:
06685                 virtual void process_inplace(EMData * image);
06686 
06687                 virtual string get_name() const
06688                 {
06689                         return NAME;
06690                 }
06691 
06692                 static Processor *NEW()
06693                 {
06694                         return new CCDNormProcessor();
06695                 }
06696 
06697                 virtual         string get_desc() const
06698                 {
06699                         return "normalize the 4 quadrants of a CCD image";
06700                 }
06701 
06702                 virtual TypeDict get_param_types() const
06703                 {
06704                         TypeDict d;
06705                         d.put("width", EMObject::INT, "number of pixels on either side of the seam to sample");
06706                         return d;
06707                 }
06708 
06709                 static const string NAME;
06710         };
06711 
06719         class WaveletProcessor:public Processor
06720         {
06721           public:
06722                 virtual void process_inplace(EMData * image);
06723 
06724                 virtual string get_name() const
06725                 {
06726                         return NAME;
06727                 }
06728 
06729                 static Processor *NEW()
06730                 {
06731                         return new WaveletProcessor();
06732                 }
06733 
06734                 virtual TypeDict get_param_types() const
06735                 {
06736                         TypeDict d;
06737                         d.put("type", EMObject::STRING, "'daub', 'harr' or 'bspl'");
06738                         d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06739                         d.put("ord", EMObject::INT, "Daubechies (4,6,8,...,20), for Harr (2), for B-Splines (103, 105, 202, 204, 206, 208, 301, 303, 305 307, 309)");
06740                         return d;
06741                 }
06742 
06743                 virtual string get_desc() const
06744                 {
06745                         return "Computes the DWT (discrete wavelet transform) of an image in one of 3 possible bases";
06746                 }
06747 
06748                 static const string NAME;
06749         };
06750 
06766         class TomoTiltEdgeMaskProcessor : public Processor
06767         {
06768         public:
06769                 virtual void process_inplace(EMData* image);
06770 
06771                 virtual string get_name() const
06772                 {
06773                         return NAME;
06774                 }
06775 
06776                 static Processor *NEW()
06777                 {
06778                         return new TomoTiltEdgeMaskProcessor();
06779                 }
06780 
06781                 virtual TypeDict get_param_types() const
06782                 {
06783                         TypeDict d;
06784                         d.put("biedgemean", EMObject::BOOL, "Mutually  exclusive of edgemean. Experimental. Causes the pixels in the masked out areas to take the average value of both the left and right edge pixel strips");
06785                         d.put("edgemean", EMObject::BOOL, "Mutually  exclusive of biedgemean. Masked pixels values assume the mean edge pixel value, independently, for both sides of the image.");
06786                         d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06787                         d.put("gauss_falloff",EMObject::INT, "Causes the edge masking to have a smooth Gaussian fall-off - this parameter specifies how many pixels the fall-off will proceed over. Default is 0.");
06788                         d.put("gauss_sigma",EMObject::FLOAT,"The sigma of the Gaussian function used to smooth the edge fall-off (functional form is exp(-(pixel distance)^2/sigma^2)");
06789                         d.put("angle_fim",EMObject::BOOL,"Read fim as 'from image metadata' - this causes the altitude angle stored in by the image object (i.e. as extracted from the header, as currently stored in memory) to be used as the angle. This overrides the angle argument");
06790                         return d;
06791                 }
06792 
06793                 virtual string get_desc() const
06794                 {
06795                         return "Masks the part of the image which is not present in the 0-tilt image. Masked areas can be 0 or set to the edgemean (of the nearest or both edges). Masked areas can also have a Gaussian fall-off to make the appearance smooth.";
06796                 }
06797 
06798                 static const string NAME;
06799 
06800         private:
06801                 class GaussianFunctoid
06802                 {
06803                         public:
06804                                 GaussianFunctoid(const float sigma, const float mean = 0.0) : m_mean(mean), m_sigma_squared(sigma*sigma) {}
06805                                 ~GaussianFunctoid() {}
06806 
06807                                 float operator()(const float distance )
06808                                 {
06809                                         return exp( -(distance-m_mean)*(distance-m_mean)/ (m_sigma_squared ));
06810                                 }
06811                         private:
06812                                 float m_mean, m_sigma_squared;
06813                 };
06814 
06815         };
06816 
06831         class TomoTiltAngleWeightProcessor : public Processor
06832         {
06833                 public:
06834                         virtual void process_inplace(EMData* image);
06835 
06836                         virtual string get_name() const
06837                         {
06838                                 return NAME;
06839                         }
06840 
06841                         static Processor *NEW()
06842                         {
06843                                 return new TomoTiltAngleWeightProcessor();
06844                         }
06845 
06846                         virtual TypeDict get_param_types() const
06847                         {
06848                                 TypeDict d;
06849                                 d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06850                                 d.put("angle_fim",EMObject::BOOL,"Read fim as 'from image metadata' - this causes the altitude angle stored in by the image object (i.e. as extracted from the header, as currently stored in memory) to be used as the angle. This overrides the angle argument");
06851                                 return d;
06852                         }
06853 
06854                         virtual string get_desc() const
06855                         {
06856                                 return "Weights the image by 1/cos(angle)";
06857                         }
06858 
06859                         static const string NAME;
06860 
06861         };
06862 
06866         class FFTProcessor : public Processor
06867         {
06868           public:
06869                 void process_inplace(EMData * image);
06870 
06871                 string get_name() const
06872                 {
06873                         return NAME;
06874                 }
06875 
06876                 static Processor *NEW()
06877                 {
06878                         return new FFTProcessor();
06879                 }
06880 
06881                 TypeDict get_param_types() const
06882                 {
06883                         TypeDict d;
06884                         d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06885                         return d;
06886                 }
06887 
06888                 string get_desc() const
06889                 {
06890                         return "Computes the DFFT (Discrete Fast Fourier Transform) of an image";
06891                 }
06892 
06893                 static const string NAME;
06894         };
06895 
06900         class RadialProcessor : public Processor
06901         {
06902         public:
06903                 void process_inplace(EMData * image);
06904 
06905                 string get_name() const
06906                 {
06907                         return NAME;
06908                 }
06909 
06910                 static Processor *NEW()
06911                 {
06912                         return new RadialProcessor();
06913                 }
06914 
06915                 TypeDict get_param_types() const
06916                 {
06917                         TypeDict d;
06918                         d.put("table", EMObject::FLOATARRAY, "Radial array of floats, 1 float/pixel");
06919                         return d;
06920                 }
06921 
06922                 string get_desc() const
06923                 {
06924                         return "Multiply a real-space image by a radial function. 1 value / pixel, extending to corner. Missing values -> 0.";
06925                 }
06926 
06927                 static const string NAME;
06928         };
06929 
06936         class HistogramBin : public Processor
06937         {
06938                 public:
06939                         HistogramBin() : default_bins(1024) {}
06940 
06941                         void process_inplace(EMData * image);
06942 
06943                         string get_name() const
06944                         {
06945                                 return NAME;
06946                         }
06947 
06948                         static Processor *NEW()
06949                         {
06950                                 return new HistogramBin();
06951                         }
06952 
06953                         TypeDict get_param_types() const
06954                         {
06955                                 TypeDict d;
06956                                 d.put("nbins", EMObject::INT, "The number of bins the pixel values will be compressed into");
06957                                 d.put("debug", EMObject::BOOL, "Outputs debugging information (number of pixels per bin)");
06958                                 return d;
06959                         }
06960 
06961                         string get_desc() const
06962                         {
06963                                 return "Bins pixel values, similar to calculating a histogram. The histogram is comprised of 'nbins' bins, and the value assigned to each pixel in the bin is the midpoint of the bin's upper and lower limits. Defaults to 256 bins";
06964                         }
06965 
06966                         static const string NAME;
06967 
06968                 protected:
06969                         int default_bins;
06970         };
06971 
06972         class ModelHelixProcessor : public Processor
06973         {
06974           protected:
06975                 float radprofile(float r, int type);
06976         };
06977 
06978         class ModelEMCylinderProcessor : public ModelHelixProcessor
06979         {
06980           public:
06981                 void process_inplace(EMData * in);
06982 
06983                 string get_name() const
06984                 {
06985                         return NAME;
06986                 }
06987 
06988                 static Processor *NEW()
06989                 {
06990                         return new ModelEMCylinderProcessor();
06991                 }
06992 
06993                 string get_desc() const
06994                 {
06995                         return "Adds a cylinder with a radial density profile similar to that of an alpha helix.";
06996                 }
06997 
06998                 virtual TypeDict get_param_types() const
06999                 {
07000                         TypeDict d;
07001                         d.put("type", EMObject::INT, "Radial profile of density method, defaults to 2: 0 = pure Gaussian falloff; 1 = Gaussian falloff + dip, so mean is zero; 2 = polynomial fitting of real helix density");
07002                         d.put("length", EMObject::FLOAT, "cylinder length in angstroms, defaults to 3 turns (16.2 Angstroms)");
07003                         d.put("x0", EMObject::INT, "x coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
07004                         d.put("y0", EMObject::INT, "y coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
07005                         d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
07006                         //TODO: Check with Matt Baker about description strings
07007                         return d;
07008                 }
07009 
07010                 static const string NAME;
07011         };
07012 
07013         class ApplyPolynomialProfileToHelix : public ModelHelixProcessor
07014         {
07015         public:
07016                 void process_inplace(EMData * in);
07017 
07018                 string get_name() const
07019                 {
07020                         return NAME;
07021                 }
07022 
07023                 static Processor *NEW()
07024                 {
07025                         return new ApplyPolynomialProfileToHelix();
07026                 }
07027 
07028                 string get_desc() const
07029                 {
07030                         return "Finds the CM of each z-axis slice and applies a polynomial radial profile about it.";
07031                 }
07032                 virtual TypeDict get_param_types() const
07033                 {
07034                         TypeDict d;
07035                         d.put("length", EMObject::FLOAT, "Helix length in angstroms.");
07036                         d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
07037                         return d;
07038                 }
07039 
07040                 static const string NAME;
07041         };
07042 
07043         class BinarySkeletonizerProcessor : public Processor
07044         {
07045         public:
07046                 virtual EMData* process(EMData * image);
07047                 virtual void process_inplace(EMData * image);
07048 
07049                 virtual string get_name() const
07050                 {
07051                         return NAME;
07052 //                      return "gorgon.binary_skel";
07053                 }
07054                 static Processor *NEW()
07055                 {
07056                         return new BinarySkeletonizerProcessor();
07057                 }
07058                 string get_desc() const
07059                 {
07060                         return "Creates a skeleton of the 3D image by considering whether density is above or below a threshold value.";
07061                 }
07062                 virtual TypeDict get_param_types() const
07063                 {
07064                         TypeDict d;
07065                         d.put("threshold", EMObject::FLOAT, "Threshold value.");
07066                         d.put("min_curve_width", EMObject::INT, "Minimum curve width.");
07067                         d.put("min_surface_width", EMObject::INT, "Minimum surface width.");
07068                         d.put("mark_surfaces", EMObject::BOOL, "Mark surfaces with a value of 2.0f, whereas curves are 1.0f.");
07069                         return d;
07070                 }
07071                 static const string NAME;
07072         };
07073 
07074         class ConvolutionKernelProcessor : public Processor
07075         {
07076         public:
07077                 virtual EMData* process(const EMData* const image);
07078                 virtual void process_inplace(EMData * image);
07079                 
07080                 virtual string get_name() const
07081                 {
07082                         return NAME;
07083                 }
07084                 static Processor *NEW()
07085                 {
07086                         return new ConvolutionKernelProcessor();
07087                 }
07088                 string get_desc() const
07089                 {
07090                         return "Filters an image with a convolution kernel in real space.";
07091                 }
07092                 virtual TypeDict get_param_types() const
07093                 {
07094                         TypeDict d;
07095                         d.put("kernel", EMObject::FLOATARRAY, "the convolution kernel");
07096                         return d;
07097                 }
07098                 static const string NAME;       
07099         };
07100         
07101         class RotateInFSProcessor : public Processor
07102                 {
07103                 public:
07104                         //virtual EMData* process(const EMData* const image);
07105                         virtual void process_inplace(EMData * image);
07106                         virtual EMData* process(const EMData* const image);
07107 
07108                         virtual string get_name() const
07109                         {
07110                                 return NAME;
07111                         }
07112                         static Processor *NEW()
07113                         {
07114                                 return new RotateInFSProcessor( );
07115                         }
07116                         string get_desc() const
07117                         {
07118                                 return "Rotates a Fourier object using a kernel.";
07119                         }
07120                         virtual TypeDict get_param_types() const
07121                         {
07122                                 TypeDict d;     
07123                                 d.put("transform", EMObject::TRANSFORM, "transform");
07124                                 d.put("interpCutoff", EMObject::FLOAT, "cutoff for interpolation");
07125 //                              d.put("offset", EMObject::FLOAT, "offset for FT centering");
07126 //                              d.put("angle", EMObject::FLOAT, "angle");
07127                                 return d;
07128                         }
07129                         static const string NAME;
07130                 };
07131         
07132 #ifdef SPARX_USING_CUDA
07133         /* class MPI CUDA kmeans processor
07134          * 2009-02-13 17:34:45 JB first version
07135          * 2009-09-02 11:19:10 JB for MPI version
07136          * python wrap for GPU cluster
07137          */
07138         class MPICUDA_kmeans {
07139         public:
07140                 MPICUDA_kmeans();
07141                 ~MPICUDA_kmeans();
07142                 int setup(int extm, int extN, int extn, int extK, int extn_start);
07143                 void append_flat_image(EMData* im, int pos);
07144                 int init_mem(int numdev);
07145                 void compute_im2();
07146                 int random_ASG(long int rnd);
07147                 vector<int> get_ASG();
07148                 vector<int> get_asg();
07149                 void compute_NC();
07150                 vector<int> get_NC();
07151                 void set_ASG(const vector <int>& ASG);
07152                 void set_NC(const vector <int>& NC);
07153                 int get_ct_im_mv();
07154                 void set_T(float extT);
07155                 float get_T();
07156                 void compute_AVE();
07157                 void set_AVE(EMData* im, int pos);
07158                 vector<EMData*> get_AVE();
07159                 int one_iter();
07160                 //int one_iter_SSE();
07161                 //int AVE_to_host();
07162                 int one_iter_SA();
07163                 vector<float> compute_ji();
07164                 vector<float> compute_criterion(const vector <float>& Ji);
07165                 int shutdown();
07166         private:
07167                 // params
07168                 int m;
07169                 int N;
07170                 int n;
07171                 int K;
07172                 int nb_part;
07173                 int n_start;
07174                 int size_im;
07175                 int size_IM;
07176                 int size_AVE;
07177                 int size_dist;
07178                 int BLOCK_SIZE;
07179                 int NB;
07180                 int ins_BLOCK;
07181                 int ite;
07182                 float T;
07183                 // debug
07184                 int ct_im_mv;
07185                 // host memory
07186                 float* h_IM;
07187                 float* h_im;
07188                 float* h_AVE;
07189                 float* h_dist;
07190                 float* h_AVE2;
07191                 float* h_im2;
07192                 unsigned short int* h_ASG;
07193                 unsigned short int* h_asg;
07194                 unsigned int* h_NC;
07195                 int* params;
07196                 float ttt;
07197                 // device memory
07198                 float* d_im;
07199                 float* d_AVE;
07200                 float* d_dist;
07201                 //int init_dist(); // intial h_dist and d_dist for SSE
07202                 float compute_tt();
07203         };
07204 
07205 #endif //EMAN2_USING_CUDA
07206 
07207 #if 0
07208 
07209         class XYZProcessor:public Processor
07210         {
07211           public:
07212                 void process_inplace(EMData * image);
07213 
07214                 string get_name() const
07215                 {
07216                         return NAME;
07217                 }
07218 
07219                 static Processor *NEW()
07220                 {
07221                         return new XYZProcessor();
07222                 }
07223 
07224                 string get_desc() const
07225                 {
07226                         return "N/A";
07227                 }
07228 
07229                 TypeDict get_param_types() const
07230                 {
07231                         TypeDict d;
07232                         return d;
07233                 }
07234 
07235                 static const string NAME;
07236         };
07237 
07238 
07239 #endif
07240 
07241 
07242 #if 0
07243 
07244         class XYZProcessor:public Processor
07245         {
07246           public:
07247                 void process_inplace(EMData * image);
07248 
07249                 string get_name() const
07250                 {
07251                         return NAME;
07252                 }
07253 
07254                 static Processor *NEW()
07255                 {
07256                         return new XYZProcessor();
07257                 }
07258 
07259                 string get_desc() const
07260                 {
07261                         return "N/A";
07262                 }
07263 
07264                 TypeDict get_param_types() const
07265                 {
07266                         TypeDict d;
07267                         return d;
07268                 }
07269 
07270                 static const string NAME;
07271         };
07272 
07273 
07274 #endif
07275 
07276 
07277         int multi_processors(EMData * image, vector < string > processornames);
07278         void dump_processors();
07279         map<string, vector<string> > dump_processors_list();
07280         map<string, vector<string> > group_processors();
07281 
07282         template <> Factory < Processor >::Factory();
07283 }
07284 
07285 #endif  //eman_filter_h__
07286 
07287 /* vim: set ts=4 noet: */
07288 

Generated on Tue Jun 11 13:46:18 2013 for EMAN2 by  doxygen 1.3.9.1