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, "Resolution in 1/A (0 - 1 / size*apix)");
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, "Resolution in 1/A (0 - 1 / size*apix)");
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 InvertCarefullyProcessor:public RealPixelProcessor
01295         {
01296                 public:
01297                         string get_name() const
01298                         {
01299                                 return NAME;
01300                         }
01301                         static Processor *NEW()
01302                         {
01303                                 return new InvertCarefullyProcessor();
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) *x = zero_to;
01330                                 else *x = 1/(*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                         return d;
01732                 }
01733 
01734                 string get_desc() const
01735                 {
01736                         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.";
01737                 }
01738 
01739                 static const string NAME;
01740 
01741           protected:
01742                 float default_max, default_min;
01743         };
01744 
01750         class NSigmaClampingProcessor : public ClampingProcessor
01751         {
01752                 public:
01753                         NSigmaClampingProcessor() : default_sigma(2.0) {}
01754 
01755                         string get_name() const
01756                         {
01757                                 return NAME;
01758                         }
01759 
01760                         static Processor *NEW()
01761                         {
01762                                 return new NSigmaClampingProcessor();
01763                         }
01764 
01765                         TypeDict get_param_types() const
01766                         {
01767                                 TypeDict d;
01768                                 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" );
01769                                 d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01770                                 return d;
01771                         }
01772 
01773                         void process_inplace(EMData *image);
01774 
01775                         string get_desc() const
01776                         {
01777                                 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.";
01778                         }
01779 
01780                         static const string NAME;
01781 
01782                 protected:
01783                         float default_sigma;
01784         };
01785 
01789         class ToMinvalProcessor:public Processor
01790         {
01791           public:
01792                 string get_name() const
01793                 {
01794                         return NAME;
01795                 }
01796                 static Processor *NEW()
01797                 {
01798                         return new ToMinvalProcessor();
01799                 }
01800 
01801                 void process_inplace(EMData *image);
01802 
01803                 TypeDict get_param_types() const
01804                 {
01805                         TypeDict d;
01806                         d.put("minval", EMObject::FLOAT, "Everything below this value is set to this value");
01807                         d.put("newval", EMObject::FLOAT, "If set, values below minval will be set to newval instead of minval ");
01808                         return d;
01809                 }
01810 
01811                 string get_desc() const
01812                 {
01813                         return "f(x) = x if x >= minval; f(x) = minval|newval if x < minval.";
01814                 }
01815 
01816                 static const string NAME;
01817 
01818         protected:
01819 
01820         };
01821 
01822 
01823 
01827         class CutToZeroProcessor:public RealPixelProcessor
01828         {
01829           public:
01830                 string get_name() const
01831                 {
01832                         return NAME;
01833                 }
01834                 static Processor *NEW()
01835                 {
01836                         return new CutToZeroProcessor();
01837                 }
01838                 TypeDict get_param_types() const
01839                 {
01840                         TypeDict d;
01841                         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" );
01842                         return d;
01843                 }
01844 
01845                 string get_desc() const
01846                 {
01847                         return "f(x) = x-minval if x >= minval; f(x) = 0 if x < minval.";
01848                 }
01849 
01850                 static const string NAME;
01851 
01852           protected:
01853                 void process_pixel(float *x) const
01854                 {
01855                         *x = *x - value;
01856                         if (*x < 0) {
01857                                 *x = 0;
01858                         }
01859                 }
01860         };
01861 
01865         class BinarizeProcessor:public RealPixelProcessor
01866         {
01867           public:
01868                 string get_name() const
01869                 {
01870                         return NAME;
01871                 }
01872                 static Processor *NEW()
01873                 {
01874                         return new BinarizeProcessor();
01875                 }
01876                 TypeDict get_param_types() const
01877                 {
01878                         TypeDict d;
01879                         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" );
01880                         return d;
01881                 }
01882 
01883                 string get_desc() const
01884                 {
01885                         return "f(x) = 0 if x < value; f(x) = 1 if x >= value.";
01886                 }
01887 
01888                 static const string NAME;
01889 
01890           protected:
01891                 void process_pixel(float *x) const
01892                 {
01893                         if (*x < value)
01894                         {
01895                                 *x = 0;
01896                         }
01897                         else
01898                         {
01899                                 *x = 1;
01900                         }
01901                 }
01902         };
01903 
01911         class BinarizeFourierProcessor:public Processor
01912                 {
01913                   public:
01914                         virtual string get_name() const
01915                         {
01916                                 return NAME;
01917                         }
01918                         static Processor *NEW()
01919                         {
01920                                 return new BinarizeFourierProcessor();
01921                         }
01922 
01927                         virtual void process_inplace(EMData* image);
01928 
01929                         virtual TypeDict get_param_types() const
01930                         {
01931                                 TypeDict d;
01932                                 d.put("value", EMObject::FLOAT, "The Fourier amplitude threshold cutoff" );
01933                                 return d;
01934                         }
01935 
01936                         virtual string get_desc() const
01937                         {
01938                                 return "f(k) = 0 + 0i if ||f(k)|| < value; f(k) = a + bi if ||f(k)|| >= value.";
01939                         }
01940 
01941                         static const string NAME;
01942                 };
01943 
01948         class CollapseProcessor:public RealPixelProcessor
01949         {
01950           public:
01951                 string get_name() const
01952                 {
01953                         return NAME;
01954                 }
01955                 static Processor *NEW()
01956                 {
01957                         return new CollapseProcessor();
01958                 }
01959 
01960                 void set_params(const Dict & new_params)
01961                 {
01962                         params = new_params;
01963                         range = params["range"];
01964                         value = params["value"];
01965                 }
01966 
01967                 TypeDict get_param_types() const
01968                 {
01969                         TypeDict d;
01970                         d.put("range", EMObject::FLOAT, "The range about 'value' which will be collapsed to 'value'");
01971                         d.put("value", EMObject::FLOAT, "The pixel value where the focus of the collapse operation is");
01972                         return d;
01973                 }
01974 
01975                 string get_desc() const
01976                 {
01977                         return "f(x): if v-r<x<v+r -> v; if x>v+r -> x-r; if x<v-r -> x+r";
01978                 }
01979 
01980                 static const string NAME;
01981 
01982           protected:
01983                 void process_pixel(float *x) const
01984                 {
01985                         if (*x>value+range) *x-=range;
01986                         else if (*x<value-range) *x+=range;
01987                         else *x=value;
01988                 }
01989                 float range;
01990         };
01991 
01996         class LinearXformProcessor:public RealPixelProcessor
01997         {
01998           public:
01999                 LinearXformProcessor():shift(0), scale(0)
02000                 {
02001                 }
02002 
02003                 string get_name() const
02004                 {
02005                         return NAME;
02006                 }
02007                 static Processor *NEW()
02008                 {
02009                         return new LinearXformProcessor();
02010                 }
02011 
02012                 void set_params(const Dict & new_params)
02013                 {
02014                         params = new_params;
02015                         shift = params.get("shift");
02016                         scale = params.get("scale");
02017                 }
02018 
02019                 TypeDict get_param_types() const
02020                 {
02021                         TypeDict d;
02022                         d.put("shift", EMObject::FLOAT, "The amount to shift pixel values by before scaling");
02023                         d.put("scale", EMObject::FLOAT, "The scaling factor to be applied to pixel values");
02024                         return d;
02025                 }
02026 
02027                 string get_desc() const
02028                 {
02029                         return "linear transform processor: f(x) = x * scale + shift. This is equivalent to a regular contrast stretching operation";
02030                 }
02031 
02032                 static const string NAME;
02033 
02034           protected:
02035                 void process_pixel(float *x) const
02036                 {
02037                         *x = (*x) * scale + shift;
02038                 }
02039 
02040           private:
02041                 float shift;
02042                 float scale;
02043         };
02044 
02049         class ExpProcessor:public RealPixelProcessor
02050         {
02051           public:
02052                 ExpProcessor():low(0), high(0)
02053                 {
02054                 }
02055 
02056                 string get_name() const
02057                 {
02058                         return NAME;
02059                 }
02060 
02061                 static Processor *NEW()
02062                 {
02063                         return new ExpProcessor();
02064                 }
02065 
02066                 void set_params(const Dict & new_params)
02067                 {
02068                         params = new_params;
02069                         low = params.get("low");
02070                         high = params.get("high");
02071                 }
02072 
02073                 TypeDict get_param_types() const
02074                 {
02075                         TypeDict d;
02076                         d.put("low", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
02077                         d.put("high", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
02078                         return d;
02079                 }
02080 
02081                 string get_desc() const
02082                 {
02083                         return "f(x) = exp( x / low - high)";
02084                 }
02085 
02086                 static const string NAME;
02087 
02088           protected:
02092                 void process_pixel(float *x) const
02093                 {
02094                         float v = *x / low - high;
02095                         if (v > 40) {
02096                                 v = 40;
02097                         }
02098                         *x = exp(v);
02099                 }
02100 
02101           private:
02102                 float low;
02103                 float high;
02104         };
02105 
02109         class FiniteProcessor:public RealPixelProcessor
02110         {
02111                 public:
02112                         FiniteProcessor():to(0)
02113                         {
02114                         }
02115 
02116                         string get_name() const
02117                         {
02118                                 return NAME;
02119                         }
02120 
02121                         static Processor *NEW()
02122                         {
02123                                 return new FiniteProcessor();
02124                         }
02125 
02126                         void set_params(const Dict & new_params)
02127                         {
02128                                 if (new_params.has_key("to") )
02129                                         to = params["to"];
02130                         }
02131 
02132                         TypeDict get_param_types() const
02133                         {
02134                                 TypeDict d;
02135                                 d.put("to", EMObject::FLOAT, "Pixels which are not finite will be set to this value");
02136                                 return d;
02137                         }
02138 
02139                         string get_desc() const
02140                         {
02141                                 return "f(x) = f(x) if f(x) is finite | to if f(x) is not finite";
02142                         }
02143 
02144                         static const string NAME;
02145 
02146                 protected:
02150                         void process_pixel(float *x) const;
02151                 private:
02152                         float to;
02153         };
02154 
02159         class RangeThresholdProcessor:public RealPixelProcessor
02160         {
02161           public:
02162                 RangeThresholdProcessor():low(0), high(0)
02163                 {
02164                 }
02165 
02166                 string get_name() const
02167                 {
02168                         return NAME;
02169                 }
02170                 static Processor *NEW()
02171                 {
02172                         return new RangeThresholdProcessor();
02173                 }
02174 
02175                 void set_params(const Dict & new_params)
02176                 {
02177                         params = new_params;
02178                         low = params.get("low");
02179                         high = params.get("high");
02180                 }
02181 
02182                 TypeDict get_param_types() const
02183                 {
02184                         TypeDict d;
02185                         d.put("low", EMObject::FLOAT, "The lower limit of the range that will be set to 1");
02186                         d.put("high", EMObject::FLOAT, "The upper limit of the range that will be set to 1");
02187                         return d;
02188                 }
02189 
02190                 string get_desc() const
02191                 {
02192                         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";
02193                 }
02194 
02195                 static const string NAME;
02196 
02197           protected:
02198                 void process_pixel(float *x) const
02199                 {
02200                         if (*x >= low && *x <= high) {
02201                                 *x = 1;
02202                         }
02203                         else {
02204                                 *x = 0;
02205                         }
02206                 }
02207           private:
02208                 float low;
02209                 float high;
02210 
02211         };
02212 
02217         class SigmaProcessor:public RealPixelProcessor
02218         {
02219           public:
02220                 string get_name() const
02221                 {
02222                         return NAME;
02223                 }
02224                 static Processor *NEW()
02225                 {
02226                         return new SigmaProcessor();
02227                 }
02228 
02229                 void set_params(const Dict & new_params)
02230                 {
02231                         params = new_params;
02232                         value1 = params.get("value1");
02233                         value2 = params.get("value2");
02234                 }
02235 
02236                 TypeDict get_param_types() const
02237                 {
02238                         TypeDict d;
02239                         d.put("value1", EMObject::FLOAT, "A number reflecting total standard deviations in the right direction");
02240                         d.put("value2", EMObject::FLOAT, "A number reflecting total standard deviations in the left direction");
02241                         return d;
02242                 }
02243 
02244                 string get_desc() const
02245                 {
02246                         return "f(x) = mean if x<(mean-v2*sigma) or x>(mean+v1*sigma); else f(x) = x;";
02247                 }
02248 
02249                 static const string NAME;
02250 
02251           protected:
02252                 void process_pixel(float *x) const
02253                 {
02254                         if (*x < (mean - value2 * sigma) || *x > (mean + value1 * sigma))
02255                         {
02256                                 *x = mean;
02257                         }
02258                 }
02259 
02260           private:
02261                 float value1;
02262                 float value2;
02263         };
02264 
02267         class LogProcessor:public RealPixelProcessor
02268         {
02269           public:
02270                 string get_name() const
02271                 {
02272                         return NAME;
02273                 }
02274                 static Processor *NEW()
02275                 {
02276                         return new LogProcessor();
02277                 }
02278 
02279                 string get_desc() const
02280                 {
02281                         return "f(x) = log10(x) if x > 0; else f(x) = 0;";
02282                 }
02283 
02284                 static const string NAME;
02285 
02286           protected:
02287                 void process_pixel(float *x) const
02288                 {
02289                         if (*x > 0)
02290                         {
02291                                 *x = log10(*x);
02292                         }
02293                         else
02294                         {
02295                                 *x = 0;
02296                         }
02297                 }
02298         };
02299 
02302         class CoordinateProcessor:public Processor
02303         {
02304           public:
02305                 CoordinateProcessor():nx(0), ny(0), nz(0), mean(0), sigma(0), maxval(0), is_complex(false)
02306                 {
02307                 }
02308                 void process_inplace(EMData * image);
02309 
02310                 static string get_group_desc()
02311                 {
02312                         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().";
02313                 }
02314 
02315           protected:
02316                 virtual void process_pixel(float *pixel, int xi, int yi, int zi) const = 0;
02317                 virtual void calc_locals(EMData *)
02318                 {
02319                 }
02320                 virtual bool is_valid() const
02321                 {
02322                         return true;
02323                 }
02324 
02325                 int nx;
02326                 int ny;
02327                 int nz;
02328                 float mean;
02329                 float sigma;
02330                 float maxval;
02331 
02332                 bool is_complex;
02333         };
02334 
02342         class CircularMaskProcessor:public CoordinateProcessor
02343         {
02344           public:
02345                 CircularMaskProcessor():inner_radius(0), outer_radius(0), inner_radius_square(0),
02346                         outer_radius_square(0), dx(0), dy(0), dz(0), xc(0), yc(0), zc(0)
02347                 {
02348                 }
02349 
02350                 void set_params(const Dict & new_params)
02351                 {
02352                         params = new_params;
02353 
02354                         if (params.has_key("inner_radius")) {
02355                                 inner_radius = params["inner_radius"];
02356                                 inner_radius_square = inner_radius * inner_radius;
02357                         }
02358                         else {
02359                                 inner_radius = -1;
02360                                 inner_radius_square = -1;
02361                         }
02362 
02363                         if (params.has_key("outer_radius")) {
02364                                 outer_radius = params["outer_radius"];
02365                                 outer_radius_square = outer_radius * outer_radius;
02366                         }
02367                         else {
02368                                 outer_radius = INT_MAX;
02369                                 outer_radius_square = INT_MAX;
02370                         }
02371 
02372                         if (params.has_key("xc")) xc = params["xc"];
02373                         if (params.has_key("yc")) yc = params["yc"];
02374                         if (params.has_key("zc")) zc = params["zc"];
02375                         if (params.has_key("dx")) dx = params["dx"];
02376                         if (params.has_key("dy")) dy = params["dy"];
02377                         if (params.has_key("dz")) dz = params["dz"];
02378                 }
02379 
02380                 string get_desc() const
02381                 {
02382                         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().";
02383                 }
02384 
02385                 TypeDict get_param_types() const
02386                 {
02387                         TypeDict d;
02388 
02389                         d.put("inner_radius", EMObject::INT, "inner mask radius. optional");
02390                         d.put("outer_radius", EMObject::INT, "outer mask radius. Negative value -> box radius + outer_radius +1");
02391 
02392                         d.put("dx", EMObject::FLOAT,
02393                                   "Modify mask center by dx relative to the default center nx/2");
02394                         d.put("dy", EMObject::FLOAT,
02395                                   "Modify mask center by dy relative to the default center ny/2");
02396                         d.put("dz", EMObject::FLOAT,
02397                                   "Modify mask center by dz relative to the default center nz/2");
02398 
02399                         return d;
02400                 }
02401           protected:
02402                 void calc_locals(EMData * image);
02403 
02404                 bool is_valid() const
02405                 {
02406                         return (!is_complex);
02407                 }
02408 
02409                 void process_pixel(float *pixel, int xi, int yi, int zi) const
02410                 {
02411                         float dist = (xi - xc) * (xi - xc) + (yi - yc) * (yi - yc) + (zi - zc) * (zi - zc);
02412                         process_dist_pixel(pixel, dist);
02413                 }
02414 
02415                 virtual void process_dist_pixel(float *pixel, float dist) const = 0;
02416 
02417                 int inner_radius;
02418                 int outer_radius;
02419                 int inner_radius_square;
02420                 int outer_radius_square;
02421                 float dx, dy, dz;
02422                 float xc, yc, zc;
02423         };
02424 
02428         class MaskSharpProcessor:public CircularMaskProcessor
02429         {
02430           public:
02431                 MaskSharpProcessor():value(0)
02432                 {
02433                 }
02434 
02435                 string get_name() const
02436                 {
02437                         return NAME;
02438                 }
02439                 static Processor *NEW()
02440                 {
02441                         return new MaskSharpProcessor();
02442                 }
02443 
02444                 void set_params(const Dict & new_params)
02445                 {
02446                         CircularMaskProcessor::set_params(new_params);
02447                         value = params.set_default("value",0.0f);
02448                 }
02449 
02450                 TypeDict get_param_types() const
02451                 {
02452                         TypeDict d = CircularMaskProcessor::get_param_types();
02453                         d.put("value", EMObject::FLOAT, "step cutoff to this value. Default is 0.");
02454                         return d;
02455                 }
02456 
02457                 string get_desc() const
02458                 {
02459                         return "step cutoff to a user-given value in both inner and outer circles.";
02460                 }
02461 
02462                 static const string NAME;
02463 
02464           protected:
02465                 void process_dist_pixel(float *pixel, float dist) const
02466                 {
02467                         if (dist >= outer_radius_square || dist < inner_radius_square)
02468                         {
02469                                 *pixel = value;
02470                         }
02471                 }
02472 
02473                 float value;
02474         };
02475 
02476 
02480         class MaskEdgeMeanProcessor:public CircularMaskProcessor
02481         {                                                       // 6
02482           public:
02483                 string get_name() const
02484                 {
02485                         return NAME;
02486                 }
02487                 static Processor *NEW()
02488                 {
02489                         return new MaskEdgeMeanProcessor();
02490                 }
02491 
02492                 void set_params(const Dict & new_params)
02493                 {
02494                         CircularMaskProcessor::set_params(new_params);
02495                         ring_width = params["ring_width"];
02496                         if (ring_width == 0) {
02497                                 ring_width = 1;
02498                         }
02499                 }
02500 
02501                 TypeDict get_param_types() const
02502                 {
02503                         TypeDict d = CircularMaskProcessor::get_param_types();
02504                         d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02505                         return d;
02506                 }
02507 
02508                 string get_desc() const
02509                 {
02510                         return "A step cutoff to the the mean value in a ring centered on the outer radius";
02511                 }
02512 
02513                 static const string NAME;
02514 
02515           protected:
02516                 void calc_locals(EMData * image);
02517 
02518 
02519                 void process_dist_pixel(float *pixel, float dist) const
02520                 {
02521                         if (dist >= outer_radius_square || dist < inner_radius_square){
02522                                 *pixel = ring_avg;
02523                         }
02524                 }
02525 
02526           private:
02527                 int ring_width;
02528                 float ring_avg;
02529         };
02530 
02533         class MaskNoiseProcessor:public CircularMaskProcessor
02534         {
02535           public:
02536                 string get_name() const
02537                 {
02538                         return NAME;
02539                 }
02540                 static Processor *NEW()
02541                 {
02542                         return new MaskNoiseProcessor();
02543                 }
02544 
02545                 string get_desc() const
02546                 {
02547                         return "fills masked region";
02548                 }
02549 
02550                 static const string NAME;
02551 
02552           protected:
02553                 void process_dist_pixel(float *pixel, float dist) const
02554                 {
02555                         if (dist >= outer_radius_square || dist < inner_radius_square)
02556                         {
02557                                 *pixel = Util::get_gauss_rand(mean, sigma);
02558                         }
02559                 }
02560         };
02561 
02564         class MaskGaussProcessor:public CircularMaskProcessor
02565         {
02566           public:
02567                 string get_name() const
02568                 {
02569                         return NAME;
02570                 }
02571                 static Processor *NEW()
02572                 {
02573                         return new MaskGaussProcessor();
02574                 }
02575 
02576                 void set_params(const Dict & new_params)
02577                 {
02578                         CircularMaskProcessor::set_params(new_params);
02579                         exponent = params["exponent"];
02580                         if (exponent <= 0.0) {
02581                                 exponent = 2.0;
02582                         }
02583                 }
02584 
02585                 TypeDict get_param_types() const
02586                 {
02587                         TypeDict d = CircularMaskProcessor::get_param_types();
02588                         d.put("exponent", EMObject::FLOAT, "The exponent, f in e^-Bs^f. default 2.0, producing a Gaussian");
02589                         return d;
02590                 }
02591 
02592                 string get_desc() const
02593                 {
02594                         return "a gaussian falloff to zero, radius is the 1/e of the width. If inner_radius>0, then \
02595 outer radius specifies width of Gaussian starting at inner_radius rather than total radius.";
02596                 }
02597 
02598                 static const string NAME;
02599 
02600           protected:
02601                 float exponent;
02602                 void process_dist_pixel(float *pixel, float dist) const
02603                 {
02604                         if (inner_radius_square>0) {
02605                                 if (dist>inner_radius_square) {
02606                                         if (exponent==2.0f) (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,2.0f) / outer_radius_square);
02607                                         else (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,exponent) / pow((float)outer_radius_square,exponent/2.0f));
02608                                 }
02609                         }
02610                         else {
02611                                 if (exponent==2.0f) (*pixel) *= exp(-dist / outer_radius_square);
02612                                 else (*pixel) *= exp(-pow(dist,exponent/2.0f) / pow((float)outer_radius_square,exponent/2.0f));
02613                         }
02614                 }
02615         };
02616 
02623         class MaskGaussNonuniformProcessor:public CoordinateProcessor
02624         {
02625           public:
02626                 MaskGaussNonuniformProcessor():radius_x(0), radius_y(0), radius_z(0), gauss_width(0)
02627                 {
02628                 }
02629 
02630                 void set_params(const Dict & new_params)
02631                 {
02632                         params = new_params;
02633 
02634                         if (params.has_key("radius_x")) radius_x=params["radius_x"];
02635                         else radius_x=5.0;
02636 
02637                         if (params.has_key("radius_y")) radius_y=params["radius_y"];
02638                         else radius_y=5.0;
02639 
02640                         if (params.has_key("radius_z")) radius_z=params["radius_z"];
02641                         else radius_z=5.0;
02642 
02643                         if (params.has_key("gauss_width")) gauss_width=params["gauss_width"];
02644                         else gauss_width=0.05f;
02645                 }
02646 
02647                 TypeDict get_param_types() const
02648                 {
02649                         TypeDict d;
02650 
02651                         d.put("radius_x", EMObject::INT, "x-axis radius");
02652                         d.put("radius_y", EMObject::INT, "y-axis radius");
02653                         d.put("radius_z", EMObject::INT, "z-axis radius");
02654                         d.put("gauss_width", EMObject::FLOAT, "Gaussian falloff width, relative to each radius, default 0.05");
02655 
02656                         return d;
02657                 }
02658 
02659                 string get_name() const
02660                 {
02661                         return NAME;
02662                 }
02663                 static Processor *NEW()
02664                 {
02665                         return new MaskGaussNonuniformProcessor();
02666                 }
02667 
02668                 string get_desc() const
02669                 {
02670                         return "A Gaussian falloff to zero. Nonisotropic, specify inner radius for x,y,z and Gaussian falloff width. Falloff \
02671 width is also nonisotropic and relative to the radii, with 1 being equal to the radius on that axis.";
02672                 }
02673 
02674                 static const string NAME;
02675 
02676           protected:
02677                 void process_pixel(float *pixel, int xi, int yi, int zi) const
02678                 {
02679                         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);
02680                         if (dist>1.0) (*pixel)*=exp(-pow((sqrt(dist)-1.0f)/gauss_width,2.0f));
02681                 }
02682 
02683                 float radius_x,radius_y,radius_z,gauss_width;
02684         };
02685 
02690         class MaskGaussInvProcessor:public CircularMaskProcessor
02691         {
02692           public:
02693                 TypeDict get_param_types() const
02694                 {
02695                         TypeDict d = CircularMaskProcessor::get_param_types();
02696                         d.put("gauss_width", EMObject::FLOAT, "Used to calculate the constant factor - gauss_width / (ny*ny)" );
02697                         d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02698                         return d;
02699                 }
02700 
02701                 string get_name() const
02702                 {
02703                         return NAME;
02704                 }
02705 
02706                 static Processor *NEW()
02707                 {
02708                         return new MaskGaussInvProcessor();
02709                 }
02710 
02711                 string get_desc() const
02712                 {
02713                         return "f(x) = f(x) / exp(-radius*radius * gauss_width / (ny*ny))";
02714                 }
02715 
02716                 static const string NAME;
02717 
02718           protected:
02719                 void calc_locals(EMData *)
02720                 {
02721                         float gauss_width = params["gauss_width"];
02722                         slice_value = gauss_width / (ny * ny);
02723                 }
02724 
02725                 void process_dist_pixel(float *pixel, float dist) const
02726                 {
02727                         (*pixel) /= exp(-dist * slice_value);
02728                 }
02729           private:
02730                 float slice_value;
02731         };
02732 
02733 
02738         class LinearPyramidProcessor:public Processor
02739         {
02740           public:
02741                 string get_name() const
02742                 {
02743                         return NAME;
02744                 }
02745 
02746                 void process_inplace(EMData *image);
02747 
02748                 static Processor *NEW()
02749                 {
02750                         return new LinearPyramidProcessor();
02751                 }
02752 
02753                 string get_desc() const
02754                 {
02755                         return "Multiplies image by a 'linear pyramid', 1-(|x-xsize/2|*|y-ysize/2|*4/(xsize*ysize))";
02756                 }
02757 
02758                 static const string NAME;
02759         };
02760 
02761 
02764         class MakeRadiusSquaredProcessor:public CircularMaskProcessor
02765         {
02766           public:
02767                 string get_name() const
02768                 {
02769                         return NAME;
02770                 }
02771                 static Processor *NEW()
02772                 {
02773                         return new MakeRadiusSquaredProcessor();
02774                 }
02775 
02776                 string get_desc() const
02777                 {
02778                         return "overwrites input, f(x) = radius * radius";
02779                 }
02780 
02781                 static const string NAME;
02782 
02783           protected:
02784                 void process_dist_pixel(float *pixel, float dist) const
02785                 {
02786                         *pixel = dist;
02787                 }
02788         };
02789 
02792         class MakeRadiusProcessor:public CircularMaskProcessor
02793         {
02794           public:
02795                 string get_name() const
02796                 {
02797                         return NAME;
02798                 }
02799                 static Processor *NEW()
02800                 {
02801                         return new MakeRadiusProcessor();
02802                 }
02803 
02804                 string get_desc() const
02805                 {
02806                         return "overwrites input, f(x) = radius;";
02807                 }
02808 
02809                 static const string NAME;
02810 
02811           protected:
02812                 void process_dist_pixel(float *pixel, float dist) const
02813                 {
02814                         *pixel = sqrt(dist);
02815                 }
02816         };
02817 
02820         class ComplexPixelProcessor:public Processor
02821         {
02822           public:
02823                 void process_inplace(EMData * image);
02824 
02825                 static string get_group_desc()
02826                 {
02827                         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.";
02828                 }
02829 
02830           protected:
02831                 virtual void process_pixel(float *x) const = 0;
02832         };
02833 
02836         class ComplexNormPixel:public ComplexPixelProcessor
02837         {
02838           public:
02839                 string get_name() const
02840                 {
02841                         return NAME;
02842                 }
02843                 static Processor *NEW()
02844                 {
02845                         return new ComplexNormPixel();
02846                 }
02847 
02848                 string get_desc() const
02849                 {
02850                         return "Each Fourier pixel will be normalized. ie - amp=1, phase=unmodified. Useful for performing phase-residual-like computations with dot products.";
02851                 }
02852 
02853                 static const string NAME;
02854 
02855           protected:
02856                 void process_pixel(float *x) const
02857                 {
02858                         *x=1.0;
02859                 }
02860         };
02861 
02865         class AreaProcessor:public Processor
02866         {
02867           public:
02868                 AreaProcessor():areasize(0), kernel(0), nx(0), ny(0), nz(0)
02869                 {
02870                 }
02871 
02872                 void process_inplace(EMData * image);
02873 
02874                 void set_params(const Dict & new_params)
02875                 {
02876                         params = new_params;
02877                         areasize = params["areasize"];
02878                 }
02879 
02880                 TypeDict get_param_types() const
02881                 {
02882                         TypeDict d;
02883                         d.put("areasize", EMObject::INT, "The width of the area to process (not radius)");
02884                         return d;
02885                 }
02886 
02887                 string get_desc() const
02888                 {
02889                         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().";
02890                 }
02891 
02892           protected:
02893                 virtual void process_pixel(float *pixel, float, float, float, float *area_matrix) const
02894                 {
02895                         for (int i = 0; i < matrix_size; i++)
02896                         {
02897                                 *pixel += area_matrix[i] * kernel[i];
02898                         }
02899                 }
02900 
02901                 virtual void create_kernel() const = 0;
02902 
02903                 int areasize;
02904                 int matrix_size;
02905                 float *kernel;
02906                 int nx;
02907                 int ny;
02908                 int nz;
02909         };
02910 
02913         class LaplacianProcessor:public AreaProcessor
02914         {
02915           public:
02916                 string get_name() const
02917                 {
02918                         return NAME;
02919                 }
02920                 static Processor *NEW()
02921                 {
02922                         return new LaplacianProcessor();
02923                 }
02924 
02925                 string get_desc() const
02926                 {
02927                         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).";
02928                 }
02929 
02930                 static const string NAME;
02931 
02932           protected:
02933                 void create_kernel() const;
02934 
02935         };
02936 
02939         class ZeroConstantProcessor:public AreaProcessor
02940         {
02941           public:
02942                 string get_name() const
02943                 {
02944                         return NAME;
02945                 }
02946                 static Processor *NEW()
02947                 {
02948                         return new ZeroConstantProcessor();
02949                 }
02950 
02951                 string get_desc() const
02952                 {
02953                         return "Contraction of data, if any nearest neighbor is 0, value -> 0, generally used iteratively";
02954                 }
02955 
02956                 static const string NAME;
02957 
02958           protected:
02959                 void process_pixel(float *pixel, float, float, float, float *matrix) const
02960                 {
02961                         if (*pixel != 0)
02962                         {
02963                                 if (*pixel == matrix[1] || *pixel == matrix[3] || *pixel == matrix[5] ||
02964                                         *pixel == matrix[7] || matrix[1] == 0 || matrix[3] == 0 ||
02965                                         matrix[5] == 0 || matrix[7] == 0) {
02966                                         *pixel = 0;
02967                                 }
02968                         }
02969                 }
02970 
02971                 void create_kernel() const
02972                 {
02973                 }
02974         };
02975 
02984         class BoxStatProcessor:public Processor
02985         {
02986           public:
02987                 void process_inplace(EMData * image);
02988 
02989                 static string get_group_desc()
02990                 {
02991                         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).";
02992                 }
02993 
02994                 TypeDict get_param_types() const
02995                 {
02996                         TypeDict d;
02997                         d.put("radius", EMObject::INT, "The radius of the search box, default is 1 which results in a 3x3 box (3 = 2xradius + 1)");
02998                         return d;
02999                 }
03000 
03001           protected:
03002                 virtual void process_pixel(float *pixel, const float *array, int n) const = 0;
03003         };
03004 
03005 
03008         class BoxMedianProcessor:public BoxStatProcessor
03009         {
03010           public:
03011                 string get_name() const
03012                 {
03013                         return NAME;
03014                 }
03015                 static Processor *NEW()
03016                 {
03017                         return new BoxMedianProcessor();
03018                 }
03019 
03020                 string get_desc() const
03021                 {
03022                         return "A processor for noise reduction. pixel = median of values surrounding pixel.";
03023                 }
03024 
03025                 static const string NAME;
03026 
03027           protected:
03028                 void process_pixel(float *pixel, const float *array, int n) const
03029                 {
03030                         float *data = new float[n];
03031                         memcpy(data, array, sizeof(float) * n);
03032 
03033                         for (int i = 0; i <= n / 2; i++)
03034                         {
03035                                 for (int j = i + 1; j < n; j++)
03036                                 {
03037                                         if (data[i] < data[j]) {
03038                                                 float t = data[i];
03039                                                 data[i] = data[j];
03040                                                 data[j] = t;
03041                                         }
03042                                 }
03043                         }
03044 
03045                         if (n % 2 != 0)
03046                         {
03047                                 *pixel = data[n / 2];
03048                         }
03049                         else {
03050                                 *pixel = (data[n / 2] + data[n / 2 - 1]) / 2;
03051                         }
03052                         if( data )
03053                         {
03054                                 delete[]data;
03055                                 data = 0;
03056                         }
03057                 }
03058         };
03059 
03062         class BoxSigmaProcessor:public BoxStatProcessor
03063         {
03064           public:
03065                 string get_name() const
03066                 {
03067                         return NAME;
03068                 }
03069                 static Processor *NEW()
03070                 {
03071                         return new BoxSigmaProcessor();
03072                 }
03073 
03074                 string get_desc() const
03075                 {
03076                         return "pixel = standard deviation of values surrounding pixel.";
03077                 }
03078 
03079                 static const string NAME;
03080 
03081           protected:
03082                 void process_pixel(float *pixel, const float *data, int n) const
03083                 {
03084                         float sum = 0;
03085                         float square_sum = 0;
03086                         for (int i = 0; i < n; i++)
03087                         {
03088                                 sum += data[i];
03089                                 square_sum += data[i] * data[i];
03090                         }
03091 
03092                         float mean = sum / n;
03093                         *pixel = sqrt(square_sum / n - mean * mean);
03094                 }
03095         };
03096 
03099         class BoxMaxProcessor:public BoxStatProcessor
03100         {
03101           public:
03102                 string get_name() const
03103                 {
03104                         return NAME;
03105                 }
03106                 static Processor *NEW()
03107                 {
03108                         return new BoxMaxProcessor();
03109                 }
03110 
03111                 string get_desc() const
03112                 {
03113                         return "peak processor: pixel = max of values surrounding pixel.";
03114                 }
03115 
03116                 static const string NAME;
03117 
03118           protected:
03119                 void process_pixel(float *pixel, const float *data, int n) const
03120                 {
03121                         float maxval = -FLT_MAX;
03122                         for (int i = 0; i < n; i++)
03123                         {
03124                                 if (data[i] > maxval) {
03125                                         maxval = data[i];
03126                                 }
03127                         }
03128                          *pixel = maxval;
03129                 }
03130         };
03131 
03134         class MinusPeakProcessor:public BoxStatProcessor
03135         {
03136           public:
03137                 string get_name() const
03138                 {
03139                         return NAME;
03140                 }
03141                 static Processor *NEW()
03142                 {
03143                         return new MinusPeakProcessor();
03144                 }
03145 
03146                 string get_desc() const
03147                 {
03148                         return "peak processor: pixel = pixel - max of values surrounding pixel. This is a sort of positive peak-finding algorithm.";
03149                 }
03150 
03151                 static const string NAME;
03152 
03153           protected:
03154                 void process_pixel(float *pixel, const float *data, int n) const
03155                 {
03156                         float maxval = -FLT_MAX;
03157                         for (int i = 0; i < n; i++)
03158                         {
03159                                 if (data[i] > maxval) {
03160                                         maxval = data[i];
03161                                 }
03162                         }
03163                          *pixel -= maxval;
03164                 }
03165         };
03166 
03170         class PeakOnlyProcessor:public BoxStatProcessor
03171         {
03172           public:
03173                 string get_name() const
03174                 {
03175                         return NAME;
03176                 }
03177                 static Processor *NEW()
03178                 {
03179                         return new PeakOnlyProcessor();
03180                 }
03181                 void set_params(const Dict & new_params)
03182                 {
03183                         params = new_params;
03184                         npeaks = params["npeaks"];
03185                         if (npeaks == 0) {
03186                                 npeaks = 1;
03187                         }
03188                 }
03189 
03190                 TypeDict get_param_types() const
03191                 {
03192                         TypeDict d;
03193                         d.put("npeaks", EMObject::INT, "the number of surrounding peaks allow to >= pixel values");
03194                         return d;
03195                 }
03196 
03197                 string get_desc() const
03198                 {
03199                         return "peak processor -> if npeaks or more surrounding values >= value, value->0";
03200                 }
03201 
03202                 static const string NAME;
03203 
03204           protected:
03205                 void process_pixel(float *pixel, const float *data, int n) const
03206                 {
03207                         int r = 0;
03208 
03209                         for (int i = 0; i < n; i++)
03210                         {
03211                                 if (data[i] >= *pixel) {
03212                                         r++;
03213                                 }
03214                         }
03215 
03216                         if (r > npeaks)
03217                         {
03218                                 *pixel = 0;
03219                         }
03220                 }
03221           private:
03222                 int npeaks;
03223         };
03224 
03229         class DiffBlockProcessor:public Processor
03230         {
03231           public:
03232                 void process_inplace(EMData * image);
03233 
03234                 string get_name() const
03235                 {
03236                         return NAME;
03237                 }
03238                 static Processor *NEW()
03239                 {
03240                         return new DiffBlockProcessor();
03241                 }
03242 
03243                 string get_desc() const
03244                 {
03245                         return "averages over cal_half_width, then sets the value in a local block";
03246                 }
03247 
03248                 TypeDict get_param_types() const
03249                 {
03250                         TypeDict d;
03251                         d.put("cal_half_width", EMObject::FLOAT, "cal_half_width is dx/dy for calculating an average");
03252                         d.put("fill_half_width", EMObject::FLOAT, "fill_half_width is dx/dy for fill/step");
03253                         return d;
03254                 }
03255 
03256                 static const string NAME;
03257         };
03258 
03263         class CutoffBlockProcessor:public Processor
03264         {
03265           public:
03266                 void process_inplace(EMData * image);
03267 
03268                 string get_name() const
03269                 {
03270                         return NAME;
03271                 }
03272                 static Processor *NEW()
03273                 {
03274                         return new CutoffBlockProcessor();
03275                 }
03276 
03277                 TypeDict get_param_types() const
03278                 {
03279                         TypeDict d;
03280                         d.put("value1", EMObject::FLOAT, "val1 is dx/dy");
03281                         d.put("value2", EMObject::FLOAT, "val2 is lowpass freq cutoff in pixels");
03282                         return d;
03283                 }
03284 
03285                 string get_desc() const
03286                 {
03287                         return "Block processor, val1 is dx/dy, val2 is lp freq cutoff in pixels. Mystery processor.";
03288                 }
03289 
03290                 static const string NAME;
03291         };
03292 
03298         class BooleanShrinkProcessor
03299         {
03300                 protected:
03308                         template<class LogicOp>
03309                         EMData* process(const EMData *const image, Dict& params);
03310 
03317                         template<class LogicOp>
03318                         void process_inplace(EMData * image, Dict& params);
03319 
03320         };
03321 
03330         class MaxShrinkProcessor:public BooleanShrinkProcessor, public Processor
03331         {
03332                 public:
03339                         virtual EMData* process(const EMData *const image)
03340                         {
03341                                 return BooleanShrinkProcessor::process<GreaterThan>(image, params);
03342                         }
03343 
03344                         // resizes the image
03345                         virtual void process_inplace(EMData * image)
03346                         {
03347                                 BooleanShrinkProcessor::process_inplace<GreaterThan>(image, params);
03348                         }
03349 
03350                         string get_desc() const
03351                         {
03352                                 return "Shrink an image by a given amount (default 2), using the maximum value found in the pixel neighborhood.";
03353                         }
03354 
03355                         string get_name() const
03356                         {
03357                                 return NAME;
03358                         }
03359                         static Processor *NEW()
03360                         {
03361                                 return new MaxShrinkProcessor();
03362                         }
03363 
03364                         TypeDict get_param_types() const
03365                         {
03366                                 TypeDict d;
03367                                 d.put("n", EMObject::INT, "The shrink factor");
03368                                 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03369                                 return d;
03370                         }
03371 
03372                         static const string NAME;
03373 
03374                 private:
03375                         struct GreaterThan
03376                         {
03377                                 inline bool operator()(float left,float right) const { return left > right; }
03378                                 inline float get_start_val() { return -10000000; }
03379                         };
03380         };
03381 
03390         class MinShrinkProcessor:public BooleanShrinkProcessor, public Processor
03391         {
03392                 public:
03399                         virtual EMData* process(const EMData *const image)
03400                         {
03401                                 return BooleanShrinkProcessor::process<LessThan>(image, params);
03402                         }
03403 
03404                         // resizes the image
03405                         virtual void process_inplace(EMData * image)
03406                         {
03407                                 BooleanShrinkProcessor::process_inplace<LessThan>(image, params);
03408                         }
03409                         string get_desc() const
03410                         {
03411                                 return "Shrink an image by a given amount (default 2), using the minimum value found in the pixel neighborhood.";
03412                         }
03413 
03414                         string get_name() const
03415                         {
03416                                 return NAME;
03417                         }
03418                         static Processor *NEW()
03419                         {
03420                                 return new MinShrinkProcessor();
03421                         }
03422 
03423                         TypeDict get_param_types() const
03424                         {
03425                                 TypeDict d;
03426                                 d.put("n", EMObject::INT, "The shrink factor");
03427                                 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03428                                 return d;
03429                         }
03430 
03431                         static const string NAME;
03432 
03433                 private:
03434                 struct LessThan
03435                 {
03436                         inline bool operator()(float left,float right) const { return left < right; }
03437                         inline float get_start_val() { return 9999999999.0f; }
03438                 };
03439         };
03440 
03447         class MeanShrinkProcessor : public Processor
03448         {
03449                 public:
03460                         virtual EMData* process(const EMData *const image);
03461 
03468                         virtual void process_inplace(EMData * image);
03469 
03470                         string get_desc() const
03471                         {
03472                                 return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
03473                         }
03474 
03475                         virtual string get_name() const
03476                         {
03477                                 return NAME;
03478                         }
03479                         static Processor *NEW()
03480                         {
03481                                 return new MeanShrinkProcessor();
03482                         }
03483 
03484                         virtual TypeDict get_param_types() const
03485                         {
03486                                 TypeDict d;
03487                                 d.put("n", EMObject::FLOAT, "The shrink factor");
03488                                 return d;
03489                         }
03490 
03491                         static const string NAME;
03492 
03493                 private:
03501                         void accrue_mean(EMData* to, const EMData *const from, const int shrinkfactor);
03502 
03509                         void accrue_mean_one_p_five(EMData* to, const EMData * const from);
03510         };
03511 
03512 
03519         class MedianShrinkProcessor : public Processor
03520         {
03521         public:
03532                 virtual EMData* process(const EMData *const image);
03533 
03540                 virtual void process_inplace(EMData * image);
03541 
03542                 string get_desc() const
03543                 {
03544                         return "Shrink an image by a given amount , using the median value found in the pixel neighborhood.";
03545                 }
03546 
03547                 virtual string get_name() const
03548                 {
03549                         return NAME;
03550                 }
03551                 static Processor *NEW()
03552                 {
03553                         return new MedianShrinkProcessor();
03554                 }
03555 
03556                 virtual TypeDict get_param_types() const
03557                 {
03558                         TypeDict d;
03559                         d.put("n", EMObject::INT, "The shrink factor");
03560                         return d;
03561                 }
03562 
03563                 static const string NAME;
03564 
03565         private:
03573                 void accrue_median(EMData* to, const EMData* const from,const int shrink_factor);
03574         };
03575 
03576 
03585         class FFTResampleProcessor : public Processor
03586         {
03587                 public:
03588                         virtual EMData* process(const EMData *const image);
03589 
03590                         virtual void process_inplace(EMData * image);
03591 
03592                         string get_desc() const
03593                         {
03594                                 return "Robust resampling of an image by clipping its Fourier transform.";
03595                         }
03596 
03597                         string get_name() const
03598                         {
03599                                 return NAME;
03600                         }
03601                         static Processor *NEW()
03602                         {
03603                                 return new FFTResampleProcessor();
03604                         }
03605 
03606                         TypeDict get_param_types() const
03607                         {
03608                                 TypeDict d;
03609                                 d.put("n", EMObject::FLOAT, "The sample rate. Less than one enlarges the image, greater than one shrinks it.");
03610                                 return d;
03611                         }
03612 
03613                         static const string NAME;
03614 
03615                 private:
03622                         void fft_resample(EMData* to, const EMData *const from, const float& sample_rate);
03623 
03624         };
03625 
03628         class GradientRemoverProcessor:public Processor
03629         {
03630           public:
03631                 void process_inplace(EMData * image);
03632 
03633                 string get_name() const
03634                 {
03635                         return NAME;
03636                 }
03637                 static Processor *NEW()
03638                 {
03639                         return new GradientRemoverProcessor();
03640                 }
03641 
03642                 string get_desc() const
03643                 {
03644                         return "Gradient remover, does a rough plane fit to find linear gradients.";
03645                 }
03646 
03647                 static const string NAME;
03648         };
03649 
03658         class GradientPlaneRemoverProcessor:public Processor
03659     {
03660           public:
03661                 void process_inplace(EMData * image);
03662 
03663                 string get_name() const
03664                 {
03665                         return NAME;
03666                 }
03667                 static Processor *NEW()
03668                 {
03669                         return new GradientPlaneRemoverProcessor();
03670                 }
03671 
03672                 string get_desc() const
03673                 {
03674                         return "Remove gradient by least square plane fit";
03675                 }
03676 
03677                 TypeDict get_param_types() const
03678                 {
03679                         TypeDict d;
03680                         d.put("mask", EMObject::EMDATA, "mask object: nonzero pixel positions will be used to fit plane. default = 0");
03681                         d.put("changeZero", EMObject::INT, "if zero pixels are modified when removing gradient. default = 0");
03682                         d.put("planeParam", EMObject::FLOATARRAY, "fitted plane parameters output");
03683                         return d;
03684                 }
03685 
03686                 static const string NAME;
03687         };
03688 
03694         class NonConvexProcessor:public Processor
03695     {
03696           public:
03697                 void process_inplace(EMData * image);
03698 
03699                 string get_name() const
03700                 {
03701                         return NAME;
03702                 }
03703                 static Processor *NEW()
03704                 {
03705                         return new NonConvexProcessor();
03706                 }
03707 
03708                 string get_desc() const
03709                 {
03710                         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).";
03711                 }
03712 
03713                 TypeDict get_param_types() const
03714                 {
03715                         TypeDict d;
03716 /*                      d.put("mask", EMObject::EMDATA, "mask object: nonzero pixel positions will be used to fit plane. default = 0");
03717                         d.put("changeZero", EMObject::INT, "if zero pixels are modified when removing gradient. default = 0");
03718                         d.put("planeParam", EMObject::FLOATARRAY, "fitted plane parameters output");*/
03719                         return d;
03720                 }
03721 
03722                 static const string NAME;
03723         };
03724 
03731         class FlattenBackgroundProcessor:public Processor
03732         {
03733                 public:
03734                         void process_inplace(EMData * image);
03735 
03736                         string get_name() const
03737                         {
03738                                 return NAME;
03739                         }
03740 
03741                         static Processor *NEW()
03742                         {
03743                                 return new FlattenBackgroundProcessor();
03744                         }
03745 
03746                         string get_desc() const
03747                         {
03748                                 return "Flattens the background by subtracting the local mean";
03749                         }
03750 
03751                         TypeDict get_param_types() const
03752                         {
03753                                 TypeDict d;
03754                                 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");
03755                                 d.put("radius", EMObject::INT, "The radius of circle/sphere that defines the local neighborhood. Exclusive of the mask argument");
03756                                 return d;
03757                         }
03758 
03759                         static const string NAME;
03760         };
03761 
03762 
03765         class RampProcessor:public Processor
03766     {
03767           public:
03768                 void process_inplace(EMData * image);
03769 
03770                 string get_name() const
03771                 {
03772                         return NAME;
03773                 }
03774                 static Processor *NEW()
03775                 {
03776                         return new RampProcessor();
03777                 }
03778 
03779                 string get_desc() const
03780                 {
03781                         return "Ramp processor -- Fits a least-squares plane "
03782                                    "to the picture, and subtracts the plane from "
03783                                    "the picture.  A wedge-shaped overall density "
03784                                    "profile can thus be removed from the picture.";
03785                 }
03786 
03787                 static const string NAME;
03788         };
03789 
03792         class VerticalStripeProcessor:public Processor
03793         {
03794           public:
03795                 void process_inplace(EMData * image);
03796 
03797                 string get_name() const
03798                 {
03799                         return NAME;
03800                 }
03801 
03802                 static Processor *NEW()
03803                 {
03804                         return new VerticalStripeProcessor();
03805                 }
03806 
03807                 string get_desc() const
03808                 {
03809                         return "Tries to fix images scanned on the zeiss for poor ccd normalization.";
03810                 }
03811 
03812                 static const string NAME;
03813         };
03814 
03817         class RealToFFTProcessor:public Processor
03818         {
03819                 public:
03820                 void process_inplace(EMData *image);
03821 
03822                 string get_name() const
03823                 {
03824                         return NAME;
03825                 }
03826 
03827                 static Processor *NEW()
03828                 {
03829                         return new RealToFFTProcessor();
03830                 }
03831 
03832                 string get_desc() const
03833                 {
03834                         return "This will replace the image with a full-circle 2D fft amplitude rendering. Note that this renders amplitude, when intensity is more common.";
03835                 }
03836 
03837                 static const string NAME;
03838         };
03839 
03840 
03843         class SigmaZeroEdgeProcessor:public Processor
03844         {
03845           public:
03846                 void process_inplace(EMData * image);
03847 
03848                 string get_name() const
03849                 {
03850                         return NAME;
03851                 }
03852                 static Processor *NEW()
03853                 {
03854                         return new SigmaZeroEdgeProcessor();
03855                 }
03856 
03857                 string get_desc() const
03858                 {
03859                         return "Fill zeroes at edges with nearest horizontal/vertical value.";
03860                 }
03861 
03862                 static const string NAME;
03863         };
03864 
03870         class BeamstopProcessor:public Processor
03871         {
03872           public:
03873                 void process_inplace(EMData * image);
03874 
03875                 string get_name() const
03876                 {
03877                         return NAME;
03878                 }
03879 
03880                 static Processor *NEW()
03881                 {
03882                         return new BeamstopProcessor();
03883                 }
03884 
03885                 string get_desc() const
03886                 {
03887                         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.";
03888                 }
03889 
03890                 TypeDict get_param_types() const
03891                 {
03892                         TypeDict d;
03893                         d.put("value1", EMObject::FLOAT, "sig multiplier");
03894                         d.put("value2", EMObject::FLOAT, "x of center");
03895                         d.put("value3", EMObject::FLOAT, "y of center");
03896                         return d;
03897                 }
03898 
03899                 static const string NAME;
03900         };
03901 
03904         class MeanZeroEdgeProcessor:public Processor
03905         {
03906           public:
03907                 void process_inplace(EMData * image);
03908 
03909                 string get_name() const
03910                 {
03911                         return NAME;
03912                 }
03913 
03914                 static Processor *NEW()
03915                 {
03916                         return new MeanZeroEdgeProcessor();
03917                 }
03918 
03919                 string get_desc() const
03920                 {
03921                         return "Fill zeroes at edges with nearest horizontal/vertical value damped towards Mean2.";
03922                 }
03923 
03924                 static const string NAME;
03925         };
03926 
03927 
03930         class AverageXProcessor:public Processor
03931         {
03932           public:
03933                 void process_inplace(EMData * image);
03934 
03935                 string get_name() const
03936                 {
03937                         return NAME;
03938                 }
03939 
03940                 static Processor *NEW()
03941                 {
03942                         return new AverageXProcessor();
03943                 }
03944 
03945                 string get_desc() const
03946                 {
03947                         return "Average along Y and replace with average";
03948                 }
03949 
03950                 static const string NAME;
03951         };
03952 
03956         class DecayEdgeProcessor:public Processor
03957         {
03958           public:
03959                 void process_inplace(EMData * image);
03960                 string get_name() const
03961                 {
03962                         return NAME;
03963                 }
03964 
03965                 static Processor *NEW()
03966                 {
03967                         return new DecayEdgeProcessor();
03968                 }
03969 
03970                 string get_desc() const
03971                 {
03972                         return "Decay edges of image to zero";
03973                 }
03974 
03975                 TypeDict get_param_types() const
03976                 {
03977                         TypeDict d;
03978                         d.put("width", EMObject::INT, "Width of the decay region around the edge of the image in pixels");
03979                         return d;
03980                 }
03981 
03982                 static const string NAME;
03983         };
03984 
03991         class ZeroEdgeRowProcessor:public Processor
03992         {
03993           public:
03994                 void process_inplace(EMData * image);
03995                 string get_name() const
03996                 {
03997                         return NAME;
03998                 }
03999 
04000                 static Processor *NEW()
04001                 {
04002                         return new ZeroEdgeRowProcessor();
04003                 }
04004 
04005                 string get_desc() const
04006                 {
04007                         return "zero edges of image on top and bottom, and on left and right.";
04008                 }
04009 
04010                 TypeDict get_param_types() const
04011                 {
04012                         TypeDict d;
04013                         d.put("x0", EMObject::INT, "The number of columns to zero from left");
04014                         d.put("x1", EMObject::INT, "The number of columns to zero from right");
04015                         d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
04016                         d.put("y1", EMObject::INT, "The number of rows to zero from the top");
04017                         return d;
04018                 }
04019 
04020                 static const string NAME;
04021         };
04022 
04031         class ZeroEdgePlaneProcessor:public Processor
04032         {
04033           public:
04034                 void process_inplace(EMData * image);
04035                 string get_name() const
04036                 {
04037                         return NAME;
04038                 }
04039 
04040                 static Processor *NEW()
04041                 {
04042                         return new ZeroEdgePlaneProcessor();
04043                 }
04044 
04045                 string get_desc() const
04046                 {
04047                         return "zero edges of volume on all sides";
04048                 }
04049 
04050                 TypeDict get_param_types() const
04051                 {
04052                         TypeDict d;
04053                         d.put("x0", EMObject::INT, "The number of columns to zero from left");
04054                         d.put("x1", EMObject::INT, "The number of columns to zero from right");
04055                         d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
04056                         d.put("y1", EMObject::INT, "The number of rows to zero from the top");
04057                         d.put("z0", EMObject::INT, "The number of slices to zero from the bottom");
04058                         d.put("z1", EMObject::INT, "The number of slices to zero from the top");
04059                         return d;
04060                 }
04061 
04062                 static const string NAME;
04063         };
04064 
04065 
04072         class BilateralProcessor:public Processor
04073         {
04074           public:
04075                 void process_inplace(EMData * image);
04076                 string get_name() const
04077                 {
04078                         return NAME;
04079                 }
04080 
04081                 string get_desc() const
04082                 {
04083                         return "Bilateral processing on 2D or 3D volume data. Bilateral processing does non-linear weighted averaging processing within a certain window. ";
04084                 }
04085 
04086                 static Processor *NEW()
04087                 {
04088                         return new BilateralProcessor();
04089                 }
04090 
04091                 TypeDict get_param_types() const
04092                 {
04093                         TypeDict d;
04094                         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.");
04095                         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.");
04096                         d.put("niter", EMObject::INT, "how many times to apply this processing on your data.");
04097                         d.put("half_width", EMObject::INT, "processing window size = (2 * half_widthh + 1) ^ 3.");
04098                         return d;
04099                 }
04100 
04101                 static const string NAME;
04102         };
04103 
04106         class NormalizeProcessor:public Processor
04107         {
04108           public:
04109                 void process_inplace(EMData * image);
04110 
04111                 static string get_group_desc()
04112                 {
04113                         return "Base class for normalization processors. Each specific normalization processor needs to define how to calculate mean and how to calculate sigma.";
04114                 }
04115 
04116           protected:
04117                 virtual float calc_sigma(EMData * image) const;
04118                 virtual float calc_mean(EMData * image) const = 0;
04119         };
04120 
04123         class NormalizeUnitProcessor:public NormalizeProcessor
04124         {
04125           public:
04126                 string get_name() const
04127                 {
04128                         return NAME;
04129                 }
04130 
04131                 static Processor *NEW()
04132                 {
04133                         return new NormalizeUnitProcessor();
04134                 }
04135 
04136                 string get_desc() const
04137                 {
04138                         return "Normalize an image so its vector length is 1.0.";
04139                 }
04140 
04141                 static const string NAME;
04142 
04143           protected:
04144                 float calc_sigma(EMData * image) const;
04145                 float calc_mean(EMData * image) const;
04146         };
04147 
04148         inline float NormalizeUnitProcessor::calc_mean(EMData *) const { return 0; }
04149 
04152         class NormalizeUnitSumProcessor:public NormalizeProcessor
04153         {
04154           public:
04155                 string get_name() const
04156                 {
04157                         return NAME;
04158                 }
04159 
04160                 static Processor *NEW()
04161                 {
04162                         return new NormalizeUnitSumProcessor();
04163                 }
04164 
04165                 string get_desc() const
04166                 {
04167                         return "Normalize an image so its elements sum to 1.0 (fails if mean=0)";
04168                 }
04169 
04170                 static const string NAME;
04171 
04172           protected:
04173                 float calc_sigma(EMData * image) const;
04174                 float calc_mean(EMData * image) const;
04175         };
04176 
04177         inline float NormalizeUnitSumProcessor::calc_mean(EMData *) const { return 0; }
04178 
04179 
04182         class NormalizeStdProcessor:public NormalizeProcessor
04183         {
04184           public:
04185                 string get_name() const
04186                 {
04187                         return NAME;
04188                 }
04189 
04190                 static Processor *NEW()
04191                 {
04192                         return new NormalizeStdProcessor();
04193                 }
04194 
04195                 string get_desc() const
04196                 {
04197                         return "do a standard normalization on an image.";
04198                 }
04199 
04200                 static const string NAME;
04201 
04202           protected:
04203                 float calc_mean(EMData * image) const;
04204         };
04205 
04210         class NormalizeMaskProcessor:public NormalizeProcessor
04211         {
04212           public:
04213                 string get_name() const
04214                 {
04215                         return NAME;
04216                 }
04217 
04218                 string get_desc() const
04219                 {
04220                         return "Uses a 1/0 mask defining a region to use for the zero-normalization.if no_sigma is 1, standard deviation not modified.";
04221                 }
04222 
04223                 static Processor *NEW()
04224                 {
04225                         return new NormalizeMaskProcessor();
04226                 }
04227 
04228                 TypeDict get_param_types() const
04229                 {
04230                         TypeDict d;
04231                         d.put("mask", EMObject::EMDATA, "the 1/0 mask defining a region to use for the zero-normalization");
04232                         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");
04233                         return d;
04234                 }
04235 
04236                 static const string NAME;
04237 
04238           protected:
04239                 float calc_sigma(EMData * image) const;
04240                 float calc_mean(EMData * image) const;
04241         };
04242 
04248         class NormalizeRampNormVar: public Processor
04249         {
04250                 public:
04251                         string get_name() const
04252                         {
04253                                 return NAME;
04254                         }
04255 
04256                         static Processor *NEW()
04257                         {
04258                                 return new NormalizeRampNormVar();
04259                         }
04260 
04261                         string get_desc() const
04262                         {
04263                                 return "First call filter.ramp on the image, then make the mean 0 and norm 1";
04264                         }
04265 
04266                         void process_inplace(EMData * image);
04267 
04268                         static const string NAME;
04269         };
04270 
04279         class NormalizeByMassProcessor: public Processor
04280         {
04281                 public:
04282                         string get_name() const
04283                         {
04284                                 return NAME;
04285                         }
04286 
04287                         static Processor *NEW()
04288                         {
04289                                 return new NormalizeByMassProcessor();
04290                         }
04291 
04292                         string get_desc() const
04293                         {
04294                                 return "Normalize the mass of the image assuming a density of 1.35 g/ml (0.81 Da/A^3) (3D only)";
04295                         }
04296 
04297                         TypeDict get_param_types() const
04298                         {
04299                                 TypeDict d;
04300                                 d.put("apix", EMObject::FLOAT,"Angstrom per pixel of the image. If not set will use the apix_x attribute of the image");
04301                                 d.put("mass", EMObject::FLOAT,"The approximate mass of protein/structure in kilodaltons");
04302                                 d.put("thr", EMObject::FLOAT,"The isosurface threshold which encapsulates the structure");
04303                                 return d;
04304                         }
04305 
04306                         void process_inplace(EMData * image);
04307 
04308                         static const string NAME;
04309         };
04310 
04311 
04314         class NormalizeEdgeMeanProcessor:public NormalizeProcessor
04315         {
04316           public:
04317                 string get_name() const
04318                 {
04319                         return NAME;
04320                 }
04321 
04322                 static Processor *NEW()
04323                 {
04324                         return new NormalizeEdgeMeanProcessor();
04325                 }
04326 
04327                 string get_desc() const
04328                 {
04329                         return "normalizes an image, mean value equals to edge mean.";
04330                 }
04331 
04332                 static const string NAME;
04333 
04334           protected:
04335                 float calc_mean(EMData * image) const;
04336         };
04337 
04340         class NormalizeCircleMeanProcessor:public NormalizeProcessor
04341         {
04342           public:
04343                 string get_name() const
04344                 {
04345                         return NAME;
04346                 }
04347 
04348                 static Processor *NEW()
04349                 {
04350                         return new NormalizeCircleMeanProcessor();
04351                 }
04352 
04353                 string get_desc() const
04354                 {
04355                         return "normalizes an image, mean value equals to mean of 2 pixel circular border.";
04356                 }
04357 
04358                 static const string NAME;
04359 
04360           protected:
04361                 float calc_mean(EMData * image) const;
04362         };
04363 
04366         class NormalizeLREdgeMeanProcessor:public NormalizeProcessor
04367         {
04368           public:
04369                 string get_name() const
04370                 {
04371                         return NAME;
04372                 }
04373 
04374                 static Processor *NEW()
04375                 {
04376                         return new NormalizeLREdgeMeanProcessor();
04377                 }
04378 
04379                 string get_desc() const
04380                 {
04381                         return "normalizes an image, uses 2 pixels on left and right edge";
04382                 }
04383 
04384                 static const string NAME;
04385 
04386           protected:
04387                 float calc_mean(EMData * image) const;
04388         };
04389 
04392         class NormalizeMaxMinProcessor:public NormalizeProcessor
04393         {
04394           public:
04395                 string get_name() const
04396                 {
04397                         return NAME;
04398                 }
04399 
04400                 static Processor *NEW()
04401                 {
04402                         return new NormalizeMaxMinProcessor();
04403                 }
04404 
04405                 string get_desc() const
04406                 {
04407                         return "normalizes an image. mean -> (maxval-minval)/2; std dev = (maxval+minval)/2;";
04408                 }
04409 
04410                 static const string NAME;
04411 
04412           protected:
04413                 float calc_sigma(EMData * image) const;
04414                 float calc_mean(EMData * image) const;
04415         };
04416 
04419         class NormalizeRowProcessor:public Processor
04420         {
04421           public:
04422                 string get_name() const
04423                 {
04424                         return NAME;
04425                 }
04426 
04427                 static Processor *NEW()
04428                 {
04429                         return new NormalizeRowProcessor();
04430                 }
04431 
04432                 string get_desc() const
04433                 {
04434                         return "normalizes each row in the image individually";
04435                 }
04436 
04437                 static const string NAME;
04438 
04439                 void process_inplace(EMData * image);
04440         };
04441 
04447         class NormalizeToLeastSquareProcessor:public Processor
04448         {
04449           public:
04450                 void process_inplace(EMData * image);
04451 
04452                 string get_name() const
04453                 {
04454                         return NAME;
04455                 }
04456 
04457                 static Processor *NEW()
04458                 {
04459                         return new NormalizeToLeastSquareProcessor();
04460                 }
04461 
04462                 TypeDict get_param_types() const
04463                 {
04464                         TypeDict d;
04465                         d.put("to", EMObject::EMDATA, "reference image normalize to");
04466                         d.put("ignore_zero", EMObject::BOOL, "If set, ignores any pixels which are exactly zero in either image. Defaut = True.");
04467                         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)");
04468                         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)");
04469                         return d;
04470                 }
04471 
04472                 string get_desc() const
04473                 {
04474                         return "use least square method to normalize";
04475                 }
04476 
04477                 static const string NAME;
04478         };
04479 
04482         class RotationalAverageProcessor:public Processor
04483         {
04484           public:
04485                 void process_inplace(EMData * image);
04486 
04487                 string get_name() const
04488                 {
04489                         return NAME;
04490                 }
04491 
04492                 static Processor *NEW()
04493                 {
04494                         return new RotationalAverageProcessor();
04495                 }
04496 
04497                 string get_desc() const
04498                 {
04499                         return "Makes image circularly/spherically symmetric.";
04500                 }
04501 
04502                 static const string NAME;
04503         };
04504 
04507         class RotationalSubstractProcessor:public Processor
04508         {
04509           public:
04510                 virtual void process_inplace(EMData * image);
04511 
04512                 virtual string get_name() const
04513                 {
04514                         return NAME;
04515                 }
04516 
04517                 static Processor *NEW()
04518                 {
04519                         return new RotationalSubstractProcessor();
04520                 }
04521 
04522                 virtual string get_desc() const
04523                 {
04524                         return "subtracts circularly/spherically symmetric part of an image.";
04525                 }
04526 
04527                 static const string NAME;
04528         };
04529 
04535         class TransposeProcessor:public Processor
04536         {
04537           public:
04538 
04543                 virtual void process_inplace(EMData * image);
04544 
04549                 virtual EMData* process(const EMData * const image);
04550 
04551                 virtual string get_name() const
04552                 {
04553                         return NAME;
04554                 }
04555 
04556                 static Processor *NEW()
04557                 {
04558                         return new TransposeProcessor();
04559                 }
04560 
04561                 virtual TypeDict get_param_types() const
04562                 {
04563                         TypeDict d;
04564                         return d;
04565                 }
04566 
04567                 virtual string get_desc() const
04568                 {
04569                         return "Get the transpose of an image. Works for 2D only";
04570                 }
04571 
04572                 static const string NAME;
04573         };
04574 
04575 
04579         class FlipProcessor:public Processor
04580         {
04581           public:
04582                 virtual void process_inplace(EMData * image);
04583 
04584                 virtual string get_name() const
04585                 {
04586                         return NAME;
04587                 }
04588 
04589                 static Processor *NEW()
04590                 {
04591                         return new FlipProcessor();
04592                 }
04593 
04594                 virtual TypeDict get_param_types() const
04595                 {
04596                         TypeDict d;
04597                         d.put("axis", EMObject::STRING, "'x', 'y', or 'z' axis.");
04598                         return d;
04599                 }
04600 
04601                 virtual string get_desc() const
04602                 {
04603                         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.";
04604                 }
04605 
04606                 static const string NAME;
04607         };
04608 
04609         /*class FlipProcessor1:public Processor
04610         {
04611           public:
04612                 void process_inplace(EMData * image);
04613 
04614                 string get_name() const
04615                 {
04616                         return "xform.flip1";
04617                 }
04618 
04619                 static Processor *NEW()
04620                 {
04621                         return new FlipProcessor1();
04622                 }
04623 
04624                 TypeDict get_param_types() const
04625                 {
04626                         TypeDict d;
04627                         d.put("axis", EMObject::STRING, "'x', 'y', or 'z' axis. 'x' means horizonal flip; 'y' means vertical flip;");
04628                         return d;
04629                 }
04630 
04631                 string get_desc() const
04632                 {
04633                         return "flip an image around an axis.";
04634                 }
04635 
04636         };*/
04637 
04642         class AddNoiseProcessor:public Processor
04643         {
04644           public:
04645                 virtual void process_inplace(EMData * image);
04646 
04647                 virtual string get_name() const
04648                 {
04649                         return NAME;
04650                 }
04651 
04652                 static Processor *NEW()
04653                 {
04654                         return new AddNoiseProcessor();
04655                 }
04656 
04657                 virtual TypeDict get_param_types() const
04658                 {
04659                         TypeDict d;
04660                         d.put("noise", EMObject::FLOAT, "noise factor used to generate Gaussian distribution random noise");
04661                         d.put("seed", EMObject::INT, "seed for random number generator");
04662                         return d;
04663                 }
04664 
04665                 virtual string get_desc() const
04666                 {
04667                         return "add noise to an image, image multiply by noise then add a random value";
04668                 }
04669 
04670                 static const string NAME;
04671 
04672           protected:
04673                 virtual float get_sigma(EMData *)
04674                 {
04675                         return 1.0;
04676                 }
04677         };
04678 
04681         class AddSigmaNoiseProcessor:public AddNoiseProcessor
04682         {
04683           public:
04684                 virtual string get_name() const
04685                 {
04686                         return NAME;
04687                 }
04688 
04689                 static Processor *NEW()
04690                 {
04691                         return new AddSigmaNoiseProcessor();
04692                 }
04693 
04694                 virtual string get_desc() const
04695                 {
04696                         return "add sigma noise.";
04697                 }
04698 
04699                 static const string NAME;
04700 
04701           protected:
04702                 float get_sigma(EMData * image);
04703         };
04704 
04713         class AddRandomNoiseProcessor:public Processor
04714         {
04715           public:
04716                 virtual void process_inplace(EMData * image);
04717 
04718                 virtual string get_name() const
04719                 {
04720                         return NAME;
04721                 }
04722 
04723                 static Processor *NEW()
04724                 {
04725                         return new AddRandomNoiseProcessor();
04726                 }
04727 
04728                 virtual TypeDict get_param_types() const
04729                 {
04730                         TypeDict d;
04731                         d.put("n", EMObject::INT);
04732                         d.put("x0", EMObject::FLOAT);
04733                         d.put("dx", EMObject::FLOAT);
04734                         d.put("y", EMObject::FLOATARRAY);
04735                         d.put("interpolation", EMObject::INT);
04736                         d.put("seed", EMObject::INT, "seed for random number generator");
04737                         return d;
04738                 }
04739 
04740                 virtual string get_desc() const
04741                 {
04742                         return "add spectral noise to a complex image.";
04743                 }
04744 
04745                 static const string NAME;
04746         };
04747 
04753         class FourierToCornerProcessor:public Processor
04754         {
04755                 public:
04761                         virtual void process_inplace(EMData * image);
04762 
04763                         virtual string get_name() const
04764                         {
04765                                 return NAME;
04766                         }
04767 
04768                         static Processor *NEW()
04769                         {
04770                                 return new FourierToCornerProcessor();
04771                         }
04772 
04773                         virtual string get_desc() const
04774                         {
04775                                 return "Undoes the xform.fourierorigin.tocenter processor";
04776                         }
04777 
04778                         static const string NAME;
04779         };
04780 
04781 
04793         class FourierToCenterProcessor:public Processor
04794         {
04795                 public:
04801                         virtual void process_inplace(EMData * image);
04802 
04803                         virtual string get_name() const
04804                         {
04805                                 return NAME;
04806                         }
04807 
04808                         static Processor *NEW()
04809                         {
04810                                 return new FourierToCenterProcessor();
04811                         }
04812 
04813                         virtual string get_desc() const
04814                         {
04815                                 return "Translates the origin in Fourier space from the corner to the center in y and z - works in 2D and 3D";
04816                         }
04817 
04818                         static const string NAME;
04819         };
04820 
04830         class Phase180Processor:public Processor
04831         {
04832                 protected:
04845                         void swap_corners_180(EMData * image);
04846 
04858                         void swap_central_slices_180(EMData * image);
04859 
04866                         void fourier_phaseshift180(EMData * image);
04867 
04868         };
04869 
04879         class PhaseToCenterProcessor:public Phase180Processor
04880         {
04881                 public:
04882                         virtual void process_inplace(EMData * image);
04883 
04884                         virtual string get_name() const
04885                         {
04886                                 return NAME;
04887                         }
04888 
04889                         static Processor *NEW()
04890                         {
04891                                 return new PhaseToCenterProcessor();
04892                         }
04893 
04894                         virtual string get_desc() const
04895                         {
04896                                 return "Undoes the effect of the xform.phaseorigin.tocorner processor";
04897                         }
04898 
04899                         static const string NAME;
04900         };
04901 
04909         class PhaseToCornerProcessor:public Phase180Processor
04910         {
04911                 public:
04912                         virtual void process_inplace(EMData * image);
04913 
04914                         virtual string get_name() const
04915                         {
04916                                 return NAME;
04917                         }
04918 
04919                         static Processor *NEW()
04920                         {
04921                                 return new PhaseToCornerProcessor();
04922                         }
04923 
04924                         virtual string get_desc() const
04925                         {
04926                                 return "Translates a centered image to the corner in a forward fashion";
04927                         }
04928 
04929                         static const string NAME;
04930         };
04931 
04936         class AutoMask2DProcessor:public Processor
04937         {
04938           public:
04939                 virtual void process_inplace(EMData * image);
04940 
04941                 virtual string get_name() const
04942                 {
04943                         return NAME;
04944                 }
04945 
04946                 static Processor *NEW()
04947                 {
04948                         return new AutoMask2DProcessor();
04949                 }
04950 
04951                 virtual TypeDict get_param_types() const
04952                 {
04953                         TypeDict d;
04954                         d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
04955                         d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
04956                         d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
04957                         d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
04958                         d.put("nshells", EMObject::INT, "The number of dilation operations");
04959                         d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
04960                         d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
04961                         d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
04962                         return d;
04963                 }
04964 
04965                 virtual string get_desc() const
04966                 {
04967                         return "2D version of mask.auto3d";
04968                 }
04969 
04970                 static const string NAME;
04971         };
04972 
04973 
04980         class AutoMaskAsymUnit:public Processor
04981         {
04982                 public:
04983                         virtual void process_inplace(EMData * image);
04984 
04985                         virtual string get_name() const
04986                         {
04987                                 return NAME;
04988                         }
04989 
04990                         static Processor *NEW()
04991                         {
04992                                 return new AutoMaskAsymUnit();
04993                         }
04994 
04995                         virtual TypeDict get_param_types() const
04996                         {
04997                                 TypeDict d;
04998                                 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.");
04999                                 d.put("sym", EMObject::STRING, "The symmetry, for example, d7");
05000                                 return d;
05001                         }
05002 
05003                         virtual string get_desc() const
05004                         {
05005                                 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.";
05006                         }
05007 
05008                         static const string NAME;
05009         };
05010 
05015         class AutoMask3DProcessor:public Processor
05016         {
05017           public:
05018                 virtual void process_inplace(EMData * image);
05019 
05020                 virtual string get_name() const
05021                 {
05022                         return NAME;
05023                 }
05024 
05025                 static Processor *NEW()
05026                 {
05027                         return new AutoMask3DProcessor();
05028                 }
05029 
05030                 virtual TypeDict get_param_types() const
05031                 {
05032                         TypeDict d;
05033                         d.put("threshold1", EMObject::FLOAT);
05034                         d.put("threshold2", EMObject::FLOAT);
05035                         return d;
05036                 }
05037 
05038                 virtual string get_desc() const
05039                 {
05040                         return "Tries to mask out only interesting density";
05041                 }
05042 
05043                 static void search_nearby(float *dat, float *dat2, int nx, int ny, int nz, float thr);
05044                 static void fill_nearby(float *dat2, int nx, int ny, int nz);
05045 
05046                 static const string NAME;
05047         };
05048 
05056         class AutoMask3D2Processor:public Processor
05057         {
05058           public:
05059                 virtual void process_inplace(EMData * image);
05060 
05061                 virtual string get_name() const
05062                 {
05063                         return NAME;
05064                 }
05065 
05066                 static Processor *NEW()
05067                 {
05068                         return new AutoMask3D2Processor();
05069                 }
05070 
05071                 virtual string get_desc() const
05072                 {
05073                         return "Tries to mask out only interesting density using something akin to a flood file approach.";
05074                 }
05075 
05076                 virtual TypeDict get_param_types() const
05077                 {
05078                         TypeDict d;
05079                         d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
05080                         d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
05081                         d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
05082                         d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
05083                         d.put("nshells", EMObject::INT, "The number of dilation operations");
05084                         d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
05085                         d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
05086                         d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
05087                         return d;
05088                 }
05089 
05090                 static const string NAME;
05091         };
05092 
05096         class AddMaskShellProcessor:public Processor
05097         {
05098           public:
05099                 virtual void process_inplace(EMData * image);
05100 
05101                 virtual string get_name() const
05102                 {
05103                         return NAME;
05104                 }
05105 
05106                 virtual string get_desc() const
05107                 {
05108                         return "Add additional shells/rings to an existing 1/0 mask image";
05109                 }
05110 
05111                 static Processor *NEW()
05112                 {
05113                         return new AddMaskShellProcessor();
05114                 }
05115 
05116                 virtual TypeDict get_param_types() const
05117                 {
05118                         TypeDict d;
05119                         d.put("nshells", EMObject::INT, "number of shells to add");
05120                         return d;
05121                 }
05122 
05123                 static const string NAME;
05124         };
05125 
05130         class PhaseToMassCenterProcessor:public Processor
05131         {
05132                 public:
05133                         virtual void process_inplace(EMData * image);
05134 
05135                         virtual string get_name() const
05136                         {
05137                                 return NAME;
05138                         }
05139 
05140                         static Processor *NEW()
05141                         {
05142                                 return new PhaseToMassCenterProcessor();
05143                         }
05144 
05145                         virtual string get_desc() const
05146                         {
05147                                 return "centers the image the center of mass, which is calculated using Fourier phases, ignores old dx, dy.";
05148                         }
05149 
05150                         virtual TypeDict get_param_types() const
05151                         {
05152                                 TypeDict d;
05153                                 d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05154                                 return d;
05155                         }
05156 
05157                         static const string NAME;
05158         };
05159 
05164         class ToMassCenterProcessor:public Processor
05165         {
05166           public:
05167                 virtual void process_inplace(EMData * image);
05168 
05169                 virtual string get_name() const
05170                 {
05171                         return NAME;
05172                 }
05173 
05174                 static Processor *NEW()
05175                 {
05176                         return new ToMassCenterProcessor();
05177                 }
05178 
05179                 virtual string get_desc() const
05180                 {
05181                         return "ToMassCenterProcessor centers image at center of mass, with a threshold. Only values higher than the threshold are considered.";
05182                 }
05183 
05184                 virtual TypeDict get_param_types() const
05185                 {
05186                         TypeDict d;
05187                         d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05188                         d.put("threshold", EMObject::FLOAT, "Only values larger than the threshold are included in the center of mass computation. Default is 0.");
05189 //                      d.put("positive", EMObject::INT, "uses only densities >0 for the calculatton");
05190                         return d;
05191                 }
05192 
05193                 static const string NAME;
05194         };
05195 
05199         class ACFCenterProcessor:public Processor
05200         {
05201           public:
05202                 virtual void process_inplace(EMData * image);
05203 
05204                 virtual string get_name() const
05205                 {
05206                         return NAME;
05207                 }
05208 
05209                 static Processor *NEW()
05210                 {
05211                         return new ACFCenterProcessor();
05212                 }
05213 
05214                 virtual string get_desc() const
05215                 {
05216                         return "Center image using self-convolution.";
05217                 }
05218 
05219                 virtual TypeDict get_param_types() const
05220                 {
05221                         TypeDict d;
05222                         return d;
05223                 }
05224 
05225                 static const string NAME;
05226         };
05227 
05232         class SNRProcessor:public Processor
05233         {
05234           public:
05235                 virtual void process_inplace(EMData * image);
05236 
05237                 virtual string get_name() const
05238                 {
05239                         return NAME;
05240                 }
05241 
05242                 static Processor *NEW()
05243                 {
05244                         return new SNRProcessor();
05245                 }
05246 
05247                 virtual string get_desc() const
05248                 {
05249                         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.";
05250                 }
05251 
05252                 virtual TypeDict get_param_types() const
05253                 {
05254                         TypeDict d;
05255                         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");
05256                         d.put("snrfile", EMObject::STRING, "structure factor file name");
05257                         return d;
05258                 }
05259 
05260                 static const string NAME;
05261         };
05262 
05266         class FileFourierProcessor:public Processor
05267         {
05268           public:
05269                 virtual void process_inplace(EMData * image);
05270 
05271                 virtual string get_name() const
05272                 {
05273                         return NAME;
05274                 }
05275 
05276                 virtual string get_desc() const
05277                 {
05278                         return "A fourier processor specified in a 2 column text file.";
05279                 }
05280 
05281                 static Processor *NEW()
05282                 {
05283                         return new FileFourierProcessor();
05284                 }
05285 
05286                 virtual TypeDict get_param_types() const
05287                 {
05288                         TypeDict d;
05289                         d.put("filename", EMObject::STRING, "file name for a 2 column text file which specified a radial function data array.");
05290                         return d;
05291                 }
05292 
05293                 static const string NAME;
05294         };
05295 
05306         class SymSearchProcessor:public Processor
05307         {
05308           public:
05309                 virtual void process_inplace(EMData * image);
05310 
05311                 virtual string get_name() const
05312                 {
05313                         return NAME;
05314                 }
05315 
05316                 virtual string get_desc() const
05317                 {
05318                         return "Identifiy the best symmetry in the given symmetry list for each pixel and then apply the best symmetry to each pixel.";
05319                 }
05320 
05321                 static Processor *NEW()
05322                 {
05323                         return new SymSearchProcessor();
05324                 }
05325 
05326                 virtual TypeDict get_param_types() const
05327                 {
05328                         TypeDict d;
05329                         d.put("sym", EMObject::STRINGARRAY, "the list of symmetries to search");
05330                         d.put("thresh", EMObject::FLOAT, "the minimal level of symmetry to be accepted (0-1)");
05331                         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");
05332                         d.put("symlabel_map", EMObject::EMDATA, "the optional return map when output_symlabel=1");
05333                         return d;
05334                 }
05335 
05336                 static const string NAME;
05337         };
05338 
05344         class LocalNormProcessor:public Processor
05345         {
05346           public:
05347                 void process_inplace(EMData * image);
05348 
05349                 virtual string get_name() const
05350                 {
05351                         return NAME;
05352                 }
05353 
05354                 static Processor *NEW()
05355                 {
05356                         return new LocalNormProcessor();
05357                 }
05358 
05359                 virtual string get_desc() const
05360                 {
05361                         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.";
05362                 }
05363 
05364                 virtual TypeDict get_param_types() const
05365                 {
05366                         TypeDict d;
05367                         d.put("threshold", EMObject::FLOAT, "an isosurface threshold at which all desired features are visible");
05368                         d.put("radius", EMObject::FLOAT, "a normalization size similar to an lp= value");
05369                         d.put("apix", EMObject::FLOAT, "Angstrom per pixel ratio");
05370                         return d;
05371                 }
05372 
05373                 static const string NAME;
05374         };
05375 
05380         class IndexMaskFileProcessor:public Processor
05381         {
05382           public:
05383                 virtual void process_inplace(EMData * image);
05384 
05385                 virtual string get_name() const
05386                 {
05387                         return NAME;
05388                 }
05389 
05390                 static Processor *NEW()
05391                 {
05392                         return new IndexMaskFileProcessor();
05393                 }
05394 
05395                 virtual TypeDict get_param_types() const
05396                 {
05397                         TypeDict d;
05398                         d.put("filename", EMObject::STRING, "mask image file name");
05399                         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");
05400                         return d;
05401                 }
05402 
05403                 virtual string get_desc() const
05404                 {
05405                         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.";
05406                 }
05407 
05408                 static const string NAME;
05409         };
05410 
05414         class CoordinateMaskFileProcessor:public Processor
05415         {
05416           public:
05417                 virtual void process_inplace(EMData * image);
05418 
05419                 virtual string get_name() const
05420                 {
05421                         return NAME;
05422                 }
05423 
05424                 static Processor *NEW()
05425                 {
05426                         return new CoordinateMaskFileProcessor();
05427                 }
05428 
05429                 virtual string get_desc() const
05430                 {
05431                         return "Multiplies the image by the specified file using pixel coordinates instead of pixel indices. The images can be different size.";
05432                 }
05433 
05434                 virtual TypeDict get_param_types() const
05435                 {
05436                         TypeDict d;
05437                         d.put("filename", EMObject::STRING, "mask image file name");
05438                         return d;
05439                 }
05440 
05441                 static const string NAME;
05442         };
05443 
05454         class PaintProcessor:public Processor
05455         {
05456           public:
05457                 PaintProcessor():x(0), y(0), z(0),r1(0), v1(0.0), r2(0), v2(0.0)
05458                 {
05459                 }
05460 
05461                 virtual string get_name() const
05462                 {
05463                         return NAME;
05464                 }
05465 
05466                 static Processor *NEW()
05467                 {
05468                         return new PaintProcessor();
05469                 }
05470 
05471                 virtual string get_desc() const
05472                 {
05473                         return "Paints a circle with a decaying edge into the image. r<r1 -> v1, r1<r<r2 -> (v1,v2), r>r2 unchanged";
05474                 }
05475 
05476                 virtual TypeDict get_param_types() const
05477                 {
05478                         TypeDict d;
05479                         d.put("x", EMObject::INT, "x coordinate for Center of circle");
05480                         d.put("y", EMObject::INT, "y coordinate for Center of circle");
05481                         d.put("z", EMObject::INT, "z coordinate for Center of circle");
05482                         d.put("r1", EMObject::INT, "Inner radius");
05483                         d.put("v1", EMObject::FLOAT, "Inner value");
05484                         d.put("r2", EMObject::INT, "Outter radius");
05485                         d.put("v2", EMObject::FLOAT, "Outer Value");
05486                         return d;
05487                 }
05488 
05489                 virtual void set_params(const Dict & new_params)
05490                 {
05491                         params = new_params;
05492 
05493                         if (params.has_key("x")) x = params["x"];
05494                         if (params.has_key("y")) y = params["y"];
05495                         if (params.has_key("z")) z = params["z"];
05496                         if (params.has_key("r1")) r1 = params["r1"];
05497                         if (params.has_key("r2")) r2 = params["r2"];
05498                         if (params.has_key("v1")) v1 = params["v1"];
05499                         if (params.has_key("v2")) v2 = params["v2"];
05500                 }
05501 
05502                 static const string NAME;
05503 
05504                 protected:
05505                 virtual void process_inplace(EMData *image);
05506 
05507                 int x,y,z,r1;
05508                 float v1;
05509                 int r2;
05510                 float v2;
05511 
05512         };
05513 
05514 
05519         class DirectionalSumProcessor : public Processor
05520         {
05521           public:
05522                 virtual string get_name() const
05523                 {
05524                         return NAME;
05525                 }
05526 
05527                 static Processor *NEW()
05528                 {
05529                         return new DirectionalSumProcessor();
05530                 }
05531 
05535                 virtual EMData* process(const EMData* const image);
05536 
05540                 virtual void process_inplace(EMData*) {
05541                         throw InvalidCallException("The directional sum processor does not work inplace");
05542                 }
05543 
05544                 virtual TypeDict get_param_types() const
05545                 {
05546                         TypeDict d;
05547                         d.put("axis", EMObject::STRING,"The direction of the sum, either x,y or z. Returned axes are xy, xz or zy.");
05548                         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)");
05549                         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)");
05550                         return d;
05551                 }
05552 
05553                 string get_desc() const
05554                 {
05555                         return "Calculates the projection of the image along one of the axial directions, either x, y or z";
05556                 }
05557 
05558                 static const string NAME;
05559         };
05560 
05568         class WatershedProcessor:public Processor
05569         {
05570           public:
05571                 virtual void process_inplace(EMData * image);
05572 
05573                 virtual string get_name() const
05574                 {
05575                         return NAME;
05576                 }
05577 
05578                 static Processor *NEW()
05579                 {
05580                         return new WatershedProcessor();
05581                 }
05582 
05583                 virtual string get_desc() const
05584                 {
05585                         return "Does a watershed";
05586                 }
05587 
05588                 virtual TypeDict get_param_types() const
05589                 {
05590                         TypeDict d;
05591                         d.put("xpoints", EMObject::FLOATARRAY,"x coordinates");
05592                         d.put("ypoints", EMObject::FLOATARRAY,"y coordinates");
05593                         d.put("zpoints", EMObject::FLOATARRAY,"z coordinates");
05594                         d.put("minval", EMObject::FLOAT,"min value");
05595                         return d;
05596                 }
05597 
05598                 static const string NAME;
05599 
05600           private:
05601                   vector<Vec3i > watershed(EMData* mask, EMData* image, const float& threshold, const Vec3i& cordinate, const int mask_value);
05602                   vector<Vec3i > find_region(EMData* mask,const vector<Vec3i >& coords, const int mask_value, vector<Vec3i >& region);
05603 
05604         };
05605 
05615         template<class Type>
05616         class BinaryOperateProcessor : public Processor{
05617                 public:
05622                         virtual void process_inplace(EMData * image) {
05623                                 if ( ! params.has_key("with") ) throw InvalidParameterException("You must supply the \"with\" parameter");
05624                                 EMData* with = params["with"];
05625 
05626                                 if ( with->get_xsize() != image->get_xsize() || with->get_ysize() != image->get_ysize() || with->get_zsize() != image->get_zsize() )
05627                                         throw ImageDimensionException("The images you are operating on do not have the same dimensions");
05628 
05629                                 float* image_data = image->get_data();
05630                                 float* with_data = with->get_data();
05631 
05632                                 std::transform(image_data,image_data+image->get_size(),with_data,image_data,Type::binary_operate);
05633                                 image->update();
05634                         }
05635 
05636                         virtual string get_name() const
05637                         {
05638                                 return op.get_name();
05639                         }
05640 
05641                         virtual string get_desc() const
05642                         {
05643                                 return op.get_desc();
05644                         }
05645 
05646                         static Processor *NEW()
05647                         {
05648                                 return new BinaryOperateProcessor<Type>();
05649                         }
05650 
05651                         virtual TypeDict get_param_types() const
05652                         {
05653                                 TypeDict d;
05654                                 d.put("with", EMObject::EMDATA,"The second image");
05655                                 return d;
05656                         }
05657 
05658                         static const string NAME;
05659                 private:
05660                         Type op;
05661         };
05662 
05663         class MaxPixelOperator {
05664                 public:
05665                 string get_name() const
05666                 {
05667                         return NAME;
05668                 }
05669 
05670                 string get_desc() const
05671                 {
05672                         return "Compares pixels in two images, returning an image with the maximum pixel value in each pixel location";
05673                 }
05674 
05675                 static float binary_operate(const float& left, const float& right) {
05676                         if (left > right) return left;
05677                         return right;
05678                 }
05679 
05680                 static const string NAME;
05681         };
05682 
05683         class MinPixelOperator {
05684                 public:
05685                         string get_name() const
05686                         {
05687                                 return NAME;
05688                         }
05689 
05690                         string get_desc() const
05691                         {
05692                                 return "Compares pixels in two images, returning an image with the minimum pixel value in each pixel location";
05693                         }
05694 
05695                         static float binary_operate(const float& left, const float& right) {
05696                                 if (left < right) return left;
05697                                 return right;
05698                         }
05699 
05700                         static const string NAME;
05701         };
05702 
05706         class MatchSFProcessor:public FourierAnlProcessor
05707         {
05708           public:
05709 
05710                 virtual string get_name() const
05711                 {
05712                         return NAME;
05713                 }
05714 
05715                 virtual string get_desc() const
05716                 {
05717                         return "Filters the image so its 1-D power spectrum matches a second image";
05718                 }
05719 
05720                 static Processor *NEW()
05721                 {
05722                         return new MatchSFProcessor();
05723                 }
05724 
05725                 virtual TypeDict get_param_types() const
05726                 {
05727                         TypeDict d;
05728                         d.put("to", EMObject::EMDATA, "The image to match with. Make sure apix values are correct.");
05729                         return d;
05730                 }
05731 
05732                 static const string NAME;
05733 
05734           protected:
05735                 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05736         };
05737 
05738 
05743         class SetSFProcessor:public FourierAnlProcessor
05744         {
05745           public:
05746 
05747                 virtual string get_name() const
05748                 {
05749                         return NAME;
05750                 }
05751 
05752                 virtual string get_desc() const
05753                 {
05754                         return "Filters the image so its 1-D power spectrum matches a supplied X-Y curve";
05755                 }
05756 
05757                 static Processor *NEW()
05758                 {
05759                         return new SetSFProcessor();
05760                 }
05761 
05762                 virtual TypeDict get_param_types() const
05763                 {
05764                         TypeDict d;
05765                         d.put("strucfac", EMObject::XYDATA, "An XYData object contaning the curve to be imposed as a function of S");
05766                         d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
05767                         return d;
05768                 }
05769 
05770                 static const string NAME;
05771 
05772           protected:
05773                 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05774         };
05775 
05779         class SmartMaskProcessor:public Processor
05780         {
05781           public:
05782                 virtual void process_inplace(EMData * image);
05783 
05784                 virtual string get_name() const
05785                 {
05786                         return NAME;
05787                 }
05788 
05789                 static Processor *NEW()
05790                 {
05791                         return new SmartMaskProcessor();
05792                 }
05793 
05794                 virtual string get_desc() const
05795                 {
05796                         return "Smart mask processor.";
05797                 }
05798 
05799                 virtual TypeDict get_param_types() const
05800                 {
05801                         TypeDict d;
05802                         d.put("mask", EMObject::FLOAT, "mask value");
05803                         return d;
05804                 }
05805 
05806                 static const string NAME;
05807         };
05808 
05813         class IterBinMaskProcessor:public Processor
05814         {
05815           public:
05816                 virtual void process_inplace(EMData * image);
05817 
05818                 virtual string get_name() const
05819                 {
05820                         return NAME;
05821                 }
05822 
05823                 virtual string get_desc() const
05824                 {
05825                         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.";
05826                 }
05827 
05828                 static Processor *NEW()
05829                 {
05830                         return new IterBinMaskProcessor();
05831                 }
05832 
05833                 virtual TypeDict get_param_types() const
05834                 {
05835                         TypeDict d;
05836                         d.put("val1", EMObject::FLOAT, "number of pixels to expand");
05837                         d.put("val2", EMObject::FLOAT, "number of Gaussian pixels to expand, following the first expansion");
05838                         return d;
05839                 }
05840 
05841                 static const string NAME;
05842         };
05843 
05846         class TestImageProcessor : public Processor
05847         {
05848         public:
05849                 static string get_group_desc()
05850                 {
05851                         return "Base class for a group of 'processors' used to create test image.";
05852                 }
05853 
05854         protected:
05855                 void preprocess(EMData * image);
05856                 int nx, ny, nz; //this is the size of the source image
05857         };
05858 
05867         class TestImagePureGaussian : public TestImageProcessor
05868         {
05869         public:
05870                 virtual void process_inplace(EMData * image);
05871 
05872                 virtual string get_name() const
05873                 {
05874                         return NAME;
05875                 }
05876 
05877                 virtual string get_desc() const
05878                 {
05879                         return "Replace a source image as a strict Gaussian ";
05880                 }
05881 
05882                 static Processor * NEW()
05883                 {
05884                         return new TestImagePureGaussian();
05885                 }
05886 
05887                 virtual TypeDict get_param_types() const
05888                 {
05889                         TypeDict d;
05890                         d.put("x_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on x direction");
05891                         d.put("y_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on y direction");
05892                         d.put("z_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on z direction");
05893                         d.put("x_center", EMObject::FLOAT, "center for this Gaussian blob on x direction" );
05894                         d.put("y_center", EMObject::FLOAT, "center for this Gaussian blob on y direction" );
05895                         d.put("z_center", EMObject::FLOAT, "center for this Gaussian blob on z direction" );
05896                         return d;
05897                 }
05898 
05899                 static const string NAME;
05900         };
05901 
05905         class TestImageFourierNoiseGaussian : public TestImageProcessor
05906         {
05907         public:
05908                 virtual void process_inplace(EMData * image);
05909 
05910                 virtual string get_name() const
05911                 {
05912                         return NAME;
05913                 }
05914 
05915                 virtual string get_desc() const
05916                 {
05917                         return "Replace a source image with pink Fourier noise, based on a Gaussian. Random phase.";
05918                 }
05919 
05920                 static Processor * NEW()
05921                 {
05922                         return new TestImageFourierNoiseGaussian();
05923                 }
05924 
05925                 virtual TypeDict get_param_types() const
05926                 {
05927                         TypeDict d;
05928                         d.put("sigma", EMObject::FLOAT, "sigma value");
05929                         return d;
05930                 }
05931 
05932                 static const string NAME;
05933         };
05934 
05939         class TestImageFourierNoiseProfile : public TestImageProcessor
05940         {
05941         public:
05942                 virtual void process_inplace(EMData * image);
05943 
05944                 virtual string get_name() const
05945                 {
05946                         return NAME;
05947                 }
05948 
05949                 virtual string get_desc() const
05950                 {
05951                         return "Replace a source image with Fourier noise using amplitude information that is stored in a profile.";
05952                 }
05953 
05954                 static Processor * NEW()
05955                 {
05956                         return new TestImageFourierNoiseProfile();
05957                 }
05958 
05959                 virtual TypeDict get_param_types() const
05960                 {
05961                         TypeDict d;
05962                         d.put("profile", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
05963                         return d;
05964                 }
05965 
05966                 static const string NAME;
05967         };
05968 
05969 
05974         class CTFSNRWeightProcessor : public TestImageProcessor
05975         {
05976                 public:
05977                         virtual void process_inplace(EMData * image);
05978 
05979                         virtual string get_name() const
05980                         {
05981                                 return NAME;
05982                         }
05983 
05984                         virtual string get_desc() const
05985                         {
05986                                 return "Weight the amplitudes of an image based on radial noise and snr curves ";
05987                         }
05988 
05989                         static Processor * NEW()
05990                         {
05991                                 return new CTFSNRWeightProcessor();
05992                         }
05993 
05994                         virtual TypeDict get_param_types() const
05995                         {
05996                                 TypeDict d;
05997                                 d.put("noise", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
05998                                 d.put("snr", EMObject::FLOATARRAY, "Squared amplitude divided by squared noise amplitude. As in, what is the EMAN2CTF.snr attribute");
05999                                 d.put("boost", EMObject::FLOAT, "Multiplicative signal boost");
06000                                 return d;
06001                         }
06002 
06003                         static const string NAME;
06004         };
06005 
06006 
06007 
06012         class TestImageLineWave : public TestImageProcessor
06013         {
06014                 public:
06015                         virtual void process_inplace(EMData * image);
06016 
06017                         virtual string get_name() const
06018                         {
06019                                 return NAME;
06020                         }
06021 
06022                         virtual string get_desc() const
06023                         {
06024                                 return "Insert an oscillating sine wave into the pixel data";
06025                         }
06026 
06027                         static Processor * NEW()
06028                         {
06029                                 return new TestImageLineWave();
06030                         }
06031 
06032                         virtual TypeDict get_param_types() const
06033                         {
06034                                 TypeDict d;
06035                                 d.put("period", EMObject::FLOAT, "The period of the oscillating sine wave. Default 10.");
06036                                 return d;
06037                         }
06038 
06039                         static const string NAME;
06040         };
06041 
06042 
06050         class TestTomoImage : public TestImageProcessor
06051         {
06052                 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 "Make an image consisting various objects, useful for tomographic testing";
06066                         }
06067 
06068                         static Processor * NEW()
06069                         {
06070                                 return new TestTomoImage();
06071                         }
06072 
06073                         static const string NAME;
06074 
06075                 private:
06076                         void insert_solid_ellipse( EMData* image, const Region& region, const float& value, const Transform& t3d  = Transform() );
06077                         void insert_hollow_ellipse( EMData* image, const Region& region, const float& value, const int& radius, const Transform& t3d = Transform() );
06078                         void insert_rectangle( EMData* image, const Region& region, const float& value, const Transform& t3d = Transform() );
06079         };
06080 
06088         class TestImageGradient : public TestImageProcessor
06089         {
06090                 public:
06091                         virtual void process_inplace(EMData * image);
06092 
06093                         virtual string get_name() const
06094                         {
06095                                 return NAME;
06096                         }
06097 
06098                         virtual string get_desc() const
06099                         {
06100                                 return "Make a gradient image of the form y=mx+b, where x is any of the image axes.";
06101                         }
06102 
06103                         static Processor * NEW()
06104                         {
06105                                 return new TestImageGradient();
06106                         }
06107 
06108                         virtual TypeDict get_param_types() const
06109                         {
06110                                 TypeDict d;
06111                                 d.put("axis", EMObject::STRING, "The axis the will be used to determine pixel values. Must be x,y or z");
06112                                 d.put("m", EMObject::FLOAT, "m in the equation m*axis+b. Default is 1.0");
06113                                 d.put("b", EMObject::FLOAT, "b in the equation m*axis+b. Default is 0.0");
06114                                 return d;
06115                         }
06116 
06117                         static const string NAME;
06118         };
06119 
06127         class TestImageAxes : public TestImageProcessor
06128         {
06129                 public:
06134                         virtual void process_inplace(EMData * image);
06135 
06136                         virtual string get_name() const
06137                         {
06138                                 return NAME;
06139                         }
06140 
06141                         virtual string get_desc() const
06142                         {
06143                                 return "Make an image consisting of a single cross";
06144                         }
06145 
06146                         static Processor * NEW()
06147                         {
06148                                 return new TestImageAxes();
06149                         }
06150 
06151                         virtual TypeDict get_param_types() const
06152                         {
06153                                 TypeDict d;
06154                                 d.put("int", EMObject::FLOAT, "radius of the lines emanating from the origin");
06155                                 d.put("fill", EMObject::FLOAT, "value to make non-zero pixels");
06156                                 return d;
06157                         }
06158 
06159                         static const string NAME;
06160         };
06161 
06167         class TestImageGaussian : public TestImageProcessor
06168         {
06169         public:
06170                 virtual void process_inplace(EMData * image);
06171 
06172                 virtual string get_name() const
06173                 {
06174                         return NAME;
06175                 }
06176 
06177                 virtual string get_desc() const
06178                 {
06179                         return "Replace a source image as a Gaussian Blob";
06180                 }
06181 
06182                 static Processor * NEW()
06183                 {
06184                         return new TestImageGaussian();
06185                 }
06186 
06187                 virtual TypeDict get_param_types() const
06188                 {
06189                         TypeDict d;
06190                         d.put("sigma", EMObject::FLOAT, "sigma value for this Gaussian blob");
06191                         d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06192                         d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06193                         return d;
06194                 }
06195 
06196                 static const string NAME;
06197         };
06198 
06201         class TestImageScurve : public TestImageProcessor
06202         {
06203         public:
06204                 virtual void process_inplace(EMData * image);
06205 
06206                 virtual string get_name() const
06207                 {
06208                         return NAME;
06209                 }
06210 
06211                 virtual string get_desc() const
06212                 {
06213                         return "Replace a source image with a lumpy S-curve used for alignment testing";
06214                 }
06215 
06216                 static Processor * NEW()
06217                 {
06218                         return new TestImageScurve();
06219                 }
06220 
06221                 virtual TypeDict get_param_types() const
06222                 {
06223                         TypeDict d;
06224                         return d;
06225                 }
06226 
06227                 static const string NAME;
06228         };
06229 
06237         class TestImageSphericalWave : public TestImageProcessor
06238         {
06239         public:
06240                 virtual void process_inplace(EMData * image);
06241 
06242                 virtual string get_name() const
06243                 {
06244                         return NAME;
06245                 }
06246 
06247                 virtual string get_desc() const
06248                 {
06249                         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)";
06250                 }
06251 
06252                 static Processor * NEW()
06253                 {
06254                         return new TestImageSphericalWave();
06255                 }
06256 
06257                 virtual TypeDict get_param_types() const
06258                 {
06259                         TypeDict d;
06260                         d.put("wavelength", EMObject::FLOAT, "cos(2*pi*r/wavelength+phase)");
06261                         d.put("phase", EMObject::FLOAT, "in radians");
06262                         d.put("x", EMObject::FLOAT, "center of the spherical wave");
06263                         d.put("y", EMObject::FLOAT, "center of the spherical wave");
06264                         d.put("z", EMObject::FLOAT, "center of the spherical wave");
06265                         return d;
06266                 }
06267 
06268                 static const string NAME;
06269         };
06270 
06271 
06280         class TestImageSinewave : public TestImageProcessor
06281         {
06282         public:
06283                 virtual void process_inplace(EMData * image);
06284 
06285                 virtual string get_name() const
06286                 {
06287                         return NAME;
06288                 }
06289 
06290                 virtual string get_desc() const
06291                 {
06292                         return "Replace a source image as a sine wave in specified wave length";
06293                 }
06294 
06295                 static Processor * NEW()
06296                 {
06297                         return new TestImageSinewave();
06298                 }
06299 
06300                 virtual TypeDict get_param_types() const
06301                 {
06302                         TypeDict d;
06303                         d.put("wavelength", EMObject::FLOAT, "wavelength in equation sin(x*2*PI/wavelength - phase*180/PI)");
06304                         d.put("axis", EMObject::STRING, "(optional) specify a major axis for asymmetric features, default x axis");
06305                         d.put("phase", EMObject::FLOAT, "(optional) the phase in radians");
06306                         d.put("az", EMObject::FLOAT, "(optional) angle in degree. for 2D image, this is the rotated angle of the image, \
06307                                                                                                 in 3D image, it's az for euler angle. default is zero");
06308                         d.put("alt", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, alt for euler angle, default is zero");
06309                         d.put("phi", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, phi for euler angle, default is zero");
06310                         return d;
06311                 }
06312 
06313                 static const string NAME;
06314         };
06315 
06322         class TestImageSinewaveCircular : public TestImageProcessor
06323         {
06324         public:
06325                 virtual void process_inplace(EMData * image);
06326 
06327                 virtual string get_name() const
06328                 {
06329                         return NAME;
06330                 }
06331 
06332                 virtual string get_desc() const
06333                 {
06334                         return "Replace a source image as a circular sine wave in specified wave length";
06335                 }
06336 
06337                 static Processor * NEW()
06338                 {
06339                         return new TestImageSinewaveCircular();
06340                 }
06341 
06342                 virtual TypeDict get_param_types() const
06343                 {
06344                         TypeDict d;
06345                         d.put("wavelength", EMObject::FLOAT, "(required)this value is the d in function |sin(x/d)|, unit: pixel");
06346                         d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06347                         d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06348                         d.put("phase", EMObject::FLOAT, "(optional)phase for sine wave, default is 0");
06349                         return d;
06350                 }
06351 
06352                 static const string NAME;
06353         };
06354 
06361         class TestImageSquarecube : public TestImageProcessor
06362         {
06363         public:
06364                 virtual void process_inplace(EMData * image);
06365 
06366                 virtual string get_name() const
06367                 {
06368                         return NAME;
06369                 }
06370 
06371                 virtual string get_desc() const
06372                 {
06373                         return "Replace a source image as a square or cube depends on 2D or 3D of the source image";
06374                 }
06375 
06376                 static Processor * NEW()
06377                 {
06378                         return new TestImageSquarecube();
06379                 }
06380 
06381                 virtual TypeDict get_param_types() const
06382                 {
06383                         TypeDict d;
06384                         d.put("edge_length", EMObject::FLOAT, "edge length of the square or cube, unit: pixel");
06385                         d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06386                         d.put("odd_edge", EMObject::FLOAT, "edge length for the asymmetric axis");
06387                         d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank");
06388                         return d;
06389                 }
06390 
06391                 static const string NAME;
06392         };
06393 
06401         class TestImageEllipse : public TestImageProcessor
06402         {
06403         public:
06404                 virtual void process_inplace(EMData * image);
06405 
06406                 virtual string get_name() const
06407                 {
06408                         return NAME;
06409                 }
06410 
06411                 virtual string get_desc() const
06412                 {
06413                         return "Insert an ellipse into the image.";
06414                 }
06415 
06416                 static Processor * NEW()
06417                 {
06418                         return new TestImageEllipse();
06419                 }
06420 
06421                 virtual TypeDict get_param_types() const
06422                 {
06423                         TypeDict d;
06424                         d.put("a", EMObject::FLOAT, "equatorial radius along x axes (major semiaxes)");
06425                         d.put("b", EMObject::FLOAT, "equatorial radius along y axes (minor semiaxes)");
06426                         d.put("c", EMObject::FLOAT, "polar radius for ellipsoid (x^2/a^2+y^2/b^2+z^2/c^2=1)");
06427                         d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06428                         d.put("fill", EMObject::FLOAT, "value you want to fill in ellipse, default to 1.0");
06429                         return d;
06430                 }
06431 
06432                 static const string NAME;
06433         };
06434 
06446         class TestImageHollowEllipse : public TestImageProcessor
06447                 {
06448                 public:
06449                         virtual void process_inplace(EMData * image);
06450 
06451                         virtual string get_name() const
06452                         {
06453                                 return NAME;
06454                         }
06455 
06456                         virtual string get_desc() const
06457                         {
06458                                 return "Insert a hollow ellipse into the image.";
06459                         }
06460 
06461                         static Processor * NEW()
06462                         {
06463                                 return new TestImageHollowEllipse();
06464                         }
06465 
06466                         virtual TypeDict get_param_types() const
06467                         {
06468                                 TypeDict d;
06469                                 d.put("xwidth", EMObject::FLOAT, "inner equatorial radii along x axes");
06470                                 d.put("ywidth", EMObject::FLOAT, "inner equatorial radii along y axes");
06471                                 d.put("zwidth", EMObject::FLOAT, "inner polar radius");
06472                                 d.put("a", EMObject::FLOAT, "outter equatorial radii along x axes");
06473                                 d.put("b", EMObject::FLOAT, "outter equatorial radii along y axes");
06474                                 d.put("c", EMObject::FLOAT, "outter polar radius");
06475                                 d.put("width",EMObject::FLOAT, "width - specify the width or specify each width explicitly - xwidth, ywidth, zwidth");
06476                                 d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06477                                 d.put("fill", EMObject::FLOAT, "value you want to fill in hollow ellipse, default to 1.0");
06478                                 return d;
06479                         }
06480 
06481                         static const string NAME;
06482                 };
06483 
06490         class TestImageCirclesphere : public TestImageProcessor
06491         {
06492         public:
06493                 virtual void process_inplace(EMData * image);
06494 
06495                 virtual string get_name() const
06496                 {
06497                         return NAME;
06498                 }
06499 
06500                 virtual string get_desc() const
06501                 {
06502                         return "Replace a source image as a circle or sphere depends on 2D or 3D of the source image";
06503                 }
06504 
06505                 static Processor * NEW()
06506                 {
06507                         return new TestImageCirclesphere();
06508                 }
06509 
06510                 virtual TypeDict get_param_types() const
06511                 {
06512                         TypeDict d;
06513                         d.put("radius", EMObject::FLOAT, "radius of circle or sphere, unit: pixel");
06514                         d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06515                         d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06516                         d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank.");
06517                         return d;
06518                 }
06519 
06520                 static const string NAME;
06521         };
06522 
06527         class TestImageNoiseUniformRand : public TestImageProcessor
06528         {
06529         public:
06530                 virtual void process_inplace(EMData * image);
06531 
06532                 virtual string get_name() const
06533                 {
06534                         return NAME;
06535                 }
06536 
06537                 virtual string get_desc() const
06538                 {
06539                         return "Replace a source image as a uniform random noise, random number generated from gsl_rng_mt19937, the pixel value is [0, 1)";
06540                 }
06541 
06542                 static Processor * NEW()
06543                 {
06544                         return new TestImageNoiseUniformRand();
06545                 }
06546 
06547                 virtual TypeDict get_param_types() const
06548                 {
06549                         TypeDict d;
06550                         d.put("seed", EMObject::INT, "seed for random number generator");
06551                         return d;
06552                 }
06553 
06554                 static const string NAME;
06555         };
06556 
06567         class TestImageNoiseGauss : public TestImageProcessor
06568         {
06569         public:
06570                 virtual void process_inplace(EMData * image);
06571 
06572                 virtual string get_name() const
06573                 {
06574                         return NAME;
06575                 }
06576 
06577                 virtual string get_desc() const
06578                 {
06579                         return "Replace a source image as a random noise, the random value is gaussian distributed";
06580                 }
06581 
06582                 static Processor * NEW()
06583                 {
06584                         return new TestImageNoiseGauss();
06585                 }
06586 
06587                 virtual TypeDict get_param_types() const
06588                 {
06589                         TypeDict d;
06590                         d.put("sigma", EMObject::FLOAT, "sigma value of gausian distributed noise, default is 0.5");
06591                         d.put("mean", EMObject::FLOAT, "mean value of gausian distributed noise, default is zero.");
06592                         d.put("seed", EMObject::INT, "the seed for random number generator, default is not to reseed.");
06593 
06594                         return d;
06595                 }
06596 
06597                 static const string NAME;
06598         };
06599 
06604         class TestImageCylinder : public TestImageProcessor
06605         {
06606         public:
06607                 virtual void process_inplace(EMData * image);
06608 
06609                 virtual string get_name() const
06610                 {
06611                         return NAME;
06612                 }
06613 
06614                 virtual string get_desc() const
06615                 {
06616                         return "Replace a source image as a cylinder";
06617                 }
06618 
06619                 static Processor * NEW()
06620                 {
06621                         return new TestImageCylinder();
06622                 }
06623 
06624                 virtual TypeDict get_param_types() const
06625                 {
06626                         TypeDict d;
06627                         d.put("radius", EMObject::FLOAT, "radius for the cylinder");
06628                         d.put("height", EMObject::FLOAT, "height for the cylinder, by default it's the nz");
06629 
06630                         return d;
06631                 }
06632 
06633                 static const string NAME;
06634         };
06635 
06641         class CCDNormProcessor:public Processor
06642         {
06643           public:
06644                 virtual void process_inplace(EMData * image);
06645 
06646                 virtual string get_name() const
06647                 {
06648                         return NAME;
06649                 }
06650 
06651                 static Processor *NEW()
06652                 {
06653                         return new CCDNormProcessor();
06654                 }
06655 
06656                 virtual         string get_desc() const
06657                 {
06658                         return "normalize the 4 quadrants of a CCD image";
06659                 }
06660 
06661                 virtual TypeDict get_param_types() const
06662                 {
06663                         TypeDict d;
06664                         d.put("width", EMObject::INT, "number of pixels on either side of the seam to sample");
06665                         return d;
06666                 }
06667 
06668                 static const string NAME;
06669         };
06670 
06678         class WaveletProcessor:public Processor
06679         {
06680           public:
06681                 virtual void process_inplace(EMData * image);
06682 
06683                 virtual string get_name() const
06684                 {
06685                         return NAME;
06686                 }
06687 
06688                 static Processor *NEW()
06689                 {
06690                         return new WaveletProcessor();
06691                 }
06692 
06693                 virtual TypeDict get_param_types() const
06694                 {
06695                         TypeDict d;
06696                         d.put("type", EMObject::STRING, "'daub', 'harr' or 'bspl'");
06697                         d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06698                         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)");
06699                         return d;
06700                 }
06701 
06702                 virtual string get_desc() const
06703                 {
06704                         return "Computes the DWT (discrete wavelet transform) of an image in one of 3 possible bases";
06705                 }
06706 
06707                 static const string NAME;
06708         };
06709 
06725         class TomoTiltEdgeMaskProcessor : public Processor
06726         {
06727         public:
06728                 virtual void process_inplace(EMData* image);
06729 
06730                 virtual string get_name() const
06731                 {
06732                         return NAME;
06733                 }
06734 
06735                 static Processor *NEW()
06736                 {
06737                         return new TomoTiltEdgeMaskProcessor();
06738                 }
06739 
06740                 virtual TypeDict get_param_types() const
06741                 {
06742                         TypeDict d;
06743                         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");
06744                         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.");
06745                         d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06746                         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.");
06747                         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)");
06748                         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");
06749                         return d;
06750                 }
06751 
06752                 virtual string get_desc() const
06753                 {
06754                         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.";
06755                 }
06756 
06757                 static const string NAME;
06758 
06759         private:
06760                 class GaussianFunctoid
06761                 {
06762                         public:
06763                                 GaussianFunctoid(const float sigma, const float mean = 0.0) : m_mean(mean), m_sigma_squared(sigma*sigma) {}
06764                                 ~GaussianFunctoid() {}
06765 
06766                                 float operator()(const float distance )
06767                                 {
06768                                         return exp( -(distance-m_mean)*(distance-m_mean)/ (m_sigma_squared ));
06769                                 }
06770                         private:
06771                                 float m_mean, m_sigma_squared;
06772                 };
06773 
06774         };
06775 
06790         class TomoTiltAngleWeightProcessor : public Processor
06791         {
06792                 public:
06793                         virtual void process_inplace(EMData* image);
06794 
06795                         virtual string get_name() const
06796                         {
06797                                 return NAME;
06798                         }
06799 
06800                         static Processor *NEW()
06801                         {
06802                                 return new TomoTiltAngleWeightProcessor();
06803                         }
06804 
06805                         virtual TypeDict get_param_types() const
06806                         {
06807                                 TypeDict d;
06808                                 d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06809                                 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");
06810                                 return d;
06811                         }
06812 
06813                         virtual string get_desc() const
06814                         {
06815                                 return "Weights the image by 1/cos(angle)";
06816                         }
06817 
06818                         static const string NAME;
06819 
06820         };
06821 
06825         class FFTProcessor : public Processor
06826         {
06827           public:
06828                 void process_inplace(EMData * image);
06829 
06830                 string get_name() const
06831                 {
06832                         return NAME;
06833                 }
06834 
06835                 static Processor *NEW()
06836                 {
06837                         return new FFTProcessor();
06838                 }
06839 
06840                 TypeDict get_param_types() const
06841                 {
06842                         TypeDict d;
06843                         d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06844                         return d;
06845                 }
06846 
06847                 string get_desc() const
06848                 {
06849                         return "Computes the DFFT (Discrete Fast Fourier Transform) of an image";
06850                 }
06851 
06852                 static const string NAME;
06853         };
06854 
06859         class RadialProcessor : public Processor
06860         {
06861         public:
06862                 void process_inplace(EMData * image);
06863 
06864                 string get_name() const
06865                 {
06866                         return NAME;
06867                 }
06868 
06869                 static Processor *NEW()
06870                 {
06871                         return new RadialProcessor();
06872                 }
06873 
06874                 TypeDict get_param_types() const
06875                 {
06876                         TypeDict d;
06877                         d.put("table", EMObject::FLOATARRAY, "Radial array of floats, 1 float/pixel");
06878                         return d;
06879                 }
06880 
06881                 string get_desc() const
06882                 {
06883                         return "Multiply a real-space image by a radial function. 1 value / pixel, extending to corner. Missing values -> 0.";
06884                 }
06885 
06886                 static const string NAME;
06887         };
06888 
06895         class HistogramBin : public Processor
06896         {
06897                 public:
06898                         HistogramBin() : default_bins(1024) {}
06899 
06900                         void process_inplace(EMData * image);
06901 
06902                         string get_name() const
06903                         {
06904                                 return NAME;
06905                         }
06906 
06907                         static Processor *NEW()
06908                         {
06909                                 return new HistogramBin();
06910                         }
06911 
06912                         TypeDict get_param_types() const
06913                         {
06914                                 TypeDict d;
06915                                 d.put("nbins", EMObject::INT, "The number of bins the pixel values will be compressed into");
06916                                 d.put("debug", EMObject::BOOL, "Outputs debugging information (number of pixels per bin)");
06917                                 return d;
06918                         }
06919 
06920                         string get_desc() const
06921                         {
06922                                 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";
06923                         }
06924 
06925                         static const string NAME;
06926 
06927                 protected:
06928                         int default_bins;
06929         };
06930 
06931         class ModelHelixProcessor : public Processor
06932         {
06933           protected:
06934                 float radprofile(float r, int type);
06935         };
06936 
06937         class ModelEMCylinderProcessor : public ModelHelixProcessor
06938         {
06939           public:
06940                 void process_inplace(EMData * in);
06941 
06942                 string get_name() const
06943                 {
06944                         return NAME;
06945                 }
06946 
06947                 static Processor *NEW()
06948                 {
06949                         return new ModelEMCylinderProcessor();
06950                 }
06951 
06952                 string get_desc() const
06953                 {
06954                         return "Adds a cylinder with a radial density profile similar to that of an alpha helix.";
06955                 }
06956 
06957                 virtual TypeDict get_param_types() const
06958                 {
06959                         TypeDict d;
06960                         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");
06961                         d.put("length", EMObject::FLOAT, "cylinder length in angstroms, defaults to 3 turns (16.2 Angstroms)");
06962                         d.put("x0", EMObject::INT, "x coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06963                         d.put("y0", EMObject::INT, "y coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06964                         d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06965                         //TODO: Check with Matt Baker about description strings
06966                         return d;
06967                 }
06968 
06969                 static const string NAME;
06970         };
06971 
06972         class ApplyPolynomialProfileToHelix : public ModelHelixProcessor
06973         {
06974         public:
06975                 void process_inplace(EMData * in);
06976 
06977                 string get_name() const
06978                 {
06979                         return NAME;
06980                 }
06981 
06982                 static Processor *NEW()
06983                 {
06984                         return new ApplyPolynomialProfileToHelix();
06985                 }
06986 
06987                 string get_desc() const
06988                 {
06989                         return "Finds the CM of each z-axis slice and applies a polynomial radial profile about it.";
06990                 }
06991                 virtual TypeDict get_param_types() const
06992                 {
06993                         TypeDict d;
06994                         d.put("length", EMObject::FLOAT, "Helix length in angstroms.");
06995                         d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06996                         return d;
06997                 }
06998 
06999                 static const string NAME;
07000         };
07001 
07002         class BinarySkeletonizerProcessor : public Processor
07003         {
07004         public:
07005                 virtual EMData* process(EMData * image);
07006                 virtual void process_inplace(EMData * image);
07007 
07008                 virtual string get_name() const
07009                 {
07010                         return NAME;
07011 //                      return "gorgon.binary_skel";
07012                 }
07013                 static Processor *NEW()
07014                 {
07015                         return new BinarySkeletonizerProcessor();
07016                 }
07017                 string get_desc() const
07018                 {
07019                         return "Creates a skeleton of the 3D image by considering whether density is above or below a threshold value.";
07020                 }
07021                 virtual TypeDict get_param_types() const
07022                 {
07023                         TypeDict d;
07024                         d.put("threshold", EMObject::FLOAT, "Threshold value.");
07025                         d.put("min_curve_width", EMObject::INT, "Minimum curve width.");
07026                         d.put("min_surface_width", EMObject::INT, "Minimum surface width.");
07027                         d.put("mark_surfaces", EMObject::BOOL, "Mark surfaces with a value of 2.0f, whereas curves are 1.0f.");
07028                         return d;
07029                 }
07030                 static const string NAME;
07031         };
07032 
07033         class ConvolutionKernelProcessor : public Processor
07034         {
07035         public:
07036                 virtual EMData* process(const EMData* const image);
07037                 virtual void process_inplace(EMData * image);
07038                 
07039                 virtual string get_name() const
07040                 {
07041                         return NAME;
07042                 }
07043                 static Processor *NEW()
07044                 {
07045                         return new ConvolutionKernelProcessor();
07046                 }
07047                 string get_desc() const
07048                 {
07049                         return "Filters an image with a convolution kernel in real space.";
07050                 }
07051                 virtual TypeDict get_param_types() const
07052                 {
07053                         TypeDict d;
07054                         d.put("kernel", EMObject::FLOATARRAY, "the convolution kernel");
07055                         return d;
07056                 }
07057                 static const string NAME;       
07058         };
07059         
07060         class RotateInFSProcessor : public Processor
07061                 {
07062                 public:
07063                         //virtual EMData* process(const EMData* const image);
07064                         virtual void process_inplace(EMData * image);
07065                         virtual EMData* process(const EMData* const image);
07066 
07067                         virtual string get_name() const
07068                         {
07069                                 return NAME;
07070                         }
07071                         static Processor *NEW()
07072                         {
07073                                 return new RotateInFSProcessor( );
07074                         }
07075                         string get_desc() const
07076                         {
07077                                 return "Rotates a Fourier object using a kernel.";
07078                         }
07079                         virtual TypeDict get_param_types() const
07080                         {
07081                                 TypeDict d;     
07082                                 d.put("transform", EMObject::TRANSFORM, "transform");
07083                                 d.put("interpCutoff", EMObject::FLOAT, "cutoff for interpolation");
07084 //                              d.put("offset", EMObject::FLOAT, "offset for FT centering");
07085 //                              d.put("angle", EMObject::FLOAT, "angle");
07086                                 return d;
07087                         }
07088                         static const string NAME;
07089                 };
07090         
07091 #ifdef SPARX_USING_CUDA
07092         /* class MPI CUDA kmeans processor
07093          * 2009-02-13 17:34:45 JB first version
07094          * 2009-09-02 11:19:10 JB for MPI version
07095          * python wrap for GPU cluster
07096          */
07097         class MPICUDA_kmeans {
07098         public:
07099                 MPICUDA_kmeans();
07100                 ~MPICUDA_kmeans();
07101                 int setup(int extm, int extN, int extn, int extK, int extn_start);
07102                 void append_flat_image(EMData* im, int pos);
07103                 int init_mem(int numdev);
07104                 void compute_im2();
07105                 int random_ASG(long int rnd);
07106                 vector<int> get_ASG();
07107                 vector<int> get_asg();
07108                 void compute_NC();
07109                 vector<int> get_NC();
07110                 void set_ASG(const vector <int>& ASG);
07111                 void set_NC(const vector <int>& NC);
07112                 int get_ct_im_mv();
07113                 void set_T(float extT);
07114                 float get_T();
07115                 void compute_AVE();
07116                 void set_AVE(EMData* im, int pos);
07117                 vector<EMData*> get_AVE();
07118                 int one_iter();
07119                 //int one_iter_SSE();
07120                 //int AVE_to_host();
07121                 int one_iter_SA();
07122                 vector<float> compute_ji();
07123                 vector<float> compute_criterion(const vector <float>& Ji);
07124                 int shutdown();
07125         private:
07126                 // params
07127                 int m;
07128                 int N;
07129                 int n;
07130                 int K;
07131                 int nb_part;
07132                 int n_start;
07133                 int size_im;
07134                 int size_IM;
07135                 int size_AVE;
07136                 int size_dist;
07137                 int BLOCK_SIZE;
07138                 int NB;
07139                 int ins_BLOCK;
07140                 int ite;
07141                 float T;
07142                 // debug
07143                 int ct_im_mv;
07144                 // host memory
07145                 float* h_IM;
07146                 float* h_im;
07147                 float* h_AVE;
07148                 float* h_dist;
07149                 float* h_AVE2;
07150                 float* h_im2;
07151                 unsigned short int* h_ASG;
07152                 unsigned short int* h_asg;
07153                 unsigned int* h_NC;
07154                 int* params;
07155                 float ttt;
07156                 // device memory
07157                 float* d_im;
07158                 float* d_AVE;
07159                 float* d_dist;
07160                 //int init_dist(); // intial h_dist and d_dist for SSE
07161                 float compute_tt();
07162         };
07163 
07164 #endif //EMAN2_USING_CUDA
07165 
07166 #if 0
07167 
07168         class XYZProcessor:public Processor
07169         {
07170           public:
07171                 void process_inplace(EMData * image);
07172 
07173                 string get_name() const
07174                 {
07175                         return NAME;
07176                 }
07177 
07178                 static Processor *NEW()
07179                 {
07180                         return new XYZProcessor();
07181                 }
07182 
07183                 string get_desc() const
07184                 {
07185                         return "N/A";
07186                 }
07187 
07188                 TypeDict get_param_types() const
07189                 {
07190                         TypeDict d;
07191                         return d;
07192                 }
07193 
07194                 static const string NAME;
07195         };
07196 
07197 
07198 #endif
07199 
07200 
07201 #if 0
07202 
07203         class XYZProcessor:public Processor
07204         {
07205           public:
07206                 void process_inplace(EMData * image);
07207 
07208                 string get_name() const
07209                 {
07210                         return NAME;
07211                 }
07212 
07213                 static Processor *NEW()
07214                 {
07215                         return new XYZProcessor();
07216                 }
07217 
07218                 string get_desc() const
07219                 {
07220                         return "N/A";
07221                 }
07222 
07223                 TypeDict get_param_types() const
07224                 {
07225                         TypeDict d;
07226                         return d;
07227                 }
07228 
07229                 static const string NAME;
07230         };
07231 
07232 
07233 #endif
07234 
07235 
07236         int multi_processors(EMData * image, vector < string > processornames);
07237         void dump_processors();
07238         map<string, vector<string> > dump_processors_list();
07239         map<string, vector<string> > group_processors();
07240 
07241         template <> Factory < Processor >::Factory();
07242 }
07243 
07244 #endif  //eman_filter_h__
07245 
07246 /* vim: set ts=4 noet: */
07247 

Generated on Thu May 3 10:06:27 2012 for EMAN2 by  doxygen 1.4.7