processor.h

Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
00007  * Copyright (c) 2000-2006 Baylor College of Medicine
00008  *
00009  * This software is issued under a joint BSD/GNU license. You may use the
00010  * source code in this file under either license. However, note that the
00011  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00012  * so you are responsible for compliance with the licenses of these packages
00013  * if you opt to use BSD licensing. The warranty disclaimer below holds
00014  * in either instance.
00015  *
00016  * This complete copyright notice must be included in any revised version of the
00017  * source code. Additional authorship citations may be added, but existing
00018  * author citations must be preserved.
00019  *
00020  * This program is free software; you can redistribute it and/or modify
00021  * it under the terms of the GNU General Public License as published by.edge
00022  * the Free Software Foundation; either version 2 of the License, or
00023  * (at your option) any later version.
00024  *
00025  * This program is distributed in the hope that it will be useful,
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00028  * GNU General Public License for more details.
00029  *
00030  * You should have received a copy of the GNU General Public License
00031  * along with this program; if not, write to the Free Software
00032  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00033  *
00034  * */
00035 
00036 #ifndef eman_processor_h__
00037 #define eman_processor_h__ 1
00038 
00039 #include "emobject.h"
00040 #include "util.h"
00041 #include "geometry.h"
00042 #include "transform.h"
00043 #include "emdata.h"
00044 #include "gorgon/skeletonizer.h"
00045 
00046 #include <cfloat>
00047 #include <climits>
00048 #include <cstring>
00049 
00050 using std::vector;
00051 using std::map;
00052 using std::string;
00053 
00054 namespace EMAN
00055 {
00056         class EMData;
00057 
00093         class Processor
00094         {
00095           public:
00096                 virtual ~ Processor()
00097                 {
00098                 }
00099 
00105                 virtual void process_inplace(EMData *image) = 0;
00106 
00113                 virtual EMData* process(const EMData * const image);
00114 
00118                 virtual void process_list_inplace(vector < EMData * > & images)
00119                 {
00120                         for (size_t i = 0; i < images.size(); i++) {
00121                                 process_inplace(images[i]);
00122                         }
00123                 }
00124 
00128                 virtual string get_name() const = 0;
00129 
00133                 virtual Dict get_params() const
00134                 {
00135                         return params;
00136                 }
00137 
00141                 virtual void set_params(const Dict & new_params)
00142                 {
00143                         params = new_params;
00144                 }
00145 
00152                 virtual TypeDict get_param_types() const
00153                 {
00154                         return TypeDict();
00155                 }
00156 
00163                 static string get_group_desc()
00164                 {
00165                         return "EMAN processors are in-place image processors. You may apply a processor to process a single image or process multiple images. Processor class is the base class for all processor. <br> \
00166 The basic design of EMAN Processors: <br>\
00167     1) Each Processor class defines an image-processinging algorithm. <br>\
00168     2) All the Processor classes in EMAN are managed by a Factory pattern. So each Processor class must define: <br> a) a unique name to idenfity itself in the factory. <br>b) a static method to register itself in the factory.<br>\
00169     3) Each Processor class defines its own parameter set.<br>\
00170     4) Each Processor class defines functions to return its documentation including parameter information, and processor description. These functions enable EMAN to generate processor manuals dynamically.";
00171                 }
00172 
00178                 virtual string get_desc() const = 0;
00179 
00186                 enum fourier_filter_types {
00187                         TOP_HAT_LOW_PASS,
00188                         TOP_HAT_HIGH_PASS,
00189                         TOP_HAT_BAND_PASS,
00190                         TOP_HOMOMORPHIC,
00191                         GAUSS_LOW_PASS,
00192                         GAUSS_HIGH_PASS,
00193                         GAUSS_BAND_PASS,
00194                         GAUSS_INVERSE,
00195                         GAUSS_HOMOMORPHIC,
00196                         BUTTERWORTH_LOW_PASS,
00197                         BUTTERWORTH_HIGH_PASS,
00198                         BUTTERWORTH_HOMOMORPHIC,
00199                         KAISER_I0,
00200                         KAISER_SINH,
00201                         KAISER_I0_INVERSE,
00202                         KAISER_SINH_INVERSE,
00203                         SHIFT,
00204                         TANH_LOW_PASS,
00205                         TANH_HIGH_PASS,
00206                         TANH_HOMOMORPHIC,
00207                         TANH_BAND_PASS,
00208                         RADIAL_TABLE,
00209                         CTF_,
00210                 };
00211 
00236                 static void
00237                 EMFourierFilterInPlace(EMData* fimage, Dict params) {
00238                         bool doInPlace = true;
00239                         EMFourierFilterFunc(fimage, params, doInPlace);
00240                 }
00241 
00267                 static EMData*
00268                 EMFourierFilter(EMData* fimage, Dict params) {
00269                         bool doInPlace = false;
00270                         return EMFourierFilterFunc(fimage, params, doInPlace);
00271                 }
00272 
00273           private:
00309                 static EMData*
00310                 EMFourierFilterFunc(EMData* fimage, Dict params, bool doInPlace=true);
00311 
00312           protected:
00313                 mutable Dict params;
00314         };
00315 
00316         class ImageProcessor:public Processor
00317         {
00318           public:
00319                 void process_inplace(EMData * image);
00320 
00321                 static string get_group_desc()
00322                 {
00323                         return "An Image Processor defines a way to create a processor image. The processor image is used to multiply the input-image in the fourier space. ImageFilter class is the base class. Each specific ImageFilter class must define function create_processor_image(). ";
00324                 }
00325 
00326           protected:
00327                 virtual EMData * create_processor_image() const = 0;
00328         };
00329 
00336         class FourierProcessor:public Processor
00337         {
00338           public:
00339                 void process_inplace(EMData * image);
00340 
00341                 static string get_group_desc()
00342                 {
00343                         return "Fourier Filter processors are a group of processor in the frequency domain. Before using such processors on an image, the image must be transformed from real space to the fourier space. FourierProcessor class is the base class of fourier space processors. Each specific processor is either a lowpass filter processor, or a highpass filter processor, or neighter. The unit of lowpass and highpass parameters are in terms of Nyquist, valid range is [0,0.5]. ";
00344                 }
00345 
00346                 TypeDict get_param_types() const
00347                 {
00348                         TypeDict d;
00349                         d.put("cutoff_abs", EMObject::FLOAT, "Processor radius in terms of Nyquist (0-.5)");
00350                         d.put("cutoff_pixels", EMObject::FLOAT, " Width in Fourier pixels (0 - size()/2)");
00351                         d.put("cutoff_freq", EMObject::FLOAT, "1/Resolution in 1/A (0 - 1 / 2*apix). eg - a 20 A filter is cutoff_freq=0.05");
00352                         d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
00353                         return d;
00354                 }
00355 
00356           protected:
00357                   virtual void preprocess(EMData *image) {
00358                         if(params.has_key("apix")) {
00359                                 image->set_attr("apix_x", (float)params["apix"]);
00360                                 image->set_attr("apix_y", (float)params["apix"]);
00361                                 image->set_attr("apix_z", (float)params["apix"]);
00362                         }
00363 
00364                         const Dict dict = image->get_attr_dict();
00365                         if( params.has_key("sigma")) {
00366                                 params["cutoff_abs"] = (float)params["sigma"];
00367                         }
00368                         else if( params.has_key("cutoff_abs") ) {
00369                                 params["sigma"] = (float)params["cutoff_abs"];
00370                         }
00371                         else if( params.has_key("cutoff_freq") ) {
00372                                 float val =  (float)params["cutoff_freq"] * (float)dict["apix_x"];
00373                                 params["cutoff_abs"] = val;
00374                                 params["sigma"] = val;
00375                         }
00376                         else if( params.has_key("cutoff_pixels") ) {
00377                                 float val = (0.5f*(float)params["cutoff_pixels"] / (float)dict["nx"]);
00378                                 params["cutoff_abs"] = val;
00379                                 params["sigma"] = val;
00380                         }
00381 
00382                         }
00383                   virtual void create_radial_func(vector < float >&radial_mask) const = 0;
00384         };
00385 
00393         class FourierAnlProcessor:public Processor
00394         {
00395           public:
00396                 void process_inplace(EMData * image);
00397 
00398                 static string get_group_desc()
00399                 {
00400                         return "Fourier Filter processors are a group of processor in the frequency domain. Before using such processors on an image, the image must be transformed from real space to the fourier space. FourierProcessor class is the base class of fourier space processors. Each specific processor is either a lowpass filter processor, or a highpass filter processor, or neighter. The unit of lowpass and highpass parameters are in terms of Nyquist, valid range is [0,0.5]. ";
00401                 }
00402 
00403                 TypeDict get_param_types() const
00404                 {
00405                         TypeDict d;
00406                         d.put("cutoff_abs", EMObject::FLOAT, "Processor radius in terms of Nyquist (0-.5)");
00407                         d.put("cutoff_pixels", EMObject::FLOAT, " Width in Fourier pixels (0 - size()/2)");
00408                         d.put("cutoff_freq", EMObject::FLOAT, "1/Resolution in 1/A (0 - 1 / 2*apix). eg - a 20 A filter is cutoff_freq=0.05");
00409                         d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
00410                         return d;
00411                 }
00412 
00413           protected:
00414                   virtual void preprocess(EMData *) {}
00415                   virtual void create_radial_func(vector < float >&radial_mask,EMData *image) const = 0;
00416         };
00417 
00420         class SNREvalProcessor:public Processor
00421         {
00422                 public:
00423                 string get_name() const
00424                 {
00425                         return NAME;
00426                 }
00427 
00428                 void process_inplace(EMData * image);
00429 
00430                 void set_params(const Dict & new_params)
00431                 {
00432                         params = new_params;
00433 //                      sum = params["sum"];
00434 //                      dosqrt = params["sqrt"];
00435 //                      printf("%s %f\n",params.keys()[0].c_str(),lowpass);
00436                 }
00437 
00438                 TypeDict get_param_types() const
00439                 {
00440                         TypeDict d;
00441 //                      d.put("sum", EMObject::EMDATA, "Adds the weights to sum for normalization");
00442 //                      d.put("sqrt", EMObject::INT, "Weights using sqrt of the amplitude if set");
00443                         return d;
00444                 }
00445 
00446                 static Processor *NEW()
00447                 {
00448                         return new SNREvalProcessor();
00449                 }
00450 
00451                 string get_desc() const
00452                 {
00453                         return "Evaluates the SNR of the particle using a masking method similar to that used in the CTF analysis process. The image is not changed. The resulting value is placed in the particle dictionary as eval_maskedsnr";
00454                 }
00455                 
00456                 static const string NAME;
00457 
00458                 protected:
00459                 EMData *sum;
00460                 int dosqrt;
00461         };
00462 
00463 
00468         class AmpweightFourierProcessor:public Processor
00469         {
00470           public:
00471                 string get_name() const
00472                 {
00473                         return NAME;
00474                 }
00475 
00476                 void process_inplace(EMData * image);
00477 
00478                 void set_params(const Dict & new_params)
00479                 {
00480                         params = new_params;
00481                         sum = params["sum"];
00482                         dosqrt = params["sqrt"];
00483 //                      printf("%s %f\n",params.keys()[0].c_str(),lowpass);
00484                 }
00485 
00486                 TypeDict get_param_types() const
00487                 {
00488                         TypeDict d;
00489                         d.put("sum", EMObject::EMDATA, "Adds the weights to sum for normalization");
00490                         d.put("sqrt", EMObject::INT, "Weights using sqrt of the amplitude if set");
00491                         return d;
00492                 }
00493 
00494                 static Processor *NEW()
00495                 {
00496                         return new AmpweightFourierProcessor();
00497                 }
00498 
00499                 string get_desc() const
00500                 {
00501                         return "Multiplies each Fourier pixel by its amplitude";
00502                 }
00503 
00504                 static const string NAME;
00505 
00506                 protected:
00507                 EMData *sum;
00508                 int dosqrt;
00509         };
00516         class ConvolutionProcessor : public Processor
00517         {
00518                 public:
00519                         ConvolutionProcessor() {}
00520 
00521                         string get_name() const
00522                         {
00523                                 return NAME;
00524                         }
00525 
00526                         void process_inplace(EMData *image);
00527 
00528                         static Processor *NEW()
00529                         {
00530                                 return new ConvolutionProcessor();
00531                         }
00532 
00533                         string get_desc() const
00534                         {
00535                                 return "Performs Fourier space convolution. Maintains the space that the image is in - i.e. if image is real, the result is real and vice versa.";
00536                         }
00537 
00538                         TypeDict get_param_types() const
00539                         {
00540                                 TypeDict d;
00541                                 d.put("with", EMObject::EMDATA, "The image that will convolute the other image");
00542                                 return d;
00543                         }
00544 
00545                         static const string NAME;
00546         };
00547 
00554         class XGradientProcessor : public Processor
00555         {
00556          public:
00557                 XGradientProcessor() {}
00558 
00559                 string get_name() const
00560                 {
00561                         return NAME;
00562                 }
00563 
00564                 void process_inplace(EMData *image);
00565 
00566                 static Processor *NEW()
00567                 {
00568                         return new XGradientProcessor();
00569                 }
00570 
00571                 string get_desc() const
00572                 {
00573                         return "Determines the image gradient in the x direction";
00574                 }
00575 
00576                 TypeDict get_param_types() const
00577                 {
00578                         TypeDict d;
00579                         return d;
00580                 }
00581 
00582                 static const string NAME;
00583         };
00584 
00585         class YGradientProcessor : public Processor
00586         {
00587                 public:
00588                         YGradientProcessor() {}
00589 
00590                         string get_name() const
00591                         {
00592                                 return NAME;
00593                         }
00594 
00595                         void process_inplace(EMData *image);
00596 
00597                         static Processor *NEW()
00598                         {
00599                                 return new YGradientProcessor();
00600                         }
00601 
00602                         string get_desc() const
00603                         {
00604                                 return "Determines the image gradient in the y direction";
00605                         }
00606 
00607 
00608                         TypeDict get_param_types() const
00609                         {
00610                                 TypeDict d;
00611                                 return d;
00612                         }
00613 
00614                         static const string NAME;
00615         };
00616 
00617         class ZGradientProcessor : public Processor
00618         {
00619                 public:
00620                         ZGradientProcessor() {}
00621 
00622                         string get_name() const
00623                         {
00624                                 return NAME;
00625                         }
00626 
00627                         void process_inplace(EMData *image);
00628 
00629                         static Processor *NEW()
00630                         {
00631                                 return new ZGradientProcessor();
00632                         }
00633 
00634                         string get_desc() const
00635                         {
00636                                 return "Determines the image gradient in the z direction";
00637                         }
00638 
00639                         TypeDict get_param_types() const
00640                         {
00641                                 TypeDict d;
00642                                 return d;
00643                         }
00644 
00645                         static const string NAME;
00646         };
00647 
00656         class Wiener2DAutoAreaProcessor:public Processor
00657         {
00658           public:
00659                 string get_name() const
00660                 {
00661                         return NAME;
00662                 }
00663 
00664                 virtual EMData* process(const EMData * const image);
00665 
00666                 void process_inplace(EMData *image);
00667 
00668                 void set_params(const Dict & new_params)
00669                 {
00670                         params = new_params;
00671                         bgsize = params["size"];
00672 //                      printf("%s %f\n",params.keys()[0].c_str(),lowpass);
00673                 }
00674 
00675                 TypeDict get_param_types() const
00676                 {
00677                         TypeDict d;
00678                         d.put("size", EMObject::INT, "Size in pixels of the boxes to chop the image into");
00679                         return d;
00680                 }
00681 
00682                 static Processor *NEW()
00683                 {
00684                         return new Wiener2DAutoAreaProcessor();
00685                 }
00686 
00687                 string get_desc() const
00688                 {
00689                         return "Automatically detrmines the background for the image then uses this to perform Wiener filters on overlapping subregions of the image, which are then combined using linear interpolation";
00690                 }
00691 
00692                 static const string NAME;
00693 
00694                 protected:
00695                 int bgsize;
00696         };
00697 
00704         class DistanceSegmentProcessor:public Processor
00705         {
00706           public:
00707                 string get_name() const
00708                 {
00709                         return NAME;
00710                 }
00711 
00712                 virtual EMData* process(const EMData * const image);
00713                 void process_inplace( EMData * image);
00714 
00715                 TypeDict get_param_types() const
00716                 {
00717                         TypeDict d ;
00718                         d.put("thr",EMObject::FLOAT,"Optional : Isosurface threshold value. Pixels below this will not be segment centers (default = 0.9)");
00719                         d.put("minsegsep",EMObject::FLOAT,"Required: Minimum segment separation in pixels. Segments too close will trigger a reseed");
00720                         d.put("maxsegsep",EMObject::FLOAT,"Required: Maximum segment separation in pixels. Segments too close will trigger a reseed");
00721                         d.put("verbose",EMObject::INT,"Be verbose while running");
00722                         return d;
00723                 }
00724 
00725                 static Processor *NEW()
00726                 {
00727                         return new DistanceSegmentProcessor();
00728                 }
00729 
00730                 string get_desc() const
00731                 {
00732                         return "Segments a volume into pieces separated by distances in the specified range.";
00733                 }
00734 
00735                 static const string NAME;
00736 
00737         };
00738 
00745         class KmeansSegmentProcessor:public Processor
00746         {
00747           public:
00748                 string get_name() const
00749                 {
00750                         return NAME;
00751                 }
00752 
00753                 virtual EMData* process(const EMData * const image);
00754                 void process_inplace( EMData * image);
00755 
00756                 TypeDict get_param_types() const
00757                 {
00758                         TypeDict d ;
00759                         d.put("nseg", EMObject::INT, "Number of segments to divide the image into. default=12" );
00760                         d.put("thr",EMObject::FLOAT,"Isosurface threshold value. Pixels below this will not be segmented");
00761                         d.put("ampweight",EMObject::INT,"If set, will weight centers by voxel amplitude. default = 1");
00762                         d.put("maxsegsize",EMObject::FLOAT,"Maximum radial distance from segment center to member voxel. Default=10000");
00763                         d.put("minsegsep",EMObject::FLOAT,"Minimum segment separation. Segments too close will trigger a reseed");
00764                         d.put("maxiter",EMObject::FLOAT,"Maximum number of iterations to run before stopping. Default=100");
00765                         d.put("maxvoxmove",EMObject::FLOAT,"Maximum number of voxels that can move before quitting. Default=25");
00766                         d.put("verbose",EMObject::INT,"Be verbose while running");
00767                         return d;
00768                 }
00769 
00770                 static Processor *NEW()
00771                 {
00772                         return new KmeansSegmentProcessor();
00773                 }
00774 
00775                 string get_desc() const
00776                 {
00777                         return "Performs K-means segmentation on a volume. Note that this method uses random seeds, and thus will return different results each time it is run. Returned map contains number of segment for each voxel (or 0 for unsegmented voxels). Segmentation centers are stored in 'segmentcenters' attribute, consisting of a list of 3n floats in x,y,z triples.";
00778                 }
00779 
00780                 static const string NAME;
00781 
00782         };
00783 
00797         class CtfSimProcessor:public Processor
00798         {
00799           public:
00800                 string get_name() const                 
00801                 {
00802                         return NAME;
00803                 }
00804 
00805                 virtual EMData* process(const EMData * const image);
00806 
00807                 void process_inplace(EMData *image);
00808 
00809                 TypeDict get_param_types() const
00810                 {
00811                         TypeDict d;
00812                         d.put("defocus", EMObject::FLOAT, "Defocus in microns (underfocus positive)");
00813                         d.put("ampcont", EMObject::FLOAT, "% amplitude contrast (0-100)");
00814                         d.put("bfactor", EMObject::FLOAT, "B-factor in A^2, uses MRC convention rather than EMAN1 convention");
00815                         d.put("noiseamp", EMObject::FLOAT, "Amplitude of the added empirical pink noise");
00816                         d.put("noiseampwhite", EMObject::FLOAT, "Amplitude of added white noise");
00817                         d.put("voltage", EMObject::FLOAT, "Microscope voltage in KV");
00818                         d.put("cs", EMObject::FLOAT, "Cs of microscope in mm");
00819                         d.put("apix", EMObject::FLOAT, "A/pix of data");
00820                         return d;
00821                 }
00822 
00823                 static Processor *NEW()
00824                 {
00825                         return new CtfSimProcessor();
00826                 }
00827 
00828                 string get_desc() const
00829                 {
00830                         return "Applies a simulated CTF with noise to an image. The added noise is either white or based on an empirical curve generated from cryoEM data. ";
00831                 }
00832 
00833                 static const string NAME;
00834 
00835 //              protected:
00836         };
00837 
00838 
00845         class Wiener2DFourierProcessor:public Processor
00846         {
00847           public:
00848                 string get_name() const                 
00849                 {
00850                         return NAME;
00851                 }
00852 
00853                 virtual EMData* process(const EMData * const image);
00854 
00855                 void process_inplace(EMData *image);
00856 
00857                 void set_params(const Dict & new_params)
00858                 {
00859                         params = new_params;
00860                         ctf = params["ctf"];
00861 //                      printf("%s %f\n",params.keys()[0].c_str(),lowpass);
00862                 }
00863 
00864                 TypeDict get_param_types() const
00865                 {
00866                         TypeDict d;
00867                         d.put("ctf", EMObject::EMDATA, "Ctf object to use for Wiener filter parameters");
00868                         return d;
00869                 }
00870 
00871                 static Processor *NEW()
00872                 {
00873                         return new Wiener2DFourierProcessor();
00874                 }
00875 
00876                 string get_desc() const
00877                 {
00878                         return "Applies a 2-D Wiener filter to an image based on its Ctf parameters";
00879                 }
00880 
00881                 static const string NAME;
00882 
00883                 protected:
00884                 Ctf *ctf;
00885         };
00886 
00887         class LinearRampFourierProcessor:public FourierProcessor
00888         {
00889                 public:
00890                         virtual string get_name() const
00891                         {
00892                                 return NAME;
00893                         }
00894 
00895                         virtual string get_desc() const
00896                         {
00897                                 return "";
00898                         }
00899 
00900                         static Processor *NEW()
00901                         {
00902                                 return new LinearRampFourierProcessor();
00903                         }
00904 
00905                         static const string NAME;
00906 
00907                 protected:
00908                         virtual void create_radial_func(vector < float >&radial_mask) const ;
00909         };
00910 
00911 
00914         class LowpassRandomPhaseProcessor:public FourierProcessor
00915         {
00916           public:
00917                 string get_name() const
00918                 { return NAME; }
00919                 static Processor *NEW() { return new LowpassRandomPhaseProcessor(); }
00920                 string get_desc() const
00921                 {
00922                         return "Above the cutoff frequency, phases will be completely randomized, but amplitudes will be unchanged. Used for testing for noise bias. If you can reconstruct information that isn't there, then you have noise bias problems.";
00923                 }
00924                                 void process_inplace(EMData * image);
00925                                 void create_radial_func(vector < float >&radial_mask) const;
00926 
00927                 static const string NAME;
00928         };
00929 
00930 
00933         class LowpassAutoBProcessor:public FourierAnlProcessor
00934         {
00935           public:
00936                 string get_name() const
00937                 {
00938                         return NAME;
00939                 }
00940 
00941                 static Processor *NEW()
00942                 {
00943                         return new LowpassAutoBProcessor();
00944                 }
00945 
00946                 string get_desc() const
00947                 {
00948                         return "This processor sharpens a map based on the concept that the power spectrum should be roughly flat over the ~15 A-Nyquist resolution range, then combines this inverse B-factor with the specified low-pass Gaussian filter parameters to produce a single aggregate Gaussian filter.";
00949                 }
00950 
00951                 static const string NAME;
00952 
00953                 virtual TypeDict get_param_types() const
00954                 {
00955                         TypeDict d = FourierAnlProcessor::get_param_types();
00956                         d.put("bfactor", EMObject::FLOAT, "B-factor in terms of e^-(B s^2/4)");
00957                         d.put("noisecutoff", EMObject::FLOAT, "Spatial frequency past which inverse-B will not be applied");
00958 //                      d.put("adaptnoise", EMObject::INT, "Dual linear fit separating lower resolution signal from higher resolution noise. Noise region not upweighted.");
00959                         d.put("verbose", EMObject::INT, "Print information about the determined B-factor");
00960                         return d;
00961                 }
00962 
00963           protected:
00964                 virtual void preprocess(EMData * image) {
00965                         if(params.has_key("apix")) {
00966                                 image->set_attr("apix_x", (float)params["apix"]);
00967                                 image->set_attr("apix_y", (float)params["apix"]);
00968                                 image->set_attr("apix_z", (float)params["apix"]);
00969                         }
00970                         float apix=(float)image->get_attr("apix_x");
00971 
00972                         const Dict dict = image->get_attr_dict();
00973                         if (params.has_key("cutoff_abs")) {
00974                                 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00975                         }
00976                         else if( params.has_key("cutoff_freq") ) {
00977                                 float val =  (float)params["cutoff_freq"] * apix;
00978                                 params["cutoff_abs"] = val;
00979                                 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00980                         }
00981                         else if( params.has_key("cutoff_pixels") ) {
00982                                 float val = 0.5f*(float)params["cutoff_pixels"] / (float)dict["nx"];
00983                                 params["cutoff_abs"] = val;
00984                                 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00985                         }
00986                 }
00987 
00988                 void create_radial_func(vector < float >&radial_mask,EMData *image) const;
00989         };
00990 
00993         class HighpassAutoPeakProcessor:public FourierAnlProcessor
00994         {
00995           public:
00996                 string get_name() const
00997                 {
00998                         return NAME;
00999                 }
01000                 static Processor *NEW()
01001                 {
01002                         return new HighpassAutoPeakProcessor();
01003                 }
01004 
01005                 string get_desc() const
01006                 {
01007                         return "Attempts to automatically remove the low resolution peak present in virtually all cryoEM data.";
01008                 }
01009 
01010                 static const string NAME;
01011 
01012           protected:
01013                 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
01014                   virtual void preprocess(EMData * image);
01015                   float highpass;
01016         };
01017 
01022         class LinearRampProcessor:public FourierProcessor
01023         {
01024           public:
01025                 LinearRampProcessor():intercept(0), slope(0)
01026                 {
01027                 }
01028 
01029                 string get_name() const
01030                 {
01031                         return NAME;
01032                 }
01033                 static Processor *NEW()
01034                 {
01035                         return new LinearRampProcessor();
01036                 }
01037 
01038                 string get_desc() const
01039                 {
01040                         return "processor radial function: f(x) = slope * x + intercept;";
01041                 }
01042 
01043                 void set_params(const Dict & new_params)
01044                 {
01045                         params = new_params;
01046                         intercept = params["intercept"];
01047                         slope = params["slope"];
01048                 }
01049 
01050                 TypeDict get_param_types() const
01051                 {
01052                         TypeDict d;
01053                         d.put("intercept", EMObject::FLOAT, "intercept in 'f(x) = slope * x + intercept'");
01054                         d.put("slope", EMObject::FLOAT, "slope in 'f(x) = slope * x + intercept'");
01055                         return d;
01056                 }
01057 
01058                 static const string NAME;
01059 
01060           protected:
01061                 void create_radial_func(vector < float >&radial_mask) const;
01062 
01063           private:
01064                 float intercept;
01065                 float slope;
01066         };
01067 
01071         class LoGFourierProcessor:public FourierProcessor
01072         {
01073           public:
01074                 LoGFourierProcessor():sigma(0)
01075                 {
01076                 }
01077 
01078                 string get_name() const
01079                 {
01080                         return NAME;
01081                 }
01082                 static Processor *NEW()
01083                 {
01084                         return new LoGFourierProcessor();
01085                 }
01086 
01087                 string get_desc() const
01088                 {
01089                         return "processor radial function: f(x) = ((x^2 - s^2)/s^4)e^-(x^2/2s^2)";
01090                 }
01091 
01092                 void set_params(const Dict & new_params)
01093                 {
01094                         params = new_params;
01095                         sigma = params["sigma"];
01096                 }
01097 
01098                 TypeDict get_param_types() const
01099                 {
01100                         TypeDict d;
01101                         d.put("sigma", EMObject::FLOAT, "LoG sigma");
01102                         return d;
01103                 }
01104 
01105                 static const string NAME;
01106 
01107           protected:
01108                 void create_radial_func(vector < float >&radial_mask) const;
01109 
01110           private:
01111                 float sigma;
01112         };
01113         
01118         class DoGFourierProcessor:public FourierProcessor
01119         {
01120           public:
01121                 DoGFourierProcessor():sigma1(0), sigma2(0)
01122                 {
01123                 }
01124 
01125                 string get_name() const
01126                 {
01127                         return NAME;
01128                 }
01129                 static Processor *NEW()
01130                 {
01131                         return new DoGFourierProcessor();
01132                 }
01133 
01134                 string get_desc() const
01135                 {
01136                         return "processor radial function: f(x) = 1/sqrt(2*pi)*[1/sigma1*exp-(x^2/2*sigma1^2) - 1/sigma2*exp-(x^2/2*sigma2^2)]";
01137                 }
01138 
01139                 void set_params(const Dict & new_params)
01140                 {
01141                         params = new_params;
01142                         sigma1 = params["sigma1"];
01143                         sigma2 = params["sigma2"];
01144                 }
01145 
01146                 TypeDict get_param_types() const
01147                 {
01148                         TypeDict d;
01149                         d.put("sigma1", EMObject::FLOAT, "DoG sigma1");
01150                         d.put("sigma2", EMObject::FLOAT, "DoG sigma2");
01151                         return d;
01152                 }
01153 
01154                 static const string NAME;
01155 
01156           protected:
01157                 void create_radial_func(vector < float >&radial_mask) const;
01158 
01159           private:
01160                 float sigma1;
01161                 float sigma2;
01162         };
01163         
01166         class RealPixelProcessor:public Processor
01167         {
01168           public:
01169                 RealPixelProcessor():value(0), maxval(1), mean(0), sigma(0)
01170                 {
01171                 }
01172                 void process_inplace(EMData * image);
01173 
01174                 virtual void set_params(const Dict & new_params)
01175                 {
01176                         params = new_params;
01177                         if (params.size() == 1) {
01178                                 vector < EMObject > dict_values = params.values();
01179                                 value = dict_values[0];
01180                         }
01181                 }
01182 
01183                 static string get_group_desc()
01184                 {
01185                         return "The base class for real space processor working on individual pixels. The processor won't consider the pixel's coordinates and neighbors.";
01186                 }
01187 
01188           protected:
01189                 virtual void process_pixel(float *x) const = 0;
01190                 virtual void calc_locals(EMData *)
01191                 {
01192                 }
01193                 virtual void normalize(EMData *) const
01194                 {
01195                 }
01196 
01197                 float value;
01198                 float maxval;
01199                 float mean;
01200                 float sigma;
01201         };
01202 
01205         class AbsoluateValueProcessor:public RealPixelProcessor
01206         {
01207           public:
01208                 string get_name() const
01209                 {
01210                         return NAME;
01211                 }
01212                 static Processor *NEW()
01213                 {
01214                         return new AbsoluateValueProcessor();
01215                 }
01216 
01217                 static const string NAME;
01218 
01219           protected:
01220                 void process_pixel(float *x) const
01221                 {
01222                         *x = fabs(*x);
01223                 }
01224 
01225                 string get_desc() const
01226                 {
01227                         return "f(x) = |x|";
01228                 }
01229         };
01230 
01233         class FloorValueProcessor:public RealPixelProcessor
01234         {
01235           public:
01236                 string get_name() const
01237                 {
01238                         return NAME;
01239                 }
01240                 static Processor *NEW()
01241                 {
01242                         return new FloorValueProcessor();
01243                 }
01244 
01245                 static const string NAME;
01246 
01247           protected:
01248                 void process_pixel(float *x) const
01249                 {
01250                         *x = floor(*x);
01251                 }
01252 
01253                 string get_desc() const
01254                 {
01255                         return "f(x) = floor(x)";
01256                 }
01257         };
01258 
01259 
01262         class BooleanProcessor:public RealPixelProcessor
01263         {
01264           public:
01265                 string get_name() const
01266                 {
01267                         return NAME;
01268                 }
01269                 static Processor *NEW()
01270                 {
01271                         return new BooleanProcessor();
01272                 }
01273 
01274                 string get_desc() const
01275                 {
01276                         return "f(x) = 0 if x = 0; f(x) = 1 if x != 0;";
01277                 }
01278 
01279                 static const string NAME;
01280 
01281           protected:
01282                 void process_pixel(float *x) const
01283                 {
01284                         if (*x != 0)
01285                         {
01286                                 *x = 1.0;
01287                         }
01288                 }
01289         };
01290 
01294         class 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 "This will mask a 3-D volume using a 'flood filling' approach. It begins with a seed generated either as a sphere with \
05074 specified 'radius' or with the 'nmaxseed' highest values. It then includes any mass connected to the seed with value higher than 'threshold'.\
05075 Next, the mask is expanded by 'nshells'+'nshellsgauss'/2 voxels. Finally a gaussian low-pass filter is applied with a width of 'nshellsgauss'.";
05076                 }
05077 
05078                 virtual TypeDict get_param_types() const
05079                 {
05080                         TypeDict d;
05081                         d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
05082                         d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
05083                         d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
05084                         d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
05085                         d.put("nshells", EMObject::INT, "Number of 1-voxel shells to expand the mask by.");
05086                         d.put("nshellsgauss", EMObject::INT, "Width in voxels of a Gaussian decay at the edge of the mask.");
05087                         d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
05088                         d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
05089                         return d;
05090                 }
05091 
05092                 static const string NAME;
05093         };
05094 
05098         class AddMaskShellProcessor:public Processor
05099         {
05100           public:
05101                 virtual void process_inplace(EMData * image);
05102 
05103                 virtual string get_name() const
05104                 {
05105                         return NAME;
05106                 }
05107 
05108                 virtual string get_desc() const
05109                 {
05110                         return "Add additional shells/rings to an existing 1/0 mask image";
05111                 }
05112 
05113                 static Processor *NEW()
05114                 {
05115                         return new AddMaskShellProcessor();
05116                 }
05117 
05118                 virtual TypeDict get_param_types() const
05119                 {
05120                         TypeDict d;
05121                         d.put("nshells", EMObject::INT, "number of shells to add");
05122                         return d;
05123                 }
05124 
05125                 static const string NAME;
05126         };
05127 
05132         class PhaseToMassCenterProcessor:public Processor
05133         {
05134                 public:
05135                         virtual void process_inplace(EMData * image);
05136 
05137                         virtual string get_name() const
05138                         {
05139                                 return NAME;
05140                         }
05141 
05142                         static Processor *NEW()
05143                         {
05144                                 return new PhaseToMassCenterProcessor();
05145                         }
05146 
05147                         virtual string get_desc() const
05148                         {
05149                                 return "centers the image the center of mass, which is calculated using Fourier phases, ignores old dx, dy.";
05150                         }
05151 
05152                         virtual TypeDict get_param_types() const
05153                         {
05154                                 TypeDict d;
05155                                 d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05156                                 return d;
05157                         }
05158 
05159                         static const string NAME;
05160         };
05161 
05166         class ToMassCenterProcessor:public Processor
05167         {
05168           public:
05169                 virtual void process_inplace(EMData * image);
05170 
05171                 virtual string get_name() const
05172                 {
05173                         return NAME;
05174                 }
05175 
05176                 static Processor *NEW()
05177                 {
05178                         return new ToMassCenterProcessor();
05179                 }
05180 
05181                 virtual string get_desc() const
05182                 {
05183                         return "ToMassCenterProcessor centers image at center of mass, with a threshold. Only values higher than the threshold are considered.";
05184                 }
05185 
05186                 virtual TypeDict get_param_types() const
05187                 {
05188                         TypeDict d;
05189                         d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05190                         d.put("threshold", EMObject::FLOAT, "Only values larger than the threshold are included in the center of mass computation. Default is 0.");
05191 //                      d.put("positive", EMObject::INT, "uses only densities >0 for the calculatton");
05192                         return d;
05193                 }
05194 
05195                 static const string NAME;
05196         };
05197 
05201         class ACFCenterProcessor:public Processor
05202         {
05203           public:
05204                 virtual void process_inplace(EMData * image);
05205 
05206                 virtual string get_name() const
05207                 {
05208                         return NAME;
05209                 }
05210 
05211                 static Processor *NEW()
05212                 {
05213                         return new ACFCenterProcessor();
05214                 }
05215 
05216                 virtual string get_desc() const
05217                 {
05218                         return "Center image using self-convolution.";
05219                 }
05220 
05221                 virtual TypeDict get_param_types() const
05222                 {
05223                         TypeDict d;
05224                         return d;
05225                 }
05226 
05227                 static const string NAME;
05228         };
05229 
05234         class SNRProcessor:public Processor
05235         {
05236           public:
05237                 virtual void process_inplace(EMData * image);
05238 
05239                 virtual string get_name() const
05240                 {
05241                         return NAME;
05242                 }
05243 
05244                 static Processor *NEW()
05245                 {
05246                         return new SNRProcessor();
05247                 }
05248 
05249                 virtual string get_desc() const
05250                 {
05251                         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.";
05252                 }
05253 
05254                 virtual TypeDict get_param_types() const
05255                 {
05256                         TypeDict d;
05257                         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");
05258                         d.put("snrfile", EMObject::STRING, "structure factor file name");
05259                         return d;
05260                 }
05261 
05262                 static const string NAME;
05263         };
05264 
05268         class FileFourierProcessor:public Processor
05269         {
05270           public:
05271                 virtual void process_inplace(EMData * image);
05272 
05273                 virtual string get_name() const
05274                 {
05275                         return NAME;
05276                 }
05277 
05278                 virtual string get_desc() const
05279                 {
05280                         return "A fourier processor specified in a 2 column text file.";
05281                 }
05282 
05283                 static Processor *NEW()
05284                 {
05285                         return new FileFourierProcessor();
05286                 }
05287 
05288                 virtual TypeDict get_param_types() const
05289                 {
05290                         TypeDict d;
05291                         d.put("filename", EMObject::STRING, "file name for a 2 column text file which specified a radial function data array.");
05292                         return d;
05293                 }
05294 
05295                 static const string NAME;
05296         };
05297 
05308         class SymSearchProcessor:public Processor
05309         {
05310           public:
05311                 virtual void process_inplace(EMData * image);
05312 
05313                 virtual string get_name() const
05314                 {
05315                         return NAME;
05316                 }
05317 
05318                 virtual string get_desc() const
05319                 {
05320                         return "Identifiy the best symmetry in the given symmetry list for each pixel and then apply the best symmetry to each pixel.";
05321                 }
05322 
05323                 static Processor *NEW()
05324                 {
05325                         return new SymSearchProcessor();
05326                 }
05327 
05328                 virtual TypeDict get_param_types() const
05329                 {
05330                         TypeDict d;
05331                         d.put("sym", EMObject::STRINGARRAY, "the list of symmetries to search");
05332                         d.put("thresh", EMObject::FLOAT, "the minimal level of symmetry to be accepted (0-1)");
05333                         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");
05334                         d.put("symlabel_map", EMObject::EMDATA, "the optional return map when output_symlabel=1");
05335                         return d;
05336                 }
05337 
05338                 static const string NAME;
05339         };
05340 
05346         class LocalNormProcessor:public Processor
05347         {
05348           public:
05349                 void process_inplace(EMData * image);
05350 
05351                 virtual string get_name() const
05352                 {
05353                         return NAME;
05354                 }
05355 
05356                 static Processor *NEW()
05357                 {
05358                         return new LocalNormProcessor();
05359                 }
05360 
05361                 virtual string get_desc() const
05362                 {
05363                         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.";
05364                 }
05365 
05366                 virtual TypeDict get_param_types() const
05367                 {
05368                         TypeDict d;
05369                         d.put("threshold", EMObject::FLOAT, "an isosurface threshold at which all desired features are visible");
05370                         d.put("radius", EMObject::FLOAT, "a normalization size similar to an lp= value");
05371                         d.put("apix", EMObject::FLOAT, "Angstrom per pixel ratio");
05372                         return d;
05373                 }
05374 
05375                 static const string NAME;
05376         };
05377 
05382         class IndexMaskFileProcessor:public Processor
05383         {
05384           public:
05385                 virtual void process_inplace(EMData * image);
05386 
05387                 virtual string get_name() const
05388                 {
05389                         return NAME;
05390                 }
05391 
05392                 static Processor *NEW()
05393                 {
05394                         return new IndexMaskFileProcessor();
05395                 }
05396 
05397                 virtual TypeDict get_param_types() const
05398                 {
05399                         TypeDict d;
05400                         d.put("filename", EMObject::STRING, "mask image file name");
05401                         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");
05402                         return d;
05403                 }
05404 
05405                 virtual string get_desc() const
05406                 {
05407                         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.";
05408                 }
05409 
05410                 static const string NAME;
05411         };
05412 
05416         class CoordinateMaskFileProcessor:public Processor
05417         {
05418           public:
05419                 virtual void process_inplace(EMData * image);
05420 
05421                 virtual string get_name() const
05422                 {
05423                         return NAME;
05424                 }
05425 
05426                 static Processor *NEW()
05427                 {
05428                         return new CoordinateMaskFileProcessor();
05429                 }
05430 
05431                 virtual string get_desc() const
05432                 {
05433                         return "Multiplies the image by the specified file using pixel coordinates instead of pixel indices. The images can be different size.";
05434                 }
05435 
05436                 virtual TypeDict get_param_types() const
05437                 {
05438                         TypeDict d;
05439                         d.put("filename", EMObject::STRING, "mask image file name");
05440                         return d;
05441                 }
05442 
05443                 static const string NAME;
05444         };
05445 
05456         class PaintProcessor:public Processor
05457         {
05458           public:
05459                 PaintProcessor():x(0), y(0), z(0),r1(0), v1(0.0), r2(0), v2(0.0)
05460                 {
05461                 }
05462 
05463                 virtual string get_name() const
05464                 {
05465                         return NAME;
05466                 }
05467 
05468                 static Processor *NEW()
05469                 {
05470                         return new PaintProcessor();
05471                 }
05472 
05473                 virtual string get_desc() const
05474                 {
05475                         return "Paints a circle with a decaying edge into the image. r<r1 -> v1, r1<r<r2 -> (v1,v2), r>r2 unchanged";
05476                 }
05477 
05478                 virtual TypeDict get_param_types() const
05479                 {
05480                         TypeDict d;
05481                         d.put("x", EMObject::INT, "x coordinate for Center of circle");
05482                         d.put("y", EMObject::INT, "y coordinate for Center of circle");
05483                         d.put("z", EMObject::INT, "z coordinate for Center of circle");
05484                         d.put("r1", EMObject::INT, "Inner radius");
05485                         d.put("v1", EMObject::FLOAT, "Inner value");
05486                         d.put("r2", EMObject::INT, "Outter radius");
05487                         d.put("v2", EMObject::FLOAT, "Outer Value");
05488                         return d;
05489                 }
05490 
05491                 virtual void set_params(const Dict & new_params)
05492                 {
05493                         params = new_params;
05494 
05495                         if (params.has_key("x")) x = params["x"];
05496                         if (params.has_key("y")) y = params["y"];
05497                         if (params.has_key("z")) z = params["z"];
05498                         if (params.has_key("r1")) r1 = params["r1"];
05499                         if (params.has_key("r2")) r2 = params["r2"];
05500                         if (params.has_key("v1")) v1 = params["v1"];
05501                         if (params.has_key("v2")) v2 = params["v2"];
05502                 }
05503 
05504                 static const string NAME;
05505 
05506                 protected:
05507                 virtual void process_inplace(EMData *image);
05508 
05509                 int x,y,z,r1;
05510                 float v1;
05511                 int r2;
05512                 float v2;
05513 
05514         };
05515 
05516 
05521         class DirectionalSumProcessor : public Processor
05522         {
05523           public:
05524                 virtual string get_name() const
05525                 {
05526                         return NAME;
05527                 }
05528 
05529                 static Processor *NEW()
05530                 {
05531                         return new DirectionalSumProcessor();
05532                 }
05533 
05537                 virtual EMData* process(const EMData* const image);
05538 
05542                 virtual void process_inplace(EMData*) {
05543                         throw InvalidCallException("The directional sum processor does not work inplace");
05544                 }
05545 
05546                 virtual TypeDict get_param_types() const
05547                 {
05548                         TypeDict d;
05549                         d.put("axis", EMObject::STRING,"The direction of the sum, either x,y or z. Returned axes are xy, xz or zy.");
05550                         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)");
05551                         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)");
05552                         return d;
05553                 }
05554 
05555                 string get_desc() const
05556                 {
05557                         return "Calculates the projection of the image along one of the axial directions, either x, y or z";
05558                 }
05559 
05560                 static const string NAME;
05561         };
05562 
05570         class WatershedProcessor:public Processor
05571         {
05572           public:
05573                 virtual void process_inplace(EMData * image);
05574 
05575                 virtual string get_name() const
05576                 {
05577                         return NAME;
05578                 }
05579 
05580                 static Processor *NEW()
05581                 {
05582                         return new WatershedProcessor();
05583                 }
05584 
05585                 virtual string get_desc() const
05586                 {
05587                         return "Does a watershed";
05588                 }
05589 
05590                 virtual TypeDict get_param_types() const
05591                 {
05592                         TypeDict d;
05593                         d.put("xpoints", EMObject::FLOATARRAY,"x coordinates");
05594                         d.put("ypoints", EMObject::FLOATARRAY,"y coordinates");
05595                         d.put("zpoints", EMObject::FLOATARRAY,"z coordinates");
05596                         d.put("minval", EMObject::FLOAT,"min value");
05597                         return d;
05598                 }
05599 
05600                 static const string NAME;
05601 
05602           private:
05603                   vector<Vec3i > watershed(EMData* mask, EMData* image, const float& threshold, const Vec3i& cordinate, const int mask_value);
05604                   vector<Vec3i > find_region(EMData* mask,const vector<Vec3i >& coords, const int mask_value, vector<Vec3i >& region);
05605 
05606         };
05607 
05617         template<class Type>
05618         class BinaryOperateProcessor : public Processor{
05619                 public:
05624                         virtual void process_inplace(EMData * image) {
05625                                 if ( ! params.has_key("with") ) throw InvalidParameterException("You must supply the \"with\" parameter");
05626                                 EMData* with = params["with"];
05627 
05628                                 if ( with->get_xsize() != image->get_xsize() || with->get_ysize() != image->get_ysize() || with->get_zsize() != image->get_zsize() )
05629                                         throw ImageDimensionException("The images you are operating on do not have the same dimensions");
05630 
05631                                 float* image_data = image->get_data();
05632                                 float* with_data = with->get_data();
05633 
05634                                 std::transform(image_data,image_data+image->get_size(),with_data,image_data,Type::binary_operate);
05635                                 image->update();
05636                         }
05637 
05638                         virtual string get_name() const
05639                         {
05640                                 return op.get_name();
05641                         }
05642 
05643                         virtual string get_desc() const
05644                         {
05645                                 return op.get_desc();
05646                         }
05647 
05648                         static Processor *NEW()
05649                         {
05650                                 return new BinaryOperateProcessor<Type>();
05651                         }
05652 
05653                         virtual TypeDict get_param_types() const
05654                         {
05655                                 TypeDict d;
05656                                 d.put("with", EMObject::EMDATA,"The second image");
05657                                 return d;
05658                         }
05659 
05660                         static const string NAME;
05661                 private:
05662                         Type op;
05663         };
05664 
05665         class MaxPixelOperator {
05666                 public:
05667                 string get_name() const
05668                 {
05669                         return NAME;
05670                 }
05671 
05672                 string get_desc() const
05673                 {
05674                         return "Compares pixels in two images, returning an image with the maximum pixel value in each pixel location";
05675                 }
05676 
05677                 static float binary_operate(const float& left, const float& right) {
05678                         if (left > right) return left;
05679                         return right;
05680                 }
05681 
05682                 static const string NAME;
05683         };
05684 
05685         class MinPixelOperator {
05686                 public:
05687                         string get_name() const
05688                         {
05689                                 return NAME;
05690                         }
05691 
05692                         string get_desc() const
05693                         {
05694                                 return "Compares pixels in two images, returning an image with the minimum pixel value in each pixel location";
05695                         }
05696 
05697                         static float binary_operate(const float& left, const float& right) {
05698                                 if (left < right) return left;
05699                                 return right;
05700                         }
05701 
05702                         static const string NAME;
05703         };
05704 
05708         class MatchSFProcessor:public FourierAnlProcessor
05709         {
05710           public:
05711 
05712                 virtual string get_name() const
05713                 {
05714                         return NAME;
05715                 }
05716 
05717                 virtual string get_desc() const
05718                 {
05719                         return "Filters the image so its 1-D power spectrum matches a second image";
05720                 }
05721 
05722                 static Processor *NEW()
05723                 {
05724                         return new MatchSFProcessor();
05725                 }
05726 
05727                 virtual TypeDict get_param_types() const
05728                 {
05729                         TypeDict d;
05730                         d.put("to", EMObject::EMDATA, "The image to match with. Make sure apix values are correct.");
05731                         return d;
05732                 }
05733 
05734                 static const string NAME;
05735 
05736           protected:
05737                 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05738         };
05739 
05740 
05745         class SetSFProcessor:public FourierAnlProcessor
05746         {
05747           public:
05748 
05749                 virtual string get_name() const
05750                 {
05751                         return NAME;
05752                 }
05753 
05754                 virtual string get_desc() const
05755                 {
05756                         return "Filters the image so its 1-D power spectrum matches a supplied X-Y curve";
05757                 }
05758 
05759                 static Processor *NEW()
05760                 {
05761                         return new SetSFProcessor();
05762                 }
05763 
05764                 virtual TypeDict get_param_types() const
05765                 {
05766                         TypeDict d;
05767                         d.put("strucfac", EMObject::XYDATA, "An XYData object contaning the curve to be imposed as a function of S");
05768                         d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
05769                         return d;
05770                 }
05771 
05772                 static const string NAME;
05773 
05774           protected:
05775                 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05776         };
05777 
05781         class SmartMaskProcessor:public Processor
05782         {
05783           public:
05784                 virtual void process_inplace(EMData * image);
05785 
05786                 virtual string get_name() const
05787                 {
05788                         return NAME;
05789                 }
05790 
05791                 static Processor *NEW()
05792                 {
05793                         return new SmartMaskProcessor();
05794                 }
05795 
05796                 virtual string get_desc() const
05797                 {
05798                         return "Smart mask processor.";
05799                 }
05800 
05801                 virtual TypeDict get_param_types() const
05802                 {
05803                         TypeDict d;
05804                         d.put("mask", EMObject::FLOAT, "mask value");
05805                         return d;
05806                 }
05807 
05808                 static const string NAME;
05809         };
05810 
05815         class IterBinMaskProcessor:public Processor
05816         {
05817           public:
05818                 virtual void process_inplace(EMData * image);
05819 
05820                 virtual string get_name() const
05821                 {
05822                         return NAME;
05823                 }
05824 
05825                 virtual string get_desc() const
05826                 {
05827                         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.";
05828                 }
05829 
05830                 static Processor *NEW()
05831                 {
05832                         return new IterBinMaskProcessor();
05833                 }
05834 
05835                 virtual TypeDict get_param_types() const
05836                 {
05837                         TypeDict d;
05838                         d.put("val1", EMObject::FLOAT, "number of pixels to expand");
05839                         d.put("val2", EMObject::FLOAT, "number of Gaussian pixels to expand, following the first expansion");
05840                         return d;
05841                 }
05842 
05843                 static const string NAME;
05844         };
05845 
05848         class TestImageProcessor : public Processor
05849         {
05850         public:
05851                 static string get_group_desc()
05852                 {
05853                         return "Base class for a group of 'processors' used to create test image.";
05854                 }
05855 
05856         protected:
05857                 void preprocess(EMData * image);
05858                 int nx, ny, nz; //this is the size of the source image
05859         };
05860 
05869         class TestImagePureGaussian : public TestImageProcessor
05870         {
05871         public:
05872                 virtual void process_inplace(EMData * image);
05873 
05874                 virtual string get_name() const
05875                 {
05876                         return NAME;
05877                 }
05878 
05879                 virtual string get_desc() const
05880                 {
05881                         return "Replace a source image as a strict Gaussian ";
05882                 }
05883 
05884                 static Processor * NEW()
05885                 {
05886                         return new TestImagePureGaussian();
05887                 }
05888 
05889                 virtual TypeDict get_param_types() const
05890                 {
05891                         TypeDict d;
05892                         d.put("x_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on x direction");
05893                         d.put("y_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on y direction");
05894                         d.put("z_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on z direction");
05895                         d.put("x_center", EMObject::FLOAT, "center for this Gaussian blob on x direction" );
05896                         d.put("y_center", EMObject::FLOAT, "center for this Gaussian blob on y direction" );
05897                         d.put("z_center", EMObject::FLOAT, "center for this Gaussian blob on z direction" );
05898                         return d;
05899                 }
05900 
05901                 static const string NAME;
05902         };
05903 
05907         class TestImageFourierNoiseGaussian : public TestImageProcessor
05908         {
05909         public:
05910                 virtual void process_inplace(EMData * image);
05911 
05912                 virtual string get_name() const
05913                 {
05914                         return NAME;
05915                 }
05916 
05917                 virtual string get_desc() const
05918                 {
05919                         return "Replace a source image with pink Fourier noise, based on a Gaussian. Random phase.";
05920                 }
05921 
05922                 static Processor * NEW()
05923                 {
05924                         return new TestImageFourierNoiseGaussian();
05925                 }
05926 
05927                 virtual TypeDict get_param_types() const
05928                 {
05929                         TypeDict d;
05930                         d.put("sigma", EMObject::FLOAT, "sigma value");
05931                         return d;
05932                 }
05933 
05934                 static const string NAME;
05935         };
05936 
05941         class TestImageFourierNoiseProfile : public TestImageProcessor
05942         {
05943         public:
05944                 virtual void process_inplace(EMData * image);
05945 
05946                 virtual string get_name() const
05947                 {
05948                         return NAME;
05949                 }
05950 
05951                 virtual string get_desc() const
05952                 {
05953                         return "Replace a source image with Fourier noise using amplitude information that is stored in a profile.";
05954                 }
05955 
05956                 static Processor * NEW()
05957                 {
05958                         return new TestImageFourierNoiseProfile();
05959                 }
05960 
05961                 virtual TypeDict get_param_types() const
05962                 {
05963                         TypeDict d;
05964                         d.put("profile", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
05965                         return d;
05966                 }
05967 
05968                 static const string NAME;
05969         };
05970 
05971 
05976         class CTFSNRWeightProcessor : public TestImageProcessor
05977         {
05978                 public:
05979                         virtual void process_inplace(EMData * image);
05980 
05981                         virtual string get_name() const
05982                         {
05983                                 return NAME;
05984                         }
05985 
05986                         virtual string get_desc() const
05987                         {
05988                                 return "Weight the amplitudes of an image based on radial noise and snr curves ";
05989                         }
05990 
05991                         static Processor * NEW()
05992                         {
05993                                 return new CTFSNRWeightProcessor();
05994                         }
05995 
05996                         virtual TypeDict get_param_types() const
05997                         {
05998                                 TypeDict d;
05999                                 d.put("noise", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
06000                                 d.put("snr", EMObject::FLOATARRAY, "Squared amplitude divided by squared noise amplitude. As in, what is the EMAN2CTF.snr attribute");
06001                                 d.put("boost", EMObject::FLOAT, "Multiplicative signal boost");
06002                                 return d;
06003                         }
06004 
06005                         static const string NAME;
06006         };
06007 
06008 
06009 
06014         class TestImageLineWave : public TestImageProcessor
06015         {
06016                 public:
06017                         virtual void process_inplace(EMData * image);
06018 
06019                         virtual string get_name() const
06020                         {
06021                                 return NAME;
06022                         }
06023 
06024                         virtual string get_desc() const
06025                         {
06026                                 return "Insert an oscillating sine wave into the pixel data";
06027                         }
06028 
06029                         static Processor * NEW()
06030                         {
06031                                 return new TestImageLineWave();
06032                         }
06033 
06034                         virtual TypeDict get_param_types() const
06035                         {
06036                                 TypeDict d;
06037                                 d.put("period", EMObject::FLOAT, "The period of the oscillating sine wave. Default 10.");
06038                                 return d;
06039                         }
06040 
06041                         static const string NAME;
06042         };
06043 
06044 
06052         class TestTomoImage : public TestImageProcessor
06053         {
06054                 public:
06058                         virtual void process_inplace(EMData * image);
06059 
06060                         virtual string get_name() const
06061                         {
06062                                 return NAME;
06063                         }
06064 
06065                         virtual string get_desc() const
06066                         {
06067                                 return "Make an image consisting various objects, useful for tomographic testing";
06068                         }
06069 
06070                         static Processor * NEW()
06071                         {
06072                                 return new TestTomoImage();
06073                         }
06074 
06075                         static const string NAME;
06076 
06077                 private:
06078                         void insert_solid_ellipse( EMData* image, const Region& region, const float& value, const Transform& t3d  = Transform() );
06079                         void insert_hollow_ellipse( EMData* image, const Region& region, const float& value, const int& radius, const Transform& t3d = Transform() );
06080                         void insert_rectangle( EMData* image, const Region& region, const float& value, const Transform& t3d = Transform() );
06081         };
06082 
06090         class TestImageGradient : public TestImageProcessor
06091         {
06092                 public:
06093                         virtual void process_inplace(EMData * image);
06094 
06095                         virtual string get_name() const
06096                         {
06097                                 return NAME;
06098                         }
06099 
06100                         virtual string get_desc() const
06101                         {
06102                                 return "Make a gradient image of the form y=mx+b, where x is any of the image axes.";
06103                         }
06104 
06105                         static Processor * NEW()
06106                         {
06107                                 return new TestImageGradient();
06108                         }
06109 
06110                         virtual TypeDict get_param_types() const
06111                         {
06112                                 TypeDict d;
06113                                 d.put("axis", EMObject::STRING, "The axis the will be used to determine pixel values. Must be x,y or z");
06114                                 d.put("m", EMObject::FLOAT, "m in the equation m*axis+b. Default is 1.0");
06115                                 d.put("b", EMObject::FLOAT, "b in the equation m*axis+b. Default is 0.0");
06116                                 return d;
06117                         }
06118 
06119                         static const string NAME;
06120         };
06121 
06129         class TestImageAxes : public TestImageProcessor
06130         {
06131                 public:
06136                         virtual void process_inplace(EMData * image);
06137 
06138                         virtual string get_name() const
06139                         {
06140                                 return NAME;
06141                         }
06142 
06143                         virtual string get_desc() const
06144                         {
06145                                 return "Make an image consisting of a single cross";
06146                         }
06147 
06148                         static Processor * NEW()
06149                         {
06150                                 return new TestImageAxes();
06151                         }
06152 
06153                         virtual TypeDict get_param_types() const
06154                         {
06155                                 TypeDict d;
06156                                 d.put("int", EMObject::FLOAT, "radius of the lines emanating from the origin");
06157                                 d.put("fill", EMObject::FLOAT, "value to make non-zero pixels");
06158                                 return d;
06159                         }
06160 
06161                         static const string NAME;
06162         };
06163 
06169         class TestImageGaussian : public TestImageProcessor
06170         {
06171         public:
06172                 virtual void process_inplace(EMData * image);
06173 
06174                 virtual string get_name() const
06175                 {
06176                         return NAME;
06177                 }
06178 
06179                 virtual string get_desc() const
06180                 {
06181                         return "Replace a source image as a Gaussian Blob";
06182                 }
06183 
06184                 static Processor * NEW()
06185                 {
06186                         return new TestImageGaussian();
06187                 }
06188 
06189                 virtual TypeDict get_param_types() const
06190                 {
06191                         TypeDict d;
06192                         d.put("sigma", EMObject::FLOAT, "sigma value for this Gaussian blob");
06193                         d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06194                         d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06195                         return d;
06196                 }
06197 
06198                 static const string NAME;
06199         };
06200 
06203         class TestImageScurve : public TestImageProcessor
06204         {
06205         public:
06206                 virtual void process_inplace(EMData * image);
06207 
06208                 virtual string get_name() const
06209                 {
06210                         return NAME;
06211                 }
06212 
06213                 virtual string get_desc() const
06214                 {
06215                         return "Replace a source image with a lumpy S-curve used for alignment testing";
06216                 }
06217 
06218                 static Processor * NEW()
06219                 {
06220                         return new TestImageScurve();
06221                 }
06222 
06223                 virtual TypeDict get_param_types() const
06224                 {
06225                         TypeDict d;
06226                         return d;
06227                 }
06228 
06229                 static const string NAME;
06230         };
06231 
06239         class TestImageSphericalWave : public TestImageProcessor
06240         {
06241         public:
06242                 virtual void process_inplace(EMData * image);
06243 
06244                 virtual string get_name() const
06245                 {
06246                         return NAME;
06247                 }
06248 
06249                 virtual string get_desc() const
06250                 {
06251                         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)";
06252                 }
06253 
06254                 static Processor * NEW()
06255                 {
06256                         return new TestImageSphericalWave();
06257                 }
06258 
06259                 virtual TypeDict get_param_types() const
06260                 {
06261                         TypeDict d;
06262                         d.put("wavelength", EMObject::FLOAT, "cos(2*pi*r/wavelength+phase)");
06263                         d.put("phase", EMObject::FLOAT, "in radians");
06264                         d.put("x", EMObject::FLOAT, "center of the spherical wave");
06265                         d.put("y", EMObject::FLOAT, "center of the spherical wave");
06266                         d.put("z", EMObject::FLOAT, "center of the spherical wave");
06267                         return d;
06268                 }
06269 
06270                 static const string NAME;
06271         };
06272 
06273 
06282         class TestImageSinewave : public TestImageProcessor
06283         {
06284         public:
06285                 virtual void process_inplace(EMData * image);
06286 
06287                 virtual string get_name() const
06288                 {
06289                         return NAME;
06290                 }
06291 
06292                 virtual string get_desc() const
06293                 {
06294                         return "Replace a source image as a sine wave in specified wave length";
06295                 }
06296 
06297                 static Processor * NEW()
06298                 {
06299                         return new TestImageSinewave();
06300                 }
06301 
06302                 virtual TypeDict get_param_types() const
06303                 {
06304                         TypeDict d;
06305                         d.put("wavelength", EMObject::FLOAT, "wavelength in equation sin(x*2*PI/wavelength - phase*180/PI)");
06306                         d.put("axis", EMObject::STRING, "(optional) specify a major axis for asymmetric features, default x axis");
06307                         d.put("phase", EMObject::FLOAT, "(optional) the phase in radians");
06308                         d.put("az", EMObject::FLOAT, "(optional) angle in degree. for 2D image, this is the rotated angle of the image, \
06309                                                                                                 in 3D image, it's az for euler angle. default is zero");
06310                         d.put("alt", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, alt for euler angle, default is zero");
06311                         d.put("phi", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, phi for euler angle, default is zero");
06312                         return d;
06313                 }
06314 
06315                 static const string NAME;
06316         };
06317 
06324         class TestImageSinewaveCircular : public TestImageProcessor
06325         {
06326         public:
06327                 virtual void process_inplace(EMData * image);
06328 
06329                 virtual string get_name() const
06330                 {
06331                         return NAME;
06332                 }
06333 
06334                 virtual string get_desc() const
06335                 {
06336                         return "Replace a source image as a circular sine wave in specified wave length";
06337                 }
06338 
06339                 static Processor * NEW()
06340                 {
06341                         return new TestImageSinewaveCircular();
06342                 }
06343 
06344                 virtual TypeDict get_param_types() const
06345                 {
06346                         TypeDict d;
06347                         d.put("wavelength", EMObject::FLOAT, "(required)this value is the d in function |sin(x/d)|, unit: pixel");
06348                         d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06349                         d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06350                         d.put("phase", EMObject::FLOAT, "(optional)phase for sine wave, default is 0");
06351                         return d;
06352                 }
06353 
06354                 static const string NAME;
06355         };
06356 
06363         class TestImageSquarecube : public TestImageProcessor
06364         {
06365         public:
06366                 virtual void process_inplace(EMData * image);
06367 
06368                 virtual string get_name() const
06369                 {
06370                         return NAME;
06371                 }
06372 
06373                 virtual string get_desc() const
06374                 {
06375                         return "Replace a source image as a square or cube depends on 2D or 3D of the source image";
06376                 }
06377 
06378                 static Processor * NEW()
06379                 {
06380                         return new TestImageSquarecube();
06381                 }
06382 
06383                 virtual TypeDict get_param_types() const
06384                 {
06385                         TypeDict d;
06386                         d.put("edge_length", EMObject::FLOAT, "edge length of the square or cube, unit: pixel");
06387                         d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06388                         d.put("odd_edge", EMObject::FLOAT, "edge length for the asymmetric axis");
06389                         d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank");
06390                         return d;
06391                 }
06392 
06393                 static const string NAME;
06394         };
06395 
06403         class TestImageEllipse : public TestImageProcessor
06404         {
06405         public:
06406                 virtual void process_inplace(EMData * image);
06407 
06408                 virtual string get_name() const
06409                 {
06410                         return NAME;
06411                 }
06412 
06413                 virtual string get_desc() const
06414                 {
06415                         return "Insert an ellipse into the image.";
06416                 }
06417 
06418                 static Processor * NEW()
06419                 {
06420                         return new TestImageEllipse();
06421                 }
06422 
06423                 virtual TypeDict get_param_types() const
06424                 {
06425                         TypeDict d;
06426                         d.put("a", EMObject::FLOAT, "equatorial radius along x axes (major semiaxes)");
06427                         d.put("b", EMObject::FLOAT, "equatorial radius along y axes (minor semiaxes)");
06428                         d.put("c", EMObject::FLOAT, "polar radius for ellipsoid (x^2/a^2+y^2/b^2+z^2/c^2=1)");
06429                         d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06430                         d.put("fill", EMObject::FLOAT, "value you want to fill in ellipse, default to 1.0");
06431                         return d;
06432                 }
06433 
06434                 static const string NAME;
06435         };
06436 
06448         class TestImageHollowEllipse : public TestImageProcessor
06449                 {
06450                 public:
06451                         virtual void process_inplace(EMData * image);
06452 
06453                         virtual string get_name() const
06454                         {
06455                                 return NAME;
06456                         }
06457 
06458                         virtual string get_desc() const
06459                         {
06460                                 return "Insert a hollow ellipse into the image.";
06461                         }
06462 
06463                         static Processor * NEW()
06464                         {
06465                                 return new TestImageHollowEllipse();
06466                         }
06467 
06468                         virtual TypeDict get_param_types() const
06469                         {
06470                                 TypeDict d;
06471                                 d.put("xwidth", EMObject::FLOAT, "inner equatorial radii along x axes");
06472                                 d.put("ywidth", EMObject::FLOAT, "inner equatorial radii along y axes");
06473                                 d.put("zwidth", EMObject::FLOAT, "inner polar radius");
06474                                 d.put("a", EMObject::FLOAT, "outter equatorial radii along x axes");
06475                                 d.put("b", EMObject::FLOAT, "outter equatorial radii along y axes");
06476                                 d.put("c", EMObject::FLOAT, "outter polar radius");
06477                                 d.put("width",EMObject::FLOAT, "width - specify the width or specify each width explicitly - xwidth, ywidth, zwidth");
06478                                 d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06479                                 d.put("fill", EMObject::FLOAT, "value you want to fill in hollow ellipse, default to 1.0");
06480                                 return d;
06481                         }
06482 
06483                         static const string NAME;
06484                 };
06485 
06492         class TestImageCirclesphere : public TestImageProcessor
06493         {
06494         public:
06495                 virtual void process_inplace(EMData * image);
06496 
06497                 virtual string get_name() const
06498                 {
06499                         return NAME;
06500                 }
06501 
06502                 virtual string get_desc() const
06503                 {
06504                         return "Replace a source image as a circle or sphere depends on 2D or 3D of the source image";
06505                 }
06506 
06507                 static Processor * NEW()
06508                 {
06509                         return new TestImageCirclesphere();
06510                 }
06511 
06512                 virtual TypeDict get_param_types() const
06513                 {
06514                         TypeDict d;
06515                         d.put("radius", EMObject::FLOAT, "radius of circle or sphere, unit: pixel");
06516                         d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06517                         d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06518                         d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank.");
06519                         return d;
06520                 }
06521 
06522                 static const string NAME;
06523         };
06524 
06529         class TestImageNoiseUniformRand : public TestImageProcessor
06530         {
06531         public:
06532                 virtual void process_inplace(EMData * image);
06533 
06534                 virtual string get_name() const
06535                 {
06536                         return NAME;
06537                 }
06538 
06539                 virtual string get_desc() const
06540                 {
06541                         return "Replace a source image as a uniform random noise, random number generated from gsl_rng_mt19937, the pixel value is [0, 1)";
06542                 }
06543 
06544                 static Processor * NEW()
06545                 {
06546                         return new TestImageNoiseUniformRand();
06547                 }
06548 
06549                 virtual TypeDict get_param_types() const
06550                 {
06551                         TypeDict d;
06552                         d.put("seed", EMObject::INT, "seed for random number generator");
06553                         return d;
06554                 }
06555 
06556                 static const string NAME;
06557         };
06558 
06569         class TestImageNoiseGauss : public TestImageProcessor
06570         {
06571         public:
06572                 virtual void process_inplace(EMData * image);
06573 
06574                 virtual string get_name() const
06575                 {
06576                         return NAME;
06577                 }
06578 
06579                 virtual string get_desc() const
06580                 {
06581                         return "Replace a source image as a random noise, the random value is gaussian distributed";
06582                 }
06583 
06584                 static Processor * NEW()
06585                 {
06586                         return new TestImageNoiseGauss();
06587                 }
06588 
06589                 virtual TypeDict get_param_types() const
06590                 {
06591                         TypeDict d;
06592                         d.put("sigma", EMObject::FLOAT, "sigma value of gausian distributed noise, default is 0.5");
06593                         d.put("mean", EMObject::FLOAT, "mean value of gausian distributed noise, default is zero.");
06594                         d.put("seed", EMObject::INT, "the seed for random number generator, default is not to reseed.");
06595 
06596                         return d;
06597                 }
06598 
06599                 static const string NAME;
06600         };
06601 
06606         class TestImageCylinder : public TestImageProcessor
06607         {
06608         public:
06609                 virtual void process_inplace(EMData * image);
06610 
06611                 virtual string get_name() const
06612                 {
06613                         return NAME;
06614                 }
06615 
06616                 virtual string get_desc() const
06617                 {
06618                         return "Replace a source image as a cylinder";
06619                 }
06620 
06621                 static Processor * NEW()
06622                 {
06623                         return new TestImageCylinder();
06624                 }
06625 
06626                 virtual TypeDict get_param_types() const
06627                 {
06628                         TypeDict d;
06629                         d.put("radius", EMObject::FLOAT, "radius for the cylinder");
06630                         d.put("height", EMObject::FLOAT, "height for the cylinder, by default it's the nz");
06631 
06632                         return d;
06633                 }
06634 
06635                 static const string NAME;
06636         };
06637 
06643         class CCDNormProcessor:public Processor
06644         {
06645           public:
06646                 virtual void process_inplace(EMData * image);
06647 
06648                 virtual string get_name() const
06649                 {
06650                         return NAME;
06651                 }
06652 
06653                 static Processor *NEW()
06654                 {
06655                         return new CCDNormProcessor();
06656                 }
06657 
06658                 virtual         string get_desc() const
06659                 {
06660                         return "normalize the 4 quadrants of a CCD image";
06661                 }
06662 
06663                 virtual TypeDict get_param_types() const
06664                 {
06665                         TypeDict d;
06666                         d.put("width", EMObject::INT, "number of pixels on either side of the seam to sample");
06667                         return d;
06668                 }
06669 
06670                 static const string NAME;
06671         };
06672 
06680         class WaveletProcessor:public Processor
06681         {
06682           public:
06683                 virtual void process_inplace(EMData * image);
06684 
06685                 virtual string get_name() const
06686                 {
06687                         return NAME;
06688                 }
06689 
06690                 static Processor *NEW()
06691                 {
06692                         return new WaveletProcessor();
06693                 }
06694 
06695                 virtual TypeDict get_param_types() const
06696                 {
06697                         TypeDict d;
06698                         d.put("type", EMObject::STRING, "'daub', 'harr' or 'bspl'");
06699                         d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06700                         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)");
06701                         return d;
06702                 }
06703 
06704                 virtual string get_desc() const
06705                 {
06706                         return "Computes the DWT (discrete wavelet transform) of an image in one of 3 possible bases";
06707                 }
06708 
06709                 static const string NAME;
06710         };
06711 
06727         class TomoTiltEdgeMaskProcessor : public Processor
06728         {
06729         public:
06730                 virtual void process_inplace(EMData* image);
06731 
06732                 virtual string get_name() const
06733                 {
06734                         return NAME;
06735                 }
06736 
06737                 static Processor *NEW()
06738                 {
06739                         return new TomoTiltEdgeMaskProcessor();
06740                 }
06741 
06742                 virtual TypeDict get_param_types() const
06743                 {
06744                         TypeDict d;
06745                         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");
06746                         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.");
06747                         d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06748                         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.");
06749                         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)");
06750                         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");
06751                         return d;
06752                 }
06753 
06754                 virtual string get_desc() const
06755                 {
06756                         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.";
06757                 }
06758 
06759                 static const string NAME;
06760 
06761         private:
06762                 class GaussianFunctoid
06763                 {
06764                         public:
06765                                 GaussianFunctoid(const float sigma, const float mean = 0.0) : m_mean(mean), m_sigma_squared(sigma*sigma) {}
06766                                 ~GaussianFunctoid() {}
06767 
06768                                 float operator()(const float distance )
06769                                 {
06770                                         return exp( -(distance-m_mean)*(distance-m_mean)/ (m_sigma_squared ));
06771                                 }
06772                         private:
06773                                 float m_mean, m_sigma_squared;
06774                 };
06775 
06776         };
06777 
06792         class TomoTiltAngleWeightProcessor : public Processor
06793         {
06794                 public:
06795                         virtual void process_inplace(EMData* image);
06796 
06797                         virtual string get_name() const
06798                         {
06799                                 return NAME;
06800                         }
06801 
06802                         static Processor *NEW()
06803                         {
06804                                 return new TomoTiltAngleWeightProcessor();
06805                         }
06806 
06807                         virtual TypeDict get_param_types() const
06808                         {
06809                                 TypeDict d;
06810                                 d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06811                                 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");
06812                                 return d;
06813                         }
06814 
06815                         virtual string get_desc() const
06816                         {
06817                                 return "Weights the image by 1/cos(angle)";
06818                         }
06819 
06820                         static const string NAME;
06821 
06822         };
06823 
06827         class FFTProcessor : public Processor
06828         {
06829           public:
06830                 void process_inplace(EMData * image);
06831 
06832                 string get_name() const
06833                 {
06834                         return NAME;
06835                 }
06836 
06837                 static Processor *NEW()
06838                 {
06839                         return new FFTProcessor();
06840                 }
06841 
06842                 TypeDict get_param_types() const
06843                 {
06844                         TypeDict d;
06845                         d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06846                         return d;
06847                 }
06848 
06849                 string get_desc() const
06850                 {
06851                         return "Computes the DFFT (Discrete Fast Fourier Transform) of an image";
06852                 }
06853 
06854                 static const string NAME;
06855         };
06856 
06861         class RadialProcessor : public Processor
06862         {
06863         public:
06864                 void process_inplace(EMData * image);
06865 
06866                 string get_name() const
06867                 {
06868                         return NAME;
06869                 }
06870 
06871                 static Processor *NEW()
06872                 {
06873                         return new RadialProcessor();
06874                 }
06875 
06876                 TypeDict get_param_types() const
06877                 {
06878                         TypeDict d;
06879                         d.put("table", EMObject::FLOATARRAY, "Radial array of floats, 1 float/pixel");
06880                         return d;
06881                 }
06882 
06883                 string get_desc() const
06884                 {
06885                         return "Multiply a real-space image by a radial function. 1 value / pixel, extending to corner. Missing values -> 0.";
06886                 }
06887 
06888                 static const string NAME;
06889         };
06890 
06897         class HistogramBin : public Processor
06898         {
06899                 public:
06900                         HistogramBin() : default_bins(1024) {}
06901 
06902                         void process_inplace(EMData * image);
06903 
06904                         string get_name() const
06905                         {
06906                                 return NAME;
06907                         }
06908 
06909                         static Processor *NEW()
06910                         {
06911                                 return new HistogramBin();
06912                         }
06913 
06914                         TypeDict get_param_types() const
06915                         {
06916                                 TypeDict d;
06917                                 d.put("nbins", EMObject::INT, "The number of bins the pixel values will be compressed into");
06918                                 d.put("debug", EMObject::BOOL, "Outputs debugging information (number of pixels per bin)");
06919                                 return d;
06920                         }
06921 
06922                         string get_desc() const
06923                         {
06924                                 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";
06925                         }
06926 
06927                         static const string NAME;
06928 
06929                 protected:
06930                         int default_bins;
06931         };
06932 
06933         class ModelHelixProcessor : public Processor
06934         {
06935           protected:
06936                 float radprofile(float r, int type);
06937         };
06938 
06939         class ModelEMCylinderProcessor : public ModelHelixProcessor
06940         {
06941           public:
06942                 void process_inplace(EMData * in);
06943 
06944                 string get_name() const
06945                 {
06946                         return NAME;
06947                 }
06948 
06949                 static Processor *NEW()
06950                 {
06951                         return new ModelEMCylinderProcessor();
06952                 }
06953 
06954                 string get_desc() const
06955                 {
06956                         return "Adds a cylinder with a radial density profile similar to that of an alpha helix.";
06957                 }
06958 
06959                 virtual TypeDict get_param_types() const
06960                 {
06961                         TypeDict d;
06962                         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");
06963                         d.put("length", EMObject::FLOAT, "cylinder length in angstroms, defaults to 3 turns (16.2 Angstroms)");
06964                         d.put("x0", EMObject::INT, "x coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06965                         d.put("y0", EMObject::INT, "y coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06966                         d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06967                         //TODO: Check with Matt Baker about description strings
06968                         return d;
06969                 }
06970 
06971                 static const string NAME;
06972         };
06973 
06974         class ApplyPolynomialProfileToHelix : public ModelHelixProcessor
06975         {
06976         public:
06977                 void process_inplace(EMData * in);
06978 
06979                 string get_name() const
06980                 {
06981                         return NAME;
06982                 }
06983 
06984                 static Processor *NEW()
06985                 {
06986                         return new ApplyPolynomialProfileToHelix();
06987                 }
06988 
06989                 string get_desc() const
06990                 {
06991                         return "Finds the CM of each z-axis slice and applies a polynomial radial profile about it.";
06992                 }
06993                 virtual TypeDict get_param_types() const
06994                 {
06995                         TypeDict d;
06996                         d.put("length", EMObject::FLOAT, "Helix length in angstroms.");
06997                         d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06998                         return d;
06999                 }
07000 
07001                 static const string NAME;
07002         };
07003 
07004         class BinarySkeletonizerProcessor : public Processor
07005         {
07006         public:
07007                 virtual EMData* process(EMData * image);
07008                 virtual void process_inplace(EMData * image);
07009 
07010                 virtual string get_name() const
07011                 {
07012                         return NAME;
07013 //                      return "gorgon.binary_skel";
07014                 }
07015                 static Processor *NEW()
07016                 {
07017                         return new BinarySkeletonizerProcessor();
07018                 }
07019                 string get_desc() const
07020                 {
07021                         return "Creates a skeleton of the 3D image by considering whether density is above or below a threshold value.";
07022                 }
07023                 virtual TypeDict get_param_types() const
07024                 {
07025                         TypeDict d;
07026                         d.put("threshold", EMObject::FLOAT, "Threshold value.");
07027                         d.put("min_curve_width", EMObject::INT, "Minimum curve width.");
07028                         d.put("min_surface_width", EMObject::INT, "Minimum surface width.");
07029                         d.put("mark_surfaces", EMObject::BOOL, "Mark surfaces with a value of 2.0f, whereas curves are 1.0f.");
07030                         return d;
07031                 }
07032                 static const string NAME;
07033         };
07034 
07035         class ConvolutionKernelProcessor : public Processor
07036         {
07037         public:
07038                 virtual EMData* process(const EMData* const image);
07039                 virtual void process_inplace(EMData * image);
07040                 
07041                 virtual string get_name() const
07042                 {
07043                         return NAME;
07044                 }
07045                 static Processor *NEW()
07046                 {
07047                         return new ConvolutionKernelProcessor();
07048                 }
07049                 string get_desc() const
07050                 {
07051                         return "Filters an image with a convolution kernel in real space.";
07052                 }
07053                 virtual TypeDict get_param_types() const
07054                 {
07055                         TypeDict d;
07056                         d.put("kernel", EMObject::FLOATARRAY, "the convolution kernel");
07057                         return d;
07058                 }
07059                 static const string NAME;       
07060         };
07061         
07062         class RotateInFSProcessor : public Processor
07063                 {
07064                 public:
07065                         //virtual EMData* process(const EMData* const image);
07066                         virtual void process_inplace(EMData * image);
07067                         virtual EMData* process(const EMData* const image);
07068 
07069                         virtual string get_name() const
07070                         {
07071                                 return NAME;
07072                         }
07073                         static Processor *NEW()
07074                         {
07075                                 return new RotateInFSProcessor( );
07076                         }
07077                         string get_desc() const
07078                         {
07079                                 return "Rotates a Fourier object using a kernel.";
07080                         }
07081                         virtual TypeDict get_param_types() const
07082                         {
07083                                 TypeDict d;     
07084                                 d.put("transform", EMObject::TRANSFORM, "transform");
07085                                 d.put("interpCutoff", EMObject::FLOAT, "cutoff for interpolation");
07086 //                              d.put("offset", EMObject::FLOAT, "offset for FT centering");
07087 //                              d.put("angle", EMObject::FLOAT, "angle");
07088                                 return d;
07089                         }
07090                         static const string NAME;
07091                 };
07092         
07093 #ifdef SPARX_USING_CUDA
07094         /* class MPI CUDA kmeans processor
07095          * 2009-02-13 17:34:45 JB first version
07096          * 2009-09-02 11:19:10 JB for MPI version
07097          * python wrap for GPU cluster
07098          */
07099         class MPICUDA_kmeans {
07100         public:
07101                 MPICUDA_kmeans();
07102                 ~MPICUDA_kmeans();
07103                 int setup(int extm, int extN, int extn, int extK, int extn_start);
07104                 void append_flat_image(EMData* im, int pos);
07105                 int init_mem(int numdev);
07106                 void compute_im2();
07107                 int random_ASG(long int rnd);
07108                 vector<int> get_ASG();
07109                 vector<int> get_asg();
07110                 void compute_NC();
07111                 vector<int> get_NC();
07112                 void set_ASG(const vector <int>& ASG);
07113                 void set_NC(const vector <int>& NC);
07114                 int get_ct_im_mv();
07115                 void set_T(float extT);
07116                 float get_T();
07117                 void compute_AVE();
07118                 void set_AVE(EMData* im, int pos);
07119                 vector<EMData*> get_AVE();
07120                 int one_iter();
07121                 //int one_iter_SSE();
07122                 //int AVE_to_host();
07123                 int one_iter_SA();
07124                 vector<float> compute_ji();
07125                 vector<float> compute_criterion(const vector <float>& Ji);
07126                 int shutdown();
07127         private:
07128                 // params
07129                 int m;
07130                 int N;
07131                 int n;
07132                 int K;
07133                 int nb_part;
07134                 int n_start;
07135                 int size_im;
07136                 int size_IM;
07137                 int size_AVE;
07138                 int size_dist;
07139                 int BLOCK_SIZE;
07140                 int NB;
07141                 int ins_BLOCK;
07142                 int ite;
07143                 float T;
07144                 // debug
07145                 int ct_im_mv;
07146                 // host memory
07147                 float* h_IM;
07148                 float* h_im;
07149                 float* h_AVE;
07150                 float* h_dist;
07151                 float* h_AVE2;
07152                 float* h_im2;
07153                 unsigned short int* h_ASG;
07154                 unsigned short int* h_asg;
07155                 unsigned int* h_NC;
07156                 int* params;
07157                 float ttt;
07158                 // device memory
07159                 float* d_im;
07160                 float* d_AVE;
07161                 float* d_dist;
07162                 //int init_dist(); // intial h_dist and d_dist for SSE
07163                 float compute_tt();
07164         };
07165 
07166 #endif //EMAN2_USING_CUDA
07167 
07168 #if 0
07169 
07170         class XYZProcessor:public Processor
07171         {
07172           public:
07173                 void process_inplace(EMData * image);
07174 
07175                 string get_name() const
07176                 {
07177                         return NAME;
07178                 }
07179 
07180                 static Processor *NEW()
07181                 {
07182                         return new XYZProcessor();
07183                 }
07184 
07185                 string get_desc() const
07186                 {
07187                         return "N/A";
07188                 }
07189 
07190                 TypeDict get_param_types() const
07191                 {
07192                         TypeDict d;
07193                         return d;
07194                 }
07195 
07196                 static const string NAME;
07197         };
07198 
07199 
07200 #endif
07201 
07202 
07203 #if 0
07204 
07205         class XYZProcessor:public Processor
07206         {
07207           public:
07208                 void process_inplace(EMData * image);
07209 
07210                 string get_name() const
07211                 {
07212                         return NAME;
07213                 }
07214 
07215                 static Processor *NEW()
07216                 {
07217                         return new XYZProcessor();
07218                 }
07219 
07220                 string get_desc() const
07221                 {
07222                         return "N/A";
07223                 }
07224 
07225                 TypeDict get_param_types() const
07226                 {
07227                         TypeDict d;
07228                         return d;
07229                 }
07230 
07231                 static const string NAME;
07232         };
07233 
07234 
07235 #endif
07236 
07237 
07238         int multi_processors(EMData * image, vector < string > processornames);
07239         void dump_processors();
07240         map<string, vector<string> > dump_processors_list();
07241         map<string, vector<string> > group_processors();
07242 
07243         template <> Factory < Processor >::Factory();
07244 }
07245 
07246 #endif  //eman_filter_h__
07247 
07248 /* vim: set ts=4 noet: */
07249 

Generated on Fri Aug 10 16:32:25 2012 for EMAN2 by  doxygen 1.4.7