00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef eman_processor_h__
00037 #define eman_processor_h__ 1
00038
00039 #include "emobject.h"
00040 #include "util.h"
00041 #include "geometry.h"
00042 #include "transform.h"
00043 #include "emdata.h"
00044 #include "gorgon/skeletonizer.h"
00045
00046 #include <cfloat>
00047 #include <climits>
00048 #include <cstring>
00049
00050 using std::vector;
00051 using std::map;
00052 using std::string;
00053
00054 namespace EMAN
00055 {
00056 class EMData;
00057
00093 class Processor
00094 {
00095 public:
00096 virtual ~ Processor()
00097 {
00098 }
00099
00105 virtual void process_inplace(EMData *image) = 0;
00106
00113 virtual EMData* process(const EMData * const image);
00114
00118 virtual void process_list_inplace(vector < EMData * > & images)
00119 {
00120 for (size_t i = 0; i < images.size(); i++) {
00121 process_inplace(images[i]);
00122 }
00123 }
00124
00128 virtual string get_name() const = 0;
00129
00133 virtual Dict get_params() const
00134 {
00135 return params;
00136 }
00137
00141 virtual void set_params(const Dict & new_params)
00142 {
00143 params = new_params;
00144 }
00145
00152 virtual TypeDict get_param_types() const
00153 {
00154 return TypeDict();
00155 }
00156
00163 static string get_group_desc()
00164 {
00165 return "EMAN processors are in-place image processors. You may apply a processor to process a single image or process multiple images. Processor class is the base class for all processor. <br> \
00166 The basic design of EMAN Processors: <br>\
00167 1) Each Processor class defines an image-processinging algorithm. <br>\
00168 2) All the Processor classes in EMAN are managed by a Factory pattern. So each Processor class must define: <br> a) a unique name to idenfity itself in the factory. <br>b) a static method to register itself in the factory.<br>\
00169 3) Each Processor class defines its own parameter set.<br>\
00170 4) Each Processor class defines functions to return its documentation including parameter information, and processor description. These functions enable EMAN to generate processor manuals dynamically.";
00171 }
00172
00178 virtual string get_desc() const = 0;
00179
00186 enum fourier_filter_types {
00187 TOP_HAT_LOW_PASS,
00188 TOP_HAT_HIGH_PASS,
00189 TOP_HAT_BAND_PASS,
00190 TOP_HOMOMORPHIC,
00191 GAUSS_LOW_PASS,
00192 GAUSS_HIGH_PASS,
00193 GAUSS_BAND_PASS,
00194 GAUSS_INVERSE,
00195 GAUSS_HOMOMORPHIC,
00196 BUTTERWORTH_LOW_PASS,
00197 BUTTERWORTH_HIGH_PASS,
00198 BUTTERWORTH_HOMOMORPHIC,
00199 KAISER_I0,
00200 KAISER_SINH,
00201 KAISER_I0_INVERSE,
00202 KAISER_SINH_INVERSE,
00203 SHIFT,
00204 TANH_LOW_PASS,
00205 TANH_HIGH_PASS,
00206 TANH_HOMOMORPHIC,
00207 TANH_BAND_PASS,
00208 RADIAL_TABLE,
00209 CTF_,
00210 };
00211
00236 static void
00237 EMFourierFilterInPlace(EMData* fimage, Dict params) {
00238 bool doInPlace = true;
00239 EMFourierFilterFunc(fimage, params, doInPlace);
00240 }
00241
00267 static EMData*
00268 EMFourierFilter(EMData* fimage, Dict params) {
00269 bool doInPlace = false;
00270 return EMFourierFilterFunc(fimage, params, doInPlace);
00271 }
00272
00273 private:
00309 static EMData*
00310 EMFourierFilterFunc(EMData* fimage, Dict params, bool doInPlace=true);
00311
00312 protected:
00313 mutable Dict params;
00314 };
00315
00316 class ImageProcessor:public Processor
00317 {
00318 public:
00319 void process_inplace(EMData * image);
00320
00321 static string get_group_desc()
00322 {
00323 return "An Image Processor defines a way to create a processor image. The processor image is used to multiply the input-image in the fourier space. ImageFilter class is the base class. Each specific ImageFilter class must define function create_processor_image(). ";
00324 }
00325
00326 protected:
00327 virtual EMData * create_processor_image() const = 0;
00328 };
00329
00336 class FourierProcessor:public Processor
00337 {
00338 public:
00339 void process_inplace(EMData * image);
00340
00341 static string get_group_desc()
00342 {
00343 return "Fourier Filter processors are a group of processor in the frequency domain. Before using such processors on an image, the image must be transformed from real space to the fourier space. FourierProcessor class is the base class of fourier space processors. Each specific processor is either a lowpass filter processor, or a highpass filter processor, or neighter. The unit of lowpass and highpass parameters are in terms of Nyquist, valid range is [0,0.5]. ";
00344 }
00345
00346 TypeDict get_param_types() const
00347 {
00348 TypeDict d;
00349 d.put("cutoff_abs", EMObject::FLOAT, "Processor radius in terms of Nyquist (0-.5)");
00350 d.put("cutoff_pixels", EMObject::FLOAT, " Width in Fourier pixels (0 - size()/2)");
00351 d.put("cutoff_freq", EMObject::FLOAT, "Resolution in 1/A (0 - 1 / size*apix)");
00352 d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
00353 return d;
00354 }
00355
00356 protected:
00357 virtual void preprocess(EMData * image) {}
00358 virtual void create_radial_func(vector < float >&radial_mask) const = 0;
00359 };
00360
00368 class FourierAnlProcessor:public Processor
00369 {
00370 public:
00371 void process_inplace(EMData * image);
00372
00373 static string get_group_desc()
00374 {
00375 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]. ";
00376 }
00377
00378 TypeDict get_param_types() const
00379 {
00380 TypeDict d;
00381 d.put("cutoff_abs", EMObject::FLOAT, "Processor radius in terms of Nyquist (0-.5)");
00382 d.put("cutoff_pixels", EMObject::FLOAT, " Width in Fourier pixels (0 - size()/2)");
00383 d.put("cutoff_freq", EMObject::FLOAT, "Resolution in 1/A (0 - 1 / size*apix)");
00384 d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
00385 return d;
00386 }
00387
00388 protected:
00389 virtual void preprocess(EMData * image) {}
00390 virtual void create_radial_func(vector < float >&radial_mask,EMData *image) const = 0;
00391 };
00392
00395 class SNREvalProcessor:public Processor
00396 {
00397 public:
00398 string get_name() const
00399 {
00400 return NAME;
00401 }
00402
00403 void process_inplace(EMData * image);
00404
00405 void set_params(const Dict & new_params)
00406 {
00407 params = new_params;
00408
00409
00410
00411 }
00412
00413 TypeDict get_param_types() const
00414 {
00415 TypeDict d;
00416
00417
00418 return d;
00419 }
00420
00421 static Processor *NEW()
00422 {
00423 return new SNREvalProcessor();
00424 }
00425
00426 string get_desc() const
00427 {
00428 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";
00429 }
00430
00431 static const string NAME;
00432
00433 protected:
00434 EMData *sum;
00435 int dosqrt;
00436 };
00437
00438
00443 class AmpweightFourierProcessor:public Processor
00444 {
00445 public:
00446 string get_name() const
00447 {
00448 return NAME;
00449 }
00450
00451 void process_inplace(EMData * image);
00452
00453 void set_params(const Dict & new_params)
00454 {
00455 params = new_params;
00456 sum = params["sum"];
00457 dosqrt = params["sqrt"];
00458
00459 }
00460
00461 TypeDict get_param_types() const
00462 {
00463 TypeDict d;
00464 d.put("sum", EMObject::EMDATA, "Adds the weights to sum for normalization");
00465 d.put("sqrt", EMObject::INT, "Weights using sqrt of the amplitude if set");
00466 return d;
00467 }
00468
00469 static Processor *NEW()
00470 {
00471 return new AmpweightFourierProcessor();
00472 }
00473
00474 string get_desc() const
00475 {
00476 return "Multiplies each Fourier pixel by its amplitude";
00477 }
00478
00479 static const string NAME;
00480
00481 protected:
00482 EMData *sum;
00483 int dosqrt;
00484 };
00491 class ConvolutionProcessor : public Processor
00492 {
00493 public:
00494 ConvolutionProcessor() {}
00495
00496 string get_name() const
00497 {
00498 return NAME;
00499 }
00500
00501 void process_inplace(EMData *image);
00502
00503 static Processor *NEW()
00504 {
00505 return new ConvolutionProcessor();
00506 }
00507
00508 string get_desc() const
00509 {
00510 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.";
00511 }
00512
00513 TypeDict get_param_types() const
00514 {
00515 TypeDict d;
00516 d.put("with", EMObject::EMDATA, "The image that will convolute the other image");
00517 return d;
00518 }
00519
00520 static const string NAME;
00521 };
00522
00529 class XGradientProcessor : public Processor
00530 {
00531 public:
00532 XGradientProcessor() {}
00533
00534 string get_name() const
00535 {
00536 return NAME;
00537 }
00538
00539 void process_inplace(EMData *image);
00540
00541 static Processor *NEW()
00542 {
00543 return new XGradientProcessor();
00544 }
00545
00546 string get_desc() const
00547 {
00548 return "Determines the image gradient in the x direction";
00549 }
00550
00551 TypeDict get_param_types() const
00552 {
00553 TypeDict d;
00554 return d;
00555 }
00556
00557 static const string NAME;
00558 };
00559
00560 class YGradientProcessor : public Processor
00561 {
00562 public:
00563 YGradientProcessor() {}
00564
00565 string get_name() const
00566 {
00567 return NAME;
00568 }
00569
00570 void process_inplace(EMData *image);
00571
00572 static Processor *NEW()
00573 {
00574 return new YGradientProcessor();
00575 }
00576
00577 string get_desc() const
00578 {
00579 return "Determines the image gradient in the y direction";
00580 }
00581
00582
00583 TypeDict get_param_types() const
00584 {
00585 TypeDict d;
00586 return d;
00587 }
00588
00589 static const string NAME;
00590 };
00591
00592 class ZGradientProcessor : public Processor
00593 {
00594 public:
00595 ZGradientProcessor() {}
00596
00597 string get_name() const
00598 {
00599 return NAME;
00600 }
00601
00602 void process_inplace(EMData *image);
00603
00604 static Processor *NEW()
00605 {
00606 return new ZGradientProcessor();
00607 }
00608
00609 string get_desc() const
00610 {
00611 return "Determines the image gradient in the z direction";
00612 }
00613
00614 TypeDict get_param_types() const
00615 {
00616 TypeDict d;
00617 return d;
00618 }
00619
00620 static const string NAME;
00621 };
00622
00631 class Wiener2DAutoAreaProcessor:public Processor
00632 {
00633 public:
00634 string get_name() const
00635 {
00636 return NAME;
00637 }
00638
00639 virtual EMData* process(const EMData * const image);
00640
00641 void process_inplace(EMData *image);
00642
00643 void set_params(const Dict & new_params)
00644 {
00645 params = new_params;
00646 bgsize = params["size"];
00647
00648 }
00649
00650 TypeDict get_param_types() const
00651 {
00652 TypeDict d;
00653 d.put("size", EMObject::INT, "Size in pixels of the boxes to chop the image into");
00654 return d;
00655 }
00656
00657 static Processor *NEW()
00658 {
00659 return new Wiener2DAutoAreaProcessor();
00660 }
00661
00662 string get_desc() const
00663 {
00664 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";
00665 }
00666
00667 static const string NAME;
00668
00669 protected:
00670 int bgsize;
00671 };
00672
00679 class KmeansSegmentProcessor:public Processor
00680 {
00681 public:
00682 string get_name() const
00683 {
00684 return NAME;
00685 }
00686
00687 virtual EMData* process(const EMData * const image);
00688 void process_inplace( EMData * image);
00689
00690 TypeDict get_param_types() const
00691 {
00692 TypeDict d ;
00693 d.put("nseg", EMObject::INT, "Number of segments to divide the image into. default=12" );
00694 d.put("thr",EMObject::FLOAT,"Isosurface threshold value. Pixels below this will not be segmented");
00695 d.put("ampweight",EMObject::INT,"If set, will weight centers by voxel amplitude. default = 1");
00696 d.put("maxsegsize",EMObject::FLOAT,"Maximum radial distance from segment center to member voxel. Default=10000");
00697 d.put("minsegsep",EMObject::FLOAT,"Minimum segment separation. Segments too close will trigger a reseed");
00698 d.put("maxiter",EMObject::FLOAT,"Maximum number of iterations to run before stopping. Default=100");
00699 d.put("maxvoxmove",EMObject::FLOAT,"Maximum number of voxels that can move before quitting. Default=25");
00700 d.put("verbose",EMObject::INT,"Be verbose while running");
00701 return d;
00702 }
00703
00704 static Processor *NEW()
00705 {
00706 return new KmeansSegmentProcessor();
00707 }
00708
00709 string get_desc() const
00710 {
00711 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.";
00712 }
00713
00714 static const string NAME;
00715
00716 };
00717
00718
00725 class Wiener2DFourierProcessor:public Processor
00726 {
00727 public:
00728 string get_name() const
00729 {
00730 return NAME;
00731 }
00732
00733 virtual EMData* process(const EMData * const image);
00734
00735 void process_inplace(EMData *image);
00736
00737 void set_params(const Dict & new_params)
00738 {
00739 params = new_params;
00740 ctf = params["ctf"];
00741
00742 }
00743
00744 TypeDict get_param_types() const
00745 {
00746 TypeDict d;
00747 d.put("ctf", EMObject::EMDATA, "Ctf object to use for Wiener filter parameters");
00748 return d;
00749 }
00750
00751 static Processor *NEW()
00752 {
00753 return new Wiener2DFourierProcessor();
00754 }
00755
00756 string get_desc() const
00757 {
00758 return "Applies a 2-D Wiener filter to an image based on its Ctf parameters";
00759 }
00760
00761 static const string NAME;
00762
00763 protected:
00764 Ctf *ctf;
00765 };
00766
00770 class LowpassFourierProcessor:public FourierProcessor
00771 {
00772 public:
00773 LowpassFourierProcessor():lowpass(0)
00774 {
00775 }
00776
00777 void set_params(const Dict & new_params)
00778 {
00779 params = new_params;
00780 if( params.has_key("lowpass") ) {
00781 lowpass = params["lowpass"];
00782 }
00783
00784 }
00785
00786 TypeDict get_param_types() const
00787 {
00788 TypeDict d = FourierProcessor::get_param_types();
00789 d.put("lowpass", EMObject::FLOAT, "Processor radius in terms of Nyquist (0-.5)");
00790 return d;
00791 }
00792
00793 static string get_group_desc()
00794 {
00795 return "Low-pass processor attenuates amplitudes at high spatial frequencies. It has the result of blurring the image, and of eliminating sharp edges and noise. The base class for all low pass fourier processors.";
00796 }
00797
00798 protected:
00799 virtual void preprocess(EMData * image);
00800 float lowpass;
00801 };
00802
00803 class LinearRampFourierProcessor:public FourierProcessor
00804 {
00805 public:
00806 virtual string get_name() const
00807 {
00808 return NAME;
00809 }
00810
00811 virtual string get_desc() const
00812 {
00813 return "";
00814 }
00815
00816 static Processor *NEW()
00817 {
00818 return new LinearRampFourierProcessor();
00819 }
00820
00821 static const string NAME;
00822
00823 protected:
00824 virtual void create_radial_func(vector < float >&radial_mask) const ;
00825 };
00826
00830 class HighpassFourierProcessor:public FourierProcessor
00831 {
00832 public:
00833 HighpassFourierProcessor():highpass(0)
00834 {
00835 }
00836
00837 void set_params(const Dict & new_params)
00838 {
00839 params = new_params;
00840 if( params.has_key("highpass") ) {
00841 highpass = params["highpass"];
00842 }
00843 }
00844
00845 TypeDict get_param_types() const
00846 {
00847 TypeDict d = FourierProcessor::get_param_types();
00848 d.put("highpass", EMObject::FLOAT, "Processor radius in terms of Nyquist (0-.5)");
00849 return d;
00850 }
00851
00852 static string get_group_desc()
00853 {
00854 return "High-pass processor is rotationally symmetric 2D function. It attenuates amplitudes at low spatial frequencies, and increases amplitudes for high spatial frequencies. It has the result of enhancing the edges in the image while suppressing all slow-moving variations. <br> HighpassFourierProcessor class is the base class for all high pass fourier processors.";
00855 }
00856
00857 protected:
00858 virtual void preprocess(EMData * image);
00859 float highpass;
00860 };
00861
00864 class LowpassSharpCutoffProcessor:public LowpassFourierProcessor
00865 {
00866 public:
00867 string get_name() const
00868 {
00869 return NAME;
00870 }
00871
00872 static Processor *NEW()
00873 {
00874 return new LowpassSharpCutoffProcessor();
00875 }
00876
00877 string get_desc() const
00878 {
00879 return "processor radial function: if x <= lowpass, f(x) = 1; else f(x) = 0;";
00880 }
00881
00882 static const string NAME;
00883
00884 protected:
00885 void create_radial_func(vector < float >&radial_mask) const;
00886 };
00887
00890 class HighpassSharpCutoffProcessor:public HighpassFourierProcessor
00891 {
00892 public:
00893 string get_name() const
00894 {
00895 return NAME;
00896 }
00897
00898 static Processor *NEW()
00899 {
00900 return new HighpassSharpCutoffProcessor();
00901 }
00902
00903 string get_desc() const
00904 {
00905 return "processor radial function: if x >= highpass, f(x) = 1; else f(x) = 0;";
00906 }
00907
00908 static const string NAME;
00909
00910 protected:
00911 void create_radial_func(vector < float >&radial_mask) const;
00912 };
00913
00916 class LowpassGaussProcessor:public LowpassFourierProcessor
00917 {
00918 public:
00919 string get_name() const
00920 {
00921 return NAME;
00922 }
00923
00924 static Processor *NEW()
00925 {
00926 return new LowpassGaussProcessor();
00927 }
00928
00929 string get_desc() const
00930 {
00931 return "processor radial function: if lowpass > 0, f(x) = exp(-x*x/(lowpass*lowpass)); else f(x) = exp(x*x/(lowpass*lowpass));";
00932 }
00933
00934 static const string NAME;
00935
00936 protected:
00937 void create_radial_func(vector < float >&radial_mask) const;
00938 };
00939
00942 class LowpassAutoBProcessor:public FourierAnlProcessor
00943 {
00944 public:
00945 string get_name() const
00946 {
00947 return NAME;
00948 }
00949
00950 static Processor *NEW()
00951 {
00952 return new LowpassAutoBProcessor();
00953 }
00954
00955 string get_desc() const
00956 {
00957 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.";
00958 }
00959
00960 static const string NAME;
00961
00962 virtual TypeDict get_param_types() const
00963 {
00964 TypeDict d = FourierAnlProcessor::get_param_types();
00965 d.put("bfactor", EMObject::FLOAT, "B-factor in terms of e^-(B s^2/4)");
00966 d.put("noisecutoff", EMObject::FLOAT, "Spatial frequency past which inverse-B will not be applied");
00967
00968 d.put("verbose", EMObject::INT, "Print information about the determined B-factor");
00969 return d;
00970 }
00971
00972 protected:
00973 virtual void preprocess(EMData * image) {
00974 if(params.has_key("apix")) {
00975 image->set_attr("apix_x", (float)params["apix"]);
00976 image->set_attr("apix_y", (float)params["apix"]);
00977 image->set_attr("apix_z", (float)params["apix"]);
00978 }
00979 float apix=(float)image->get_attr("apix_x");
00980
00981 const Dict dict = image->get_attr_dict();
00982 if (params.has_key("cutoff_abs")) {
00983 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00984 }
00985 else if( params.has_key("cutoff_freq") ) {
00986 float val = (float)params["cutoff_freq"] * apix;
00987 params["cutoff_abs"] = val;
00988 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00989 }
00990 else if( params.has_key("cutoff_pixels") ) {
00991 float val = 0.5f*(float)params["cutoff_pixels"] / (float)dict["nx"];
00992 params["cutoff_abs"] = val;
00993 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00994 }
00995 }
00996
00997 void create_radial_func(vector < float >&radial_mask,EMData *image) const;
00998 };
00999
01002 class HighpassAutoPeakProcessor:public FourierAnlProcessor
01003 {
01004 public:
01005 string get_name() const
01006 {
01007 return NAME;
01008 }
01009 static Processor *NEW()
01010 {
01011 return new HighpassAutoPeakProcessor();
01012 }
01013
01014 string get_desc() const
01015 {
01016 return "Attempts to automatically remove the low resolution peak present in virtually all cryoEM data.";
01017 }
01018
01019 static const string NAME;
01020
01021 protected:
01022 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
01023 virtual void preprocess(EMData * image);
01024 float highpass;
01025 };
01026
01027
01030 class HighpassGaussProcessor:public HighpassFourierProcessor
01031 {
01032 public:
01033 string get_name() const
01034 {
01035 return NAME;
01036 }
01037 static Processor *NEW()
01038 {
01039 return new HighpassGaussProcessor();
01040 }
01041
01042 string get_desc() const
01043 {
01044 return "processor radial function: f(x) = 1.0-exp(-x*x/(highpass*highpass);";
01045 }
01046
01047 static const string NAME;
01048
01049 protected:
01050 void create_radial_func(vector < float >&radial_mask) const;
01051 };
01052
01055 class LowpassTanhProcessor:public LowpassFourierProcessor
01056 {
01057 public:
01058 string get_name() const
01059 {
01060 return NAME;
01061 }
01062 static Processor *NEW()
01063 {
01064 return new LowpassTanhProcessor();
01065 }
01066
01067 string get_desc() const
01068 {
01069 return "processor radial function: f(x)=tanh(lowpass-x)/2.0 + 0.5;";
01070 }
01071
01072 static const string NAME;
01073
01074 protected:
01075 void create_radial_func(vector < float >&radial_mask) const;
01076 };
01077
01078
01081 class HighpassTanhProcessor:public HighpassFourierProcessor
01082 {
01083 public:
01084 string get_name() const
01085 {
01086 return NAME;
01087 }
01088 static Processor *NEW()
01089 {
01090 return new HighpassTanhProcessor();
01091 }
01092
01093 string get_desc() const
01094 {
01095 return "processor radial function: f(x)=tanh(x-highpass)/2.0+0.5;";
01096 }
01097
01098 static const string NAME;
01099
01100 protected:
01101 void create_radial_func(vector < float >&radial_mask) const;
01102 };
01103
01106 class HighpassButterworthProcessor:public HighpassFourierProcessor
01107 {
01108 public:
01109 string get_name() const
01110 {
01111 return NAME;
01112 }
01113 static Processor *NEW()
01114 {
01115 return new HighpassButterworthProcessor();
01116 }
01117
01118 string get_desc() const
01119 {
01120 return "processor radial function: f(x) = 1/(1+t*t);";
01121 }
01122
01123 static const string NAME;
01124
01125 protected:
01126 void create_radial_func(vector < float >&radial_mask) const;
01127 };
01128
01133 class LinearRampProcessor:public FourierProcessor
01134 {
01135 public:
01136 LinearRampProcessor():intercept(0), slope(0)
01137 {
01138 }
01139
01140 string get_name() const
01141 {
01142 return NAME;
01143 }
01144 static Processor *NEW()
01145 {
01146 return new LinearRampProcessor();
01147 }
01148
01149 string get_desc() const
01150 {
01151 return "processor radial function: f(x) = slope * x + intercept;";
01152 }
01153
01154 void set_params(const Dict & new_params)
01155 {
01156 params = new_params;
01157 intercept = params["intercept"];
01158 slope = params["slope"];
01159 }
01160
01161 TypeDict get_param_types() const
01162 {
01163 TypeDict d;
01164 d.put("intercept", EMObject::FLOAT, "intercept in 'f(x) = slope * x + intercept'");
01165 d.put("slope", EMObject::FLOAT, "slope in 'f(x) = slope * x + intercept'");
01166 return d;
01167 }
01168
01169 static const string NAME;
01170
01171 protected:
01172 void create_radial_func(vector < float >&radial_mask) const;
01173
01174 private:
01175 float intercept;
01176 float slope;
01177 };
01178
01181 class RealPixelProcessor:public Processor
01182 {
01183 public:
01184 RealPixelProcessor():value(0), maxval(1), mean(0), sigma(0)
01185 {
01186 }
01187 void process_inplace(EMData * image);
01188
01189 virtual void set_params(const Dict & new_params)
01190 {
01191 params = new_params;
01192 if (params.size() == 1) {
01193 vector < EMObject > dict_values = params.values();
01194 value = dict_values[0];
01195 }
01196 }
01197
01198 static string get_group_desc()
01199 {
01200 return "The base class for real space processor working on individual pixels. The processor won't consider the pixel's coordinates and neighbors.";
01201 }
01202
01203 protected:
01204 virtual void process_pixel(float *x) const = 0;
01205 virtual void calc_locals(EMData *)
01206 {
01207 }
01208 virtual void normalize(EMData *) const
01209 {
01210 }
01211
01212 float value;
01213 float maxval;
01214 float mean;
01215 float sigma;
01216 };
01217
01220 class AbsoluateValueProcessor:public RealPixelProcessor
01221 {
01222 public:
01223 string get_name() const
01224 {
01225 return NAME;
01226 }
01227 static Processor *NEW()
01228 {
01229 return new AbsoluateValueProcessor();
01230 }
01231
01232 static const string NAME;
01233
01234 protected:
01235 void process_pixel(float *x) const
01236 {
01237 *x = fabs(*x);
01238 }
01239
01240 string get_desc() const
01241 {
01242 return "f(x) = |x|";
01243 }
01244 };
01245
01246
01249 class BooleanProcessor:public RealPixelProcessor
01250 {
01251 public:
01252 string get_name() const
01253 {
01254 return NAME;
01255 }
01256 static Processor *NEW()
01257 {
01258 return new BooleanProcessor();
01259 }
01260
01261 string get_desc() const
01262 {
01263 return "f(x) = 0 if x = 0; f(x) = 1 if x != 0;";
01264 }
01265
01266 static const string NAME;
01267
01268 protected:
01269 void process_pixel(float *x) const
01270 {
01271 if (*x != 0)
01272 {
01273 *x = 1.0;
01274 }
01275 }
01276 };
01277
01281 class InvertCarefullyProcessor:public RealPixelProcessor
01282 {
01283 public:
01284 string get_name() const
01285 {
01286 return NAME;
01287 }
01288 static Processor *NEW()
01289 {
01290 return new InvertCarefullyProcessor();
01291 }
01292
01293 void set_params(const Dict & new_params)
01294 {
01295 params = new_params;
01296 zero_to = params.set_default("zero_to",0.0f);
01297 }
01298
01299 TypeDict get_param_types() const
01300 {
01301 TypeDict d;
01302 d.put("zero_to", EMObject::FLOAT, "Inverted zero values are set to this value, default is 0.");
01303 return d;
01304 }
01305
01306 string get_desc() const
01307 {
01308 return "if f(x) != 0: f(x) = 1/f(x) else: f(x) = zero_to";
01309 }
01310
01311 static const string NAME;
01312
01313 protected:
01314 void process_pixel(float *x) const
01315 {
01316 if (*x == 0) *x = zero_to;
01317 else *x = 1/(*x);
01318 }
01319 private:
01320 float zero_to;
01321 };
01322
01326 class ValuePowProcessor:public RealPixelProcessor
01327 {
01328 public:
01329 string get_name() const
01330 {
01331 return NAME;
01332 }
01333 static Processor *NEW()
01334 {
01335 return new ValuePowProcessor();
01336 }
01337
01338 void set_params(const Dict & new_params)
01339 {
01340 params = new_params;
01341 pwr = params["pow"];
01342 }
01343
01344 TypeDict get_param_types() const
01345 {
01346 TypeDict d;
01347 d.put("pow", EMObject::FLOAT, "Each pixel is raised to this power");
01348 return d;
01349 }
01350
01351 string get_desc() const
01352 {
01353 return "f(x) = x ^ pow;";
01354 }
01355
01356 static const string NAME;
01357
01358 protected:
01359 void process_pixel(float *x) const
01360 {
01361 if (*x<0 && pwr!=(int)pwr) *x=0;
01362 else (*x) = pow(*x,pwr);
01363 }
01364 private:
01365 float pwr;
01366 };
01367
01370 class ValueSquaredProcessor:public RealPixelProcessor
01371 {
01372 public:
01373 string get_name() const
01374 {
01375 return NAME;
01376 }
01377 static Processor *NEW()
01378 {
01379 return new ValueSquaredProcessor();
01380 }
01381
01382
01383 string get_desc() const
01384 {
01385 return "f(x) = x * x;";
01386 }
01387
01388 static const string NAME;
01389
01390 protected:
01391 void process_pixel(float *x) const
01392 {
01393 (*x) *= (*x);
01394 }
01395 };
01396
01399 class ValueSqrtProcessor:public RealPixelProcessor
01400 {
01401 public:
01402 string get_name() const
01403 {
01404 return NAME;
01405 }
01406 static Processor *NEW()
01407 {
01408 return new ValueSqrtProcessor();
01409 }
01410
01411 string get_desc() const
01412 {
01413 return "f(x) = sqrt(x)";
01414 }
01415
01416 static const string NAME;
01417
01418 protected:
01419 void process_pixel(float *x) const
01420 {
01421 *x = sqrt(*x);
01422 }
01423 };
01424
01428 class ToZeroProcessor:public RealPixelProcessor
01429 {
01430 public:
01431 string get_name() const
01432 {
01433 return NAME;
01434 }
01435 static Processor *NEW()
01436 {
01437 return new ToZeroProcessor();
01438 }
01439 TypeDict get_param_types() const
01440 {
01441 TypeDict d;
01442 d.put("minval", EMObject::FLOAT, "Everything below this value is set to zero");
01443 return d;
01444 }
01445
01446 string get_desc() const
01447 {
01448 return "f(x) = x if x >= minval; f(x) = 0 if x < minval.";
01449 }
01450
01451 static const string NAME;
01452
01453 protected:
01454 inline void process_pixel(float *x) const
01455 {
01456 if (*x < value) {
01457 *x = 0;
01458 }
01459 }
01460 };
01461
01467 class Rotate180Processor:public Processor
01468 {
01469 public:
01470 string get_name() const
01471 {
01472 return NAME;
01473 }
01474 static Processor *NEW()
01475 {
01476 return new Rotate180Processor();
01477 }
01478
01482 void process_inplace(EMData* image);
01483
01484 string get_desc() const
01485 {
01486 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.";
01487 }
01488
01489 static const string NAME;
01490 };
01491
01498 class TransformProcessor:public Processor
01499 {
01500 public:
01501 virtual string get_name() const
01502 {
01503 return NAME;
01504 }
01505 static Processor *NEW()
01506 {
01507 return new TransformProcessor();
01508 }
01509
01514 virtual void process_inplace(EMData* image);
01515
01520 virtual EMData* process(const EMData* const image);
01521
01522 virtual TypeDict get_param_types() const
01523 {
01524 TypeDict d;
01525 d.put("transform", EMObject::TRANSFORM, "The Transform object that will be applied to the image" );
01526 return d;
01527 }
01528
01529 virtual string get_desc() const
01530 {
01531 return "The image is transformed using Transform parameter.";
01532 }
01533
01534 static const string NAME;
01535
01536 private:
01537 float* transform(const EMData* const image, const Transform& t) const;
01538
01539
01540
01541
01542 void assert_valid_aspect(const EMData* const image) const;
01543 };
01544
01552 class IntTranslateProcessor:public Processor
01553 {
01554 public:
01555 virtual string get_name() const
01556 {
01557 return NAME;
01558 }
01559
01560 static Processor *NEW()
01561 {
01562 return new IntTranslateProcessor();
01563 }
01564
01569 virtual void process_inplace(EMData* image);
01570
01575 virtual EMData* process(const EMData* const image);
01576
01577 virtual TypeDict get_param_types() const
01578 {
01579 TypeDict d;
01580 d.put("trans", EMObject::INTARRAY, "The displacement array, can be length 1-3" );
01581 return d;
01582 }
01583
01584 virtual string get_desc() const
01585 {
01586 return "The image is translated an integer amount";
01587 }
01588
01589 static const string NAME;
01590
01591 private:
01595 void assert_valid_aspect(const vector<int>& translation, const EMData* const image) const;
01596
01602 Region get_clip_region(vector<int>& translation, const EMData* const image) const;
01603 };
01604
01611 class ScaleTransformProcessor:public Processor
01612 {
01613 public:
01614 virtual string get_name() const
01615 {
01616 return NAME;
01617 }
01618 static Processor *NEW()
01619 {
01620 return new ScaleTransformProcessor();
01621 }
01622
01627 virtual void process_inplace(EMData* image);
01628
01633 virtual EMData* process(const EMData* const image);
01634
01635 virtual TypeDict get_param_types() const
01636 {
01637 TypeDict d;
01638 d.put("scale", EMObject::FLOAT, "The amount by which to scale" );
01639 d.put("clip", EMObject::INT, "The length of each output dimension. Non sophisticated, output dimensions can't be different" );
01642 return d;
01643 }
01644
01645 virtual string get_desc() const
01646 {
01647 return "The image is scaled with the clip variable in mind, being sure to preserve as much pixel information as possible.";
01648 }
01649
01650 static const string NAME;
01651 };
01652
01659 class ClampingProcessor :public Processor
01660 {
01661 public:
01662 ClampingProcessor() : default_max(1.0), default_min(0.0) {}
01663
01664 string get_name() const
01665 {
01666 return NAME;
01667 }
01668 static Processor *NEW()
01669 {
01670 return new ClampingProcessor();
01671 }
01672
01673 void process_inplace(EMData *image);
01674
01675 TypeDict get_param_types() const
01676 {
01677 TypeDict d;
01678 d.put("minval", EMObject::FLOAT, "The pixel values that bounds the smallest pixel value in the output image" );
01679 d.put("maxval", EMObject::FLOAT, "The pixel values that bounds the largest pixel value in the output image" );
01680 d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01681 return d;
01682 }
01683
01684 string get_desc() const
01685 {
01686 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.";
01687 }
01688
01689 static const string NAME;
01690
01691 protected:
01692 float default_max, default_min;
01693 };
01694
01700 class NSigmaClampingProcessor : public ClampingProcessor
01701 {
01702 public:
01703 NSigmaClampingProcessor() : default_sigma(2.0) {}
01704
01705 string get_name() const
01706 {
01707 return NAME;
01708 }
01709
01710 static Processor *NEW()
01711 {
01712 return new NSigmaClampingProcessor();
01713 }
01714
01715 TypeDict get_param_types() const
01716 {
01717 TypeDict d;
01718 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" );
01719 d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01720 return d;
01721 }
01722
01723 void process_inplace(EMData *image);
01724
01725 string get_desc() const
01726 {
01727 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.";
01728 }
01729
01730 static const string NAME;
01731
01732 protected:
01733 float default_sigma;
01734 };
01735
01739 class ToMinvalProcessor:public Processor
01740 {
01741 public:
01742 string get_name() const
01743 {
01744 return NAME;
01745 }
01746 static Processor *NEW()
01747 {
01748 return new ToMinvalProcessor();
01749 }
01750
01751 void process_inplace(EMData *image);
01752
01753 TypeDict get_param_types() const
01754 {
01755 TypeDict d;
01756 d.put("minval", EMObject::FLOAT, "Everything below this value is set to this value");
01757 d.put("newval", EMObject::FLOAT, "If set, values below minval will be set to newval instead of minval ");
01758 return d;
01759 }
01760
01761 string get_desc() const
01762 {
01763 return "f(x) = x if x >= minval; f(x) = minval|newval if x < minval.";
01764 }
01765
01766 static const string NAME;
01767
01768 protected:
01769
01770 };
01771
01772
01773
01777 class CutToZeroProcessor:public RealPixelProcessor
01778 {
01779 public:
01780 string get_name() const
01781 {
01782 return NAME;
01783 }
01784 static Processor *NEW()
01785 {
01786 return new CutToZeroProcessor();
01787 }
01788 TypeDict get_param_types() const
01789 {
01790 TypeDict d;
01791 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" );
01792 return d;
01793 }
01794
01795 string get_desc() const
01796 {
01797 return "f(x) = x-minval if x >= minval; f(x) = 0 if x < minval.";
01798 }
01799
01800 static const string NAME;
01801
01802 protected:
01803 void process_pixel(float *x) const
01804 {
01805 *x = *x - value;
01806 if (*x < 0) {
01807 *x = 0;
01808 }
01809 }
01810 };
01811
01815 class BinarizeProcessor:public RealPixelProcessor
01816 {
01817 public:
01818 string get_name() const
01819 {
01820 return NAME;
01821 }
01822 static Processor *NEW()
01823 {
01824 return new BinarizeProcessor();
01825 }
01826 TypeDict get_param_types() const
01827 {
01828 TypeDict d;
01829 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" );
01830 return d;
01831 }
01832
01833 string get_desc() const
01834 {
01835 return "f(x) = 0 if x < value; f(x) = 1 if x >= value.";
01836 }
01837
01838 static const string NAME;
01839
01840 protected:
01841 void process_pixel(float *x) const
01842 {
01843 if (*x < value)
01844 {
01845 *x = 0;
01846 }
01847 else
01848 {
01849 *x = 1;
01850 }
01851 }
01852 };
01853
01865 class BinarizeFourierProcessor:public Processor
01866 {
01867 public:
01868 virtual string get_name() const
01869 {
01870 return NAME;
01871 }
01872 static Processor *NEW()
01873 {
01874 return new BinarizeFourierProcessor();
01875 }
01876
01883 virtual void process_inplace(EMData* image);
01884
01885 virtual TypeDict get_param_types() const
01886 {
01887 TypeDict d;
01888 d.put("value", EMObject::FLOAT, "The Fourier amplitude threshold cutoff" );
01889 return d;
01890 }
01891
01892 virtual string get_desc() const
01893 {
01894 return "f(k) = 0 + 0i if ||f(k)|| < value; f(k) = 1 + 0i if ||f(k)|| >= value.";
01895 }
01896
01897 static const string NAME;
01898 };
01899
01904 class CollapseProcessor:public RealPixelProcessor
01905 {
01906 public:
01907 string get_name() const
01908 {
01909 return NAME;
01910 }
01911 static Processor *NEW()
01912 {
01913 return new CollapseProcessor();
01914 }
01915
01916 void set_params(const Dict & new_params)
01917 {
01918 params = new_params;
01919 range = params["range"];
01920 value = params["value"];
01921 }
01922
01923 TypeDict get_param_types() const
01924 {
01925 TypeDict d;
01926 d.put("range", EMObject::FLOAT, "The range about 'value' which will be collapsed to 'value'");
01927 d.put("value", EMObject::FLOAT, "The pixel value where the focus of the collapse operation is");
01928 return d;
01929 }
01930
01931 string get_desc() const
01932 {
01933 return "f(x): if v-r<x<v+r -> v; if x>v+r -> x-r; if x<v-r -> x+r";
01934 }
01935
01936 static const string NAME;
01937
01938 protected:
01939 void process_pixel(float *x) const
01940 {
01941 if (*x>value+range) *x-=range;
01942 else if (*x<value-range) *x+=range;
01943 else *x=value;
01944 }
01945 float range;
01946 };
01947
01952 class LinearXformProcessor:public RealPixelProcessor
01953 {
01954 public:
01955 LinearXformProcessor():shift(0), scale(0)
01956 {
01957 }
01958
01959 string get_name() const
01960 {
01961 return NAME;
01962 }
01963 static Processor *NEW()
01964 {
01965 return new LinearXformProcessor();
01966 }
01967
01968 void set_params(const Dict & new_params)
01969 {
01970 params = new_params;
01971 shift = params.get("shift");
01972 scale = params.get("scale");
01973 }
01974
01975 TypeDict get_param_types() const
01976 {
01977 TypeDict d;
01978 d.put("shift", EMObject::FLOAT, "The amount to shift pixel values by before scaling");
01979 d.put("scale", EMObject::FLOAT, "The scaling factor to be applied to pixel values");
01980 return d;
01981 }
01982
01983 string get_desc() const
01984 {
01985 return "linear transform processor: f(x) = x * scale + shift. This is equivalent to a regular contrast stretching operation";
01986 }
01987
01988 static const string NAME;
01989
01990 protected:
01991 void process_pixel(float *x) const
01992 {
01993 *x = (*x) * scale + shift;
01994 }
01995
01996 private:
01997 float shift;
01998 float scale;
01999 };
02000
02005 class ExpProcessor:public RealPixelProcessor
02006 {
02007 public:
02008 ExpProcessor():low(0), high(0)
02009 {
02010 }
02011
02012 string get_name() const
02013 {
02014 return NAME;
02015 }
02016
02017 static Processor *NEW()
02018 {
02019 return new ExpProcessor();
02020 }
02021
02022 void set_params(const Dict & new_params)
02023 {
02024 params = new_params;
02025 low = params.get("low");
02026 high = params.get("high");
02027 }
02028
02029 TypeDict get_param_types() const
02030 {
02031 TypeDict d;
02032 d.put("low", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
02033 d.put("high", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
02034 return d;
02035 }
02036
02037 string get_desc() const
02038 {
02039 return "f(x) = exp( x / low - high)";
02040 }
02041
02042 static const string NAME;
02043
02044 protected:
02048 void process_pixel(float *x) const
02049 {
02050 float v = *x / low - high;
02051 if (v > 40) {
02052 v = 40;
02053 }
02054 *x = exp(v);
02055 }
02056
02057 private:
02058 float low;
02059 float high;
02060 };
02061
02065 class FiniteProcessor:public RealPixelProcessor
02066 {
02067 public:
02068 FiniteProcessor():to(0)
02069 {
02070 }
02071
02072 string get_name() const
02073 {
02074 return NAME;
02075 }
02076
02077 static Processor *NEW()
02078 {
02079 return new FiniteProcessor();
02080 }
02081
02082 void set_params(const Dict & new_params)
02083 {
02084 if (new_params.has_key("to") )
02085 to = params["to"];
02086 }
02087
02088 TypeDict get_param_types() const
02089 {
02090 TypeDict d;
02091 d.put("to", EMObject::FLOAT, "Pixels which are not finite will be set to this value");
02092 return d;
02093 }
02094
02095 string get_desc() const
02096 {
02097 return "f(x) = f(x) if f(x) is finite | to if f(x) is not finite";
02098 }
02099
02100 static const string NAME;
02101
02102 protected:
02106 void process_pixel(float *x) const;
02107 private:
02108 float to;
02109 };
02110
02115 class RangeThresholdProcessor:public RealPixelProcessor
02116 {
02117 public:
02118 RangeThresholdProcessor():low(0), high(0)
02119 {
02120 }
02121
02122 string get_name() const
02123 {
02124 return NAME;
02125 }
02126 static Processor *NEW()
02127 {
02128 return new RangeThresholdProcessor();
02129 }
02130
02131 void set_params(const Dict & new_params)
02132 {
02133 params = new_params;
02134 low = params.get("low");
02135 high = params.get("high");
02136 }
02137
02138 TypeDict get_param_types() const
02139 {
02140 TypeDict d;
02141 d.put("low", EMObject::FLOAT, "The lower limit of the range that will be set to 1");
02142 d.put("high", EMObject::FLOAT, "The upper limit of the range that will be set to 1");
02143 return d;
02144 }
02145
02146 string get_desc() const
02147 {
02148 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";
02149 }
02150
02151 static const string NAME;
02152
02153 protected:
02154 void process_pixel(float *x) const
02155 {
02156 if (*x >= low && *x <= high) {
02157 *x = 1;
02158 }
02159 else {
02160 *x = 0;
02161 }
02162 }
02163 private:
02164 float low;
02165 float high;
02166
02167 };
02168
02173 class SigmaProcessor:public RealPixelProcessor
02174 {
02175 public:
02176 string get_name() const
02177 {
02178 return NAME;
02179 }
02180 static Processor *NEW()
02181 {
02182 return new SigmaProcessor();
02183 }
02184
02185 void set_params(const Dict & new_params)
02186 {
02187 params = new_params;
02188 value1 = params.get("value1");
02189 value2 = params.get("value2");
02190 }
02191
02192 TypeDict get_param_types() const
02193 {
02194 TypeDict d;
02195 d.put("value1", EMObject::FLOAT, "A number reflecting total standard deviations in the right direction");
02196 d.put("value2", EMObject::FLOAT, "A number reflecting total standard deviations in the left direction");
02197 return d;
02198 }
02199
02200 string get_desc() const
02201 {
02202 return "f(x) = mean if x<(mean-v2*sigma) or x>(mean+v1*sigma); else f(x) = x;";
02203 }
02204
02205 static const string NAME;
02206
02207 protected:
02208 void process_pixel(float *x) const
02209 {
02210 if (*x < (mean - value2 * sigma) || *x > (mean + value1 * sigma))
02211 {
02212 *x = mean;
02213 }
02214 }
02215
02216 private:
02217 float value1;
02218 float value2;
02219 };
02220
02223 class LogProcessor:public RealPixelProcessor
02224 {
02225 public:
02226 string get_name() const
02227 {
02228 return NAME;
02229 }
02230 static Processor *NEW()
02231 {
02232 return new LogProcessor();
02233 }
02234
02235 string get_desc() const
02236 {
02237 return "f(x) = log10(x) if x > 0; else f(x) = 0;";
02238 }
02239
02240 static const string NAME;
02241
02242 protected:
02243 void process_pixel(float *x) const
02244 {
02245 if (*x > 0)
02246 {
02247 *x = log10(*x);
02248 }
02249 else
02250 {
02251 *x = 0;
02252 }
02253 }
02254 };
02255
02258 class CoordinateProcessor:public Processor
02259 {
02260 public:
02261 CoordinateProcessor():nx(0), ny(0), nz(0), mean(0), sigma(0), maxval(0), is_complex(false)
02262 {
02263 }
02264 void process_inplace(EMData * image);
02265
02266 static string get_group_desc()
02267 {
02268 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().";
02269 }
02270
02271 protected:
02272 virtual void process_pixel(float *pixel, int xi, int yi, int zi) const = 0;
02273 virtual void calc_locals(EMData *)
02274 {
02275 }
02276 virtual bool is_valid() const
02277 {
02278 return true;
02279 }
02280
02281 int nx;
02282 int ny;
02283 int nz;
02284 float mean;
02285 float sigma;
02286 float maxval;
02287
02288 bool is_complex;
02289 };
02290
02298 class CircularMaskProcessor:public CoordinateProcessor
02299 {
02300 public:
02301 CircularMaskProcessor():inner_radius(0), outer_radius(0), inner_radius_square(0),
02302 outer_radius_square(0), dx(0), dy(0), dz(0), xc(0), yc(0), zc(0)
02303 {
02304 }
02305
02306 void set_params(const Dict & new_params)
02307 {
02308 params = new_params;
02309
02310 if (params.has_key("inner_radius")) {
02311 inner_radius = params["inner_radius"];
02312 inner_radius_square = inner_radius * inner_radius;
02313 }
02314 else {
02315 inner_radius = -1;
02316 inner_radius_square = -1;
02317 }
02318
02319 if (params.has_key("outer_radius")) {
02320 outer_radius = params["outer_radius"];
02321 outer_radius_square = outer_radius * outer_radius;
02322 }
02323 else {
02324 outer_radius = INT_MAX;
02325 outer_radius_square = INT_MAX;
02326 }
02327
02328 if (params.has_key("xc")) xc = params["xc"];
02329 if (params.has_key("yc")) yc = params["yc"];
02330 if (params.has_key("zc")) zc = params["zc"];
02331 if (params.has_key("dx")) dx = params["dx"];
02332 if (params.has_key("dy")) dy = params["dy"];
02333 if (params.has_key("dz")) dz = params["dz"];
02334 }
02335
02336 string get_desc() const
02337 {
02338 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().";
02339 }
02340
02341 TypeDict get_param_types() const
02342 {
02343 TypeDict d;
02344
02345 d.put("inner_radius", EMObject::INT, "inner mask radius. optional, default=-1");
02346 d.put("outer_radius", EMObject::INT, "outer mask radius");
02347
02348 d.put("dx", EMObject::FLOAT,
02349 "Modify mask center by dx relative to the default center nx/2");
02350 d.put("dy", EMObject::FLOAT,
02351 "Modify mask center by dy relative to the default center ny/2");
02352 d.put("dz", EMObject::FLOAT,
02353 "Modify mask center by dz relative to the default center nz/2");
02354
02355 return d;
02356 }
02357 protected:
02358 void calc_locals(EMData * image);
02359
02360 bool is_valid() const
02361 {
02362 return (!is_complex);
02363 }
02364
02365 void process_pixel(float *pixel, int xi, int yi, int zi) const
02366 {
02367 float dist = (xi - xc) * (xi - xc) + (yi - yc) * (yi - yc) + (zi - zc) * (zi - zc);
02368 process_dist_pixel(pixel, dist);
02369 }
02370
02371 virtual void process_dist_pixel(float *pixel, float dist) const = 0;
02372
02373 int inner_radius;
02374 int outer_radius;
02375 int inner_radius_square;
02376 int outer_radius_square;
02377 float dx, dy, dz;
02378 float xc, yc, zc;
02379 };
02380
02384 class MaskSharpProcessor:public CircularMaskProcessor
02385 {
02386 public:
02387 MaskSharpProcessor():value(0)
02388 {
02389 }
02390
02391 string get_name() const
02392 {
02393 return NAME;
02394 }
02395 static Processor *NEW()
02396 {
02397 return new MaskSharpProcessor();
02398 }
02399
02400 void set_params(const Dict & new_params)
02401 {
02402 CircularMaskProcessor::set_params(new_params);
02403 value = params.set_default("value",0.0f);
02404 }
02405
02406 TypeDict get_param_types() const
02407 {
02408 TypeDict d = CircularMaskProcessor::get_param_types();
02409 d.put("value", EMObject::FLOAT, "step cutoff to this value. Default is 0.");
02410 return d;
02411 }
02412
02413 string get_desc() const
02414 {
02415 return "step cutoff to a user-given value in both inner and outer circles.";
02416 }
02417
02418 static const string NAME;
02419
02420 protected:
02421 void process_dist_pixel(float *pixel, float dist) const
02422 {
02423 if (dist >= outer_radius_square || dist < inner_radius_square)
02424 {
02425 *pixel = value;
02426 }
02427 }
02428
02429 float value;
02430 };
02431
02432
02436 class MaskEdgeMeanProcessor:public CircularMaskProcessor
02437 {
02438 public:
02439 string get_name() const
02440 {
02441 return NAME;
02442 }
02443 static Processor *NEW()
02444 {
02445 return new MaskEdgeMeanProcessor();
02446 }
02447
02448 void set_params(const Dict & new_params)
02449 {
02450 CircularMaskProcessor::set_params(new_params);
02451 ring_width = params["ring_width"];
02452 if (ring_width == 0) {
02453 ring_width = 1;
02454 }
02455 }
02456
02457 TypeDict get_param_types() const
02458 {
02459 TypeDict d = CircularMaskProcessor::get_param_types();
02460 d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02461 return d;
02462 }
02463
02464 string get_desc() const
02465 {
02466 return "A step cutoff to the the mean value in a ring centered on the outer radius";
02467 }
02468
02469 static const string NAME;
02470
02471 protected:
02472 void calc_locals(EMData * image);
02473
02474
02475 void process_dist_pixel(float *pixel, float dist) const
02476 {
02477 if (dist >= outer_radius_square || dist < inner_radius_square){
02478 *pixel = ring_avg;
02479 }
02480 }
02481
02482 private:
02483 int ring_width;
02484 float ring_avg;
02485 };
02486
02489 class MaskNoiseProcessor:public CircularMaskProcessor
02490 {
02491 public:
02492 string get_name() const
02493 {
02494 return NAME;
02495 }
02496 static Processor *NEW()
02497 {
02498 return new MaskNoiseProcessor();
02499 }
02500
02501 string get_desc() const
02502 {
02503 return "fills masked region";
02504 }
02505
02506 static const string NAME;
02507
02508 protected:
02509 void process_dist_pixel(float *pixel, float dist) const
02510 {
02511 if (dist >= outer_radius_square || dist < inner_radius_square)
02512 {
02513 *pixel = Util::get_gauss_rand(mean, sigma);
02514 }
02515 }
02516 };
02517
02520 class MaskGaussProcessor:public CircularMaskProcessor
02521 {
02522 public:
02523 string get_name() const
02524 {
02525 return NAME;
02526 }
02527 static Processor *NEW()
02528 {
02529 return new MaskGaussProcessor();
02530 }
02531
02532 void set_params(const Dict & new_params)
02533 {
02534 CircularMaskProcessor::set_params(new_params);
02535 exponent = params["exponent"];
02536 if (exponent <= 0.0) {
02537 exponent = 2.0;
02538 }
02539 }
02540
02541 TypeDict get_param_types() const
02542 {
02543 TypeDict d = CircularMaskProcessor::get_param_types();
02544 d.put("exponent", EMObject::FLOAT, "The exponent, f in e^-Bs^f. default 2.0, producing a Gaussian");
02545 return d;
02546 }
02547
02548 string get_desc() const
02549 {
02550 return "a gaussian falloff to zero, radius is the 1/e of the width. If inner_radius>0, then \
02551 outer radius specifies width of Gaussian starting at inner_radius rather than total radius.";
02552 }
02553
02554 static const string NAME;
02555
02556 protected:
02557 float exponent;
02558 void process_dist_pixel(float *pixel, float dist) const
02559 {
02560 if (inner_radius_square>0) {
02561 if (dist>inner_radius_square) {
02562 if (exponent==2.0f) (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,2.0f) / outer_radius_square);
02563 else (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,exponent) / pow((float)outer_radius_square,exponent/2.0f));
02564 }
02565 }
02566 else {
02567 if (exponent==2.0f) (*pixel) *= exp(-dist / outer_radius_square);
02568 else (*pixel) *= exp(-pow(dist,exponent/2.0f) / pow((float)outer_radius_square,exponent/2.0f));
02569 }
02570 }
02571 };
02572
02579 class MaskGaussNonuniformProcessor:public CoordinateProcessor
02580 {
02581 public:
02582 MaskGaussNonuniformProcessor():radius_x(0), radius_y(0), radius_z(0), gauss_width(0)
02583 {
02584 }
02585
02586 void set_params(const Dict & new_params)
02587 {
02588 params = new_params;
02589
02590 if (params.has_key("radius_x")) radius_x=params["radius_x"];
02591 else radius_x=5.0;
02592
02593 if (params.has_key("radius_y")) radius_y=params["radius_y"];
02594 else radius_y=5.0;
02595
02596 if (params.has_key("radius_z")) radius_z=params["radius_z"];
02597 else radius_z=5.0;
02598
02599 if (params.has_key("gauss_width")) gauss_width=params["gauss_width"];
02600 else gauss_width=0.05f;
02601 }
02602
02603 TypeDict get_param_types() const
02604 {
02605 TypeDict d;
02606
02607 d.put("radius_x", EMObject::INT, "x-axis radius");
02608 d.put("radius_y", EMObject::INT, "y-axis radius");
02609 d.put("radius_z", EMObject::INT, "z-axis radius");
02610 d.put("gauss_width", EMObject::FLOAT, "Gaussian falloff width, relative to each radius, default 0.05");
02611
02612 return d;
02613 }
02614
02615 string get_name() const
02616 {
02617 return NAME;
02618 }
02619 static Processor *NEW()
02620 {
02621 return new MaskGaussNonuniformProcessor();
02622 }
02623
02624 string get_desc() const
02625 {
02626 return "A Gaussian falloff to zero. Nonisotropic, specify inner radius for x,y,z and Gaussian falloff width. Falloff \
02627 width is also nonisotropic and relative to the radii, with 1 being equal to the radius on that axis.";
02628 }
02629
02630 static const string NAME;
02631
02632 protected:
02633 void process_pixel(float *pixel, int xi, int yi, int zi) const
02634 {
02635 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);
02636 if (dist>1.0) (*pixel)*=exp(-pow((sqrt(dist)-1.0f)/gauss_width,2.0f));
02637 }
02638
02639 float radius_x,radius_y,radius_z,gauss_width;
02640 };
02641
02646 class MaskGaussInvProcessor:public CircularMaskProcessor
02647 {
02648 public:
02649 TypeDict get_param_types() const
02650 {
02651 TypeDict d = CircularMaskProcessor::get_param_types();
02652 d.put("gauss_width", EMObject::FLOAT, "Used to calculate the constant factor - gauss_width / (ny*ny)" );
02653 d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02654 return d;
02655 }
02656
02657 string get_name() const
02658 {
02659 return NAME;
02660 }
02661
02662 static Processor *NEW()
02663 {
02664 return new MaskGaussInvProcessor();
02665 }
02666
02667 string get_desc() const
02668 {
02669 return "f(x) = f(x) / exp(-radius*radius * gauss_width / (ny*ny))";
02670 }
02671
02672 static const string NAME;
02673
02674 protected:
02675 void calc_locals(EMData *)
02676 {
02677 float gauss_width = params["gauss_width"];
02678 slice_value = gauss_width / (ny * ny);
02679 }
02680
02681 void process_dist_pixel(float *pixel, float dist) const
02682 {
02683 (*pixel) /= exp(-dist * slice_value);
02684 }
02685 private:
02686 float slice_value;
02687 };
02688
02689
02694 class LinearPyramidProcessor:public Processor
02695 {
02696 public:
02697 string get_name() const
02698 {
02699 return NAME;
02700 }
02701
02702 void process_inplace(EMData *image);
02703
02704 static Processor *NEW()
02705 {
02706 return new LinearPyramidProcessor();
02707 }
02708
02709 string get_desc() const
02710 {
02711 return "Multiplies image by a 'linear pyramid', 1-(|x-xsize/2|*|y-ysize/2|*4/(xsize*ysize))";
02712 }
02713
02714 static const string NAME;
02715 };
02716
02717
02720 class MakeRadiusSquaredProcessor:public CircularMaskProcessor
02721 {
02722 public:
02723 string get_name() const
02724 {
02725 return NAME;
02726 }
02727 static Processor *NEW()
02728 {
02729 return new MakeRadiusSquaredProcessor();
02730 }
02731
02732 string get_desc() const
02733 {
02734 return "overwrites input, f(x) = radius * radius";
02735 }
02736
02737 static const string NAME;
02738
02739 protected:
02740 void process_dist_pixel(float *pixel, float dist) const
02741 {
02742 *pixel = dist;
02743 }
02744 };
02745
02748 class MakeRadiusProcessor:public CircularMaskProcessor
02749 {
02750 public:
02751 string get_name() const
02752 {
02753 return NAME;
02754 }
02755 static Processor *NEW()
02756 {
02757 return new MakeRadiusProcessor();
02758 }
02759
02760 string get_desc() const
02761 {
02762 return "overwrites input, f(x) = radius;";
02763 }
02764
02765 static const string NAME;
02766
02767 protected:
02768 void process_dist_pixel(float *pixel, float dist) const
02769 {
02770 *pixel = sqrt(dist);
02771 }
02772 };
02773
02776 class ComplexPixelProcessor:public Processor
02777 {
02778 public:
02779 void process_inplace(EMData * image);
02780
02781 static string get_group_desc()
02782 {
02783 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.";
02784 }
02785
02786 protected:
02787 virtual void process_pixel(float *x) const = 0;
02788 };
02789
02792 class ComplexNormPixel:public ComplexPixelProcessor
02793 {
02794 public:
02795 string get_name() const
02796 {
02797 return NAME;
02798 }
02799 static Processor *NEW()
02800 {
02801 return new ComplexNormPixel();
02802 }
02803
02804 string get_desc() const
02805 {
02806 return "Each Fourier pixel will be normalized. ie - amp=1, phase=unmodified. Useful for performing phase-residual-like computations with dot products.";
02807 }
02808
02809 static const string NAME;
02810
02811 protected:
02812 void process_pixel(float *x) const
02813 {
02814 *x=1.0;
02815 }
02816 };
02817
02821 class AreaProcessor:public Processor
02822 {
02823 public:
02824 AreaProcessor():areasize(0), kernel(0), nx(0), ny(0), nz(0)
02825 {
02826 }
02827
02828 void process_inplace(EMData * image);
02829
02830 void set_params(const Dict & new_params)
02831 {
02832 params = new_params;
02833 areasize = params["areasize"];
02834 }
02835
02836 TypeDict get_param_types() const
02837 {
02838 TypeDict d;
02839 d.put("areasize", EMObject::INT, "The width of the area to process (not radius)");
02840 return d;
02841 }
02842
02843 string get_desc() const
02844 {
02845 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().";
02846 }
02847
02848 protected:
02849 virtual void process_pixel(float *pixel, float, float, float, float *area_matrix) const
02850 {
02851 for (int i = 0; i < matrix_size; i++)
02852 {
02853 *pixel += area_matrix[i] * kernel[i];
02854 }
02855 }
02856
02857 virtual void create_kernel() const = 0;
02858
02859 int areasize;
02860 int matrix_size;
02861 float *kernel;
02862 int nx;
02863 int ny;
02864 int nz;
02865 };
02866
02869 class LaplacianProcessor:public AreaProcessor
02870 {
02871 public:
02872 string get_name() const
02873 {
02874 return NAME;
02875 }
02876 static Processor *NEW()
02877 {
02878 return new LaplacianProcessor();
02879 }
02880
02881 string get_desc() const
02882 {
02883 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).";
02884 }
02885
02886 static const string NAME;
02887
02888 protected:
02889 void create_kernel() const;
02890
02891 };
02892
02895 class ZeroConstantProcessor:public AreaProcessor
02896 {
02897 public:
02898 string get_name() const
02899 {
02900 return NAME;
02901 }
02902 static Processor *NEW()
02903 {
02904 return new ZeroConstantProcessor();
02905 }
02906
02907 string get_desc() const
02908 {
02909 return "Contraction of data, if any nearest neighbor is 0, value -> 0, generally used iteratively";
02910 }
02911
02912 static const string NAME;
02913
02914 protected:
02915 void process_pixel(float *pixel, float, float, float, float *matrix) const
02916 {
02917 if (*pixel != 0)
02918 {
02919 if (*pixel == matrix[1] || *pixel == matrix[3] || *pixel == matrix[5] ||
02920 *pixel == matrix[7] || matrix[1] == 0 || matrix[3] == 0 ||
02921 matrix[5] == 0 || matrix[7] == 0) {
02922 *pixel = 0;
02923 }
02924 }
02925 }
02926
02927 void create_kernel() const
02928 {
02929 }
02930 };
02931
02940 class BoxStatProcessor:public Processor
02941 {
02942 public:
02943 void process_inplace(EMData * image);
02944
02945 static string get_group_desc()
02946 {
02947 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).";
02948 }
02949
02950 TypeDict get_param_types() const
02951 {
02952 TypeDict d;
02953 d.put("radius", EMObject::INT, "The radius of the search box, default is 1 which results in a 3x3 box (3 = 2xradius + 1)");
02954 return d;
02955 }
02956
02957 protected:
02958 virtual void process_pixel(float *pixel, const float *array, int n) const = 0;
02959 };
02960
02961
02964 class BoxMedianProcessor:public BoxStatProcessor
02965 {
02966 public:
02967 string get_name() const
02968 {
02969 return NAME;
02970 }
02971 static Processor *NEW()
02972 {
02973 return new BoxMedianProcessor();
02974 }
02975
02976 string get_desc() const
02977 {
02978 return "A processor for noise reduction. pixel = median of values surrounding pixel.";
02979 }
02980
02981 static const string NAME;
02982
02983 protected:
02984 void process_pixel(float *pixel, const float *array, int n) const
02985 {
02986 float *data = new float[n];
02987 memcpy(data, array, sizeof(float) * n);
02988
02989 for (int i = 0; i <= n / 2; i++)
02990 {
02991 for (int j = i + 1; j < n; j++)
02992 {
02993 if (data[i] < data[j]) {
02994 float t = data[i];
02995 data[i] = data[j];
02996 data[j] = t;
02997 }
02998 }
02999 }
03000
03001 if (n % 2 != 0)
03002 {
03003 *pixel = data[n / 2];
03004 }
03005 else {
03006 *pixel = (data[n / 2] + data[n / 2 - 1]) / 2;
03007 }
03008 if( data )
03009 {
03010 delete[]data;
03011 data = 0;
03012 }
03013 }
03014 };
03015
03018 class BoxSigmaProcessor:public BoxStatProcessor
03019 {
03020 public:
03021 string get_name() const
03022 {
03023 return NAME;
03024 }
03025 static Processor *NEW()
03026 {
03027 return new BoxSigmaProcessor();
03028 }
03029
03030 string get_desc() const
03031 {
03032 return "pixel = standard deviation of values surrounding pixel.";
03033 }
03034
03035 static const string NAME;
03036
03037 protected:
03038 void process_pixel(float *pixel, const float *data, int n) const
03039 {
03040 float sum = 0;
03041 float square_sum = 0;
03042 for (int i = 0; i < n; i++)
03043 {
03044 sum += data[i];
03045 square_sum += data[i] * data[i];
03046 }
03047
03048 float mean = sum / n;
03049 *pixel = sqrt(square_sum / n - mean * mean);
03050 }
03051 };
03052
03055 class BoxMaxProcessor:public BoxStatProcessor
03056 {
03057 public:
03058 string get_name() const
03059 {
03060 return NAME;
03061 }
03062 static Processor *NEW()
03063 {
03064 return new BoxMaxProcessor();
03065 }
03066
03067 string get_desc() const
03068 {
03069 return "peak processor: pixel = max of values surrounding pixel.";
03070 }
03071
03072 static const string NAME;
03073
03074 protected:
03075 void process_pixel(float *pixel, const float *data, int n) const
03076 {
03077 float maxval = -FLT_MAX;
03078 for (int i = 0; i < n; i++)
03079 {
03080 if (data[i] > maxval) {
03081 maxval = data[i];
03082 }
03083 }
03084 *pixel = maxval;
03085 }
03086 };
03087
03090 class MinusPeakProcessor:public BoxStatProcessor
03091 {
03092 public:
03093 string get_name() const
03094 {
03095 return NAME;
03096 }
03097 static Processor *NEW()
03098 {
03099 return new MinusPeakProcessor();
03100 }
03101
03102 string get_desc() const
03103 {
03104 return "peak processor: pixel = pixel - max of values surrounding pixel. This is a sort of positive peak-finding algorithm.";
03105 }
03106
03107 static const string NAME;
03108
03109 protected:
03110 void process_pixel(float *pixel, const float *data, int n) const
03111 {
03112 float maxval = -FLT_MAX;
03113 for (int i = 0; i < n; i++)
03114 {
03115 if (data[i] > maxval) {
03116 maxval = data[i];
03117 }
03118 }
03119 *pixel -= maxval;
03120 }
03121 };
03122
03126 class PeakOnlyProcessor:public BoxStatProcessor
03127 {
03128 public:
03129 string get_name() const
03130 {
03131 return NAME;
03132 }
03133 static Processor *NEW()
03134 {
03135 return new PeakOnlyProcessor();
03136 }
03137 void set_params(const Dict & new_params)
03138 {
03139 params = new_params;
03140 npeaks = params["npeaks"];
03141 if (npeaks == 0) {
03142 npeaks = 1;
03143 }
03144 }
03145
03146 TypeDict get_param_types() const
03147 {
03148 TypeDict d;
03149 d.put("npeaks", EMObject::INT, "the number of surrounding peaks allow to >= pixel values");
03150 return d;
03151 }
03152
03153 string get_desc() const
03154 {
03155 return "peak processor -> if npeaks or more surrounding values >= value, value->0";
03156 }
03157
03158 static const string NAME;
03159
03160 protected:
03161 void process_pixel(float *pixel, const float *data, int n) const
03162 {
03163 int r = 0;
03164
03165 for (int i = 0; i < n; i++)
03166 {
03167 if (data[i] >= *pixel) {
03168 r++;
03169 }
03170 }
03171
03172 if (r > npeaks)
03173 {
03174 *pixel = 0;
03175 }
03176 }
03177 private:
03178 int npeaks;
03179 };
03180
03185 class DiffBlockProcessor:public Processor
03186 {
03187 public:
03188 void process_inplace(EMData * image);
03189
03190 string get_name() const
03191 {
03192 return NAME;
03193 }
03194 static Processor *NEW()
03195 {
03196 return new DiffBlockProcessor();
03197 }
03198
03199 string get_desc() const
03200 {
03201 return "averages over cal_half_width, then sets the value in a local block";
03202 }
03203
03204 TypeDict get_param_types() const
03205 {
03206 TypeDict d;
03207 d.put("cal_half_width", EMObject::FLOAT, "cal_half_width is dx/dy for calculating an average");
03208 d.put("fill_half_width", EMObject::FLOAT, "fill_half_width is dx/dy for fill/step");
03209 return d;
03210 }
03211
03212 static const string NAME;
03213 };
03214
03219 class CutoffBlockProcessor:public Processor
03220 {
03221 public:
03222 void process_inplace(EMData * image);
03223
03224 string get_name() const
03225 {
03226 return NAME;
03227 }
03228 static Processor *NEW()
03229 {
03230 return new CutoffBlockProcessor();
03231 }
03232
03233 TypeDict get_param_types() const
03234 {
03235 TypeDict d;
03236 d.put("value1", EMObject::FLOAT, "val1 is dx/dy");
03237 d.put("value2", EMObject::FLOAT, "val2 is lowpass freq cutoff in pixels");
03238 return d;
03239 }
03240
03241 string get_desc() const
03242 {
03243 return "Block processor, val1 is dx/dy, val2 is lp freq cutoff in pixels. Mystery processor.";
03244 }
03245
03246 static const string NAME;
03247 };
03248
03254 class BooleanShrinkProcessor
03255 {
03256 protected:
03264 template<class LogicOp>
03265 EMData* process(const EMData *const image, Dict& params);
03266
03273 template<class LogicOp>
03274 void process_inplace(EMData * image, Dict& params);
03275
03276 };
03277
03286 class MaxShrinkProcessor:public BooleanShrinkProcessor, public Processor
03287 {
03288 public:
03295 virtual EMData* process(const EMData *const image)
03296 {
03297 return BooleanShrinkProcessor::process<GreaterThan>(image, params);
03298 }
03299
03300
03301 virtual void process_inplace(EMData * image)
03302 {
03303 BooleanShrinkProcessor::process_inplace<GreaterThan>(image, params);
03304 }
03305
03306 string get_desc() const
03307 {
03308 return "Shrink an image by a given amount (default 2), using the maximum value found in the pixel neighborhood.";
03309 }
03310
03311 string get_name() const
03312 {
03313 return NAME;
03314 }
03315 static Processor *NEW()
03316 {
03317 return new MaxShrinkProcessor();
03318 }
03319
03320 TypeDict get_param_types() const
03321 {
03322 TypeDict d;
03323 d.put("n", EMObject::INT, "The shrink factor");
03324 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03325 return d;
03326 }
03327
03328 static const string NAME;
03329
03330 private:
03331 struct GreaterThan
03332 {
03333 inline bool operator()(float left,float right) const { return left > right; }
03334 inline float get_start_val() { return -10000000; }
03335 };
03336 };
03337
03346 class MinShrinkProcessor:public BooleanShrinkProcessor, public Processor
03347 {
03348 public:
03355 virtual EMData* process(const EMData *const image)
03356 {
03357 return BooleanShrinkProcessor::process<LessThan>(image, params);
03358 }
03359
03360
03361 virtual void process_inplace(EMData * image)
03362 {
03363 BooleanShrinkProcessor::process_inplace<LessThan>(image, params);
03364 }
03365 string get_desc() const
03366 {
03367 return "Shrink an image by a given amount (default 2), using the minimum value found in the pixel neighborhood.";
03368 }
03369
03370 string get_name() const
03371 {
03372 return NAME;
03373 }
03374 static Processor *NEW()
03375 {
03376 return new MinShrinkProcessor();
03377 }
03378
03379 TypeDict get_param_types() const
03380 {
03381 TypeDict d;
03382 d.put("n", EMObject::INT, "The shrink factor");
03383 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03384 return d;
03385 }
03386
03387 static const string NAME;
03388
03389 private:
03390 struct LessThan
03391 {
03392 inline bool operator()(float left,float right) const { return left < right; }
03393 inline float get_start_val() { return 9999999999.0f; }
03394 };
03395 };
03396
03403 class MeanShrinkProcessor : public Processor
03404 {
03405 public:
03416 virtual EMData* process(const EMData *const image);
03417
03424 virtual void process_inplace(EMData * image);
03425
03426 string get_desc() const
03427 {
03428 return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
03429 }
03430
03431 virtual string get_name() const
03432 {
03433 return NAME;
03434 }
03435 static Processor *NEW()
03436 {
03437 return new MeanShrinkProcessor();
03438 }
03439
03440 virtual TypeDict get_param_types() const
03441 {
03442 TypeDict d;
03443 d.put("n", EMObject::FLOAT, "The shrink factor");
03444 return d;
03445 }
03446
03447 static const string NAME;
03448
03449 private:
03457 void accrue_mean(EMData* to, const EMData *const from, const int shrinkfactor);
03458
03465 void accrue_mean_one_p_five(EMData* to, const EMData * const from);
03466 };
03467
03468
03475 class MedianShrinkProcessor : public Processor
03476 {
03477 public:
03488 virtual EMData* process(const EMData *const image);
03489
03496 virtual void process_inplace(EMData * image);
03497
03498 string get_desc() const
03499 {
03500 return "Shrink an image by a given amount , using the median value found in the pixel neighborhood.";
03501 }
03502
03503 virtual string get_name() const
03504 {
03505 return NAME;
03506 }
03507 static Processor *NEW()
03508 {
03509 return new MedianShrinkProcessor();
03510 }
03511
03512 virtual TypeDict get_param_types() const
03513 {
03514 TypeDict d;
03515 d.put("n", EMObject::INT, "The shrink factor");
03516 return d;
03517 }
03518
03519 static const string NAME;
03520
03521 private:
03529 void accrue_median(EMData* to, const EMData* const from,const int shrink_factor);
03530 };
03531
03532
03541 class FFTResampleProcessor : public Processor
03542 {
03543 public:
03544 virtual EMData* process(const EMData *const image);
03545
03546 virtual void process_inplace(EMData * image);
03547
03548 string get_desc() const
03549 {
03550 return "Robust resampling of an image by clipping its Fourier transform.";
03551 }
03552
03553 string get_name() const
03554 {
03555 return NAME;
03556 }
03557 static Processor *NEW()
03558 {
03559 return new FFTResampleProcessor();
03560 }
03561
03562 TypeDict get_param_types() const
03563 {
03564 TypeDict d;
03565 d.put("n", EMObject::FLOAT, "The sample rate. Less than one enlarges the image, greater than one shrinks it.");
03566 return d;
03567 }
03568
03569 static const string NAME;
03570
03571 private:
03578 void fft_resample(EMData* to, const EMData *const from, const float& sample_rate);
03579
03580 };
03581
03584 class GradientRemoverProcessor:public Processor
03585 {
03586 public:
03587 void process_inplace(EMData * image);
03588
03589 string get_name() const
03590 {
03591 return NAME;
03592 }
03593 static Processor *NEW()
03594 {
03595 return new GradientRemoverProcessor();
03596 }
03597
03598 string get_desc() const
03599 {
03600 return "Gradient remover, does a rough plane fit to find linear gradients.";
03601 }
03602
03603 static const string NAME;
03604 };
03605
03614 class GradientPlaneRemoverProcessor:public Processor
03615 {
03616 public:
03617 void process_inplace(EMData * image);
03618
03619 string get_name() const
03620 {
03621 return NAME;
03622 }
03623 static Processor *NEW()
03624 {
03625 return new GradientPlaneRemoverProcessor();
03626 }
03627
03628 string get_desc() const
03629 {
03630 return "Remove gradient by least square plane fit";
03631 }
03632
03633 TypeDict get_param_types() const
03634 {
03635 TypeDict d;
03636 d.put("mask", EMObject::EMDATA, "mask object: nonzero pixel positions will be used to fit plane. default = 0");
03637 d.put("changeZero", EMObject::INT, "if zero pixels are modified when removing gradient. default = 0");
03638 d.put("planeParam", EMObject::FLOATARRAY, "fitted plane parameters output");
03639 return d;
03640 }
03641
03642 static const string NAME;
03643 };
03644
03645
03652 class FlattenBackgroundProcessor:public Processor
03653 {
03654 public:
03655 void process_inplace(EMData * image);
03656
03657 string get_name() const
03658 {
03659 return NAME;
03660 }
03661
03662 static Processor *NEW()
03663 {
03664 return new FlattenBackgroundProcessor();
03665 }
03666
03667 string get_desc() const
03668 {
03669 return "Flattens the background by subtracting the local mean";
03670 }
03671
03672 TypeDict get_param_types() const
03673 {
03674 TypeDict d;
03675 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");
03676 d.put("radius", EMObject::INT, "The radius of circle/sphere that defines the local neighborhood. Exclusive of the mask argument");
03677 return d;
03678 }
03679
03680 static const string NAME;
03681 };
03682
03683
03686 class RampProcessor:public Processor
03687 {
03688 public:
03689 void process_inplace(EMData * image);
03690
03691 string get_name() const
03692 {
03693 return NAME;
03694 }
03695 static Processor *NEW()
03696 {
03697 return new RampProcessor();
03698 }
03699
03700 string get_desc() const
03701 {
03702 return "Ramp processor -- Fits a least-squares plane "
03703 "to the picture, and subtracts the plane from "
03704 "the picture. A wedge-shaped overall density "
03705 "profile can thus be removed from the picture.";
03706 }
03707
03708 static const string NAME;
03709 };
03710
03713 class VerticalStripeProcessor:public Processor
03714 {
03715 public:
03716 void process_inplace(EMData * image);
03717
03718 string get_name() const
03719 {
03720 return NAME;
03721 }
03722
03723 static Processor *NEW()
03724 {
03725 return new VerticalStripeProcessor();
03726 }
03727
03728 string get_desc() const
03729 {
03730 return "Tries to fix images scanned on the zeiss for poor ccd normalization.";
03731 }
03732
03733 static const string NAME;
03734 };
03735
03738 class RealToFFTProcessor:public Processor
03739 {
03740 public:
03741 void process_inplace(EMData *image);
03742
03743 string get_name() const
03744 {
03745 return NAME;
03746 }
03747
03748 static Processor *NEW()
03749 {
03750 return new RealToFFTProcessor();
03751 }
03752
03753 string get_desc() const
03754 {
03755 return "This will replace the image with a full-circle 2D fft amplitude rendering. Note that this renders amplitude, when intensity is more common.";
03756 }
03757
03758 static const string NAME;
03759 };
03760
03761
03764 class SigmaZeroEdgeProcessor:public Processor
03765 {
03766 public:
03767 void process_inplace(EMData * image);
03768
03769 string get_name() const
03770 {
03771 return NAME;
03772 }
03773 static Processor *NEW()
03774 {
03775 return new SigmaZeroEdgeProcessor();
03776 }
03777
03778 string get_desc() const
03779 {
03780 return "Fill zeroes at edges with nearest horizontal/vertical value.";
03781 }
03782
03783 static const string NAME;
03784 };
03785
03791 class BeamstopProcessor:public Processor
03792 {
03793 public:
03794 void process_inplace(EMData * image);
03795
03796 string get_name() const
03797 {
03798 return NAME;
03799 }
03800
03801 static Processor *NEW()
03802 {
03803 return new BeamstopProcessor();
03804 }
03805
03806 string get_desc() const
03807 {
03808 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.";
03809 }
03810
03811 TypeDict get_param_types() const
03812 {
03813 TypeDict d;
03814 d.put("value1", EMObject::FLOAT, "sig multiplier");
03815 d.put("value2", EMObject::FLOAT, "x of center");
03816 d.put("value3", EMObject::FLOAT, "y of center");
03817 return d;
03818 }
03819
03820 static const string NAME;
03821 };
03822
03825 class MeanZeroEdgeProcessor:public Processor
03826 {
03827 public:
03828 void process_inplace(EMData * image);
03829
03830 string get_name() const
03831 {
03832 return NAME;
03833 }
03834
03835 static Processor *NEW()
03836 {
03837 return new MeanZeroEdgeProcessor();
03838 }
03839
03840 string get_desc() const
03841 {
03842 return "Fill zeroes at edges with nearest horizontal/vertical value damped towards Mean2.";
03843 }
03844
03845 static const string NAME;
03846 };
03847
03848
03851 class AverageXProcessor:public Processor
03852 {
03853 public:
03854 void process_inplace(EMData * image);
03855
03856 string get_name() const
03857 {
03858 return NAME;
03859 }
03860
03861 static Processor *NEW()
03862 {
03863 return new AverageXProcessor();
03864 }
03865
03866 string get_desc() const
03867 {
03868 return "Average along Y and replace with average";
03869 }
03870
03871 static const string NAME;
03872 };
03873
03877 class DecayEdgeProcessor:public Processor
03878 {
03879 public:
03880 void process_inplace(EMData * image);
03881 string get_name() const
03882 {
03883 return NAME;
03884 }
03885
03886 static Processor *NEW()
03887 {
03888 return new DecayEdgeProcessor();
03889 }
03890
03891 string get_desc() const
03892 {
03893 return "Decay edges of image to zero";
03894 }
03895
03896 TypeDict get_param_types() const
03897 {
03898 TypeDict d;
03899 d.put("width", EMObject::INT, "Width of the decay region around the edge of the image in pixels");
03900 return d;
03901 }
03902
03903 static const string NAME;
03904 };
03905
03912 class ZeroEdgeRowProcessor:public Processor
03913 {
03914 public:
03915 void process_inplace(EMData * image);
03916 string get_name() const
03917 {
03918 return NAME;
03919 }
03920
03921 static Processor *NEW()
03922 {
03923 return new ZeroEdgeRowProcessor();
03924 }
03925
03926 string get_desc() const
03927 {
03928 return "zero edges of image on top and bottom, and on left and right.";
03929 }
03930
03931 TypeDict get_param_types() const
03932 {
03933 TypeDict d;
03934 d.put("x0", EMObject::INT, "The number of columns to zero from left");
03935 d.put("x1", EMObject::INT, "The number of columns to zero from right");
03936 d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
03937 d.put("y1", EMObject::INT, "The number of rows to zero from the top");
03938 return d;
03939 }
03940
03941 static const string NAME;
03942 };
03943
03952 class ZeroEdgePlaneProcessor:public Processor
03953 {
03954 public:
03955 void process_inplace(EMData * image);
03956 string get_name() const
03957 {
03958 return NAME;
03959 }
03960
03961 static Processor *NEW()
03962 {
03963 return new ZeroEdgePlaneProcessor();
03964 }
03965
03966 string get_desc() const
03967 {
03968 return "zero edges of volume on all sides";
03969 }
03970
03971 TypeDict get_param_types() const
03972 {
03973 TypeDict d;
03974 d.put("x0", EMObject::INT, "The number of columns to zero from left");
03975 d.put("x1", EMObject::INT, "The number of columns to zero from right");
03976 d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
03977 d.put("y1", EMObject::INT, "The number of rows to zero from the top");
03978 d.put("z0", EMObject::INT, "The number of slices to zero from the bottom");
03979 d.put("z1", EMObject::INT, "The number of slices to zero from the top");
03980 return d;
03981 }
03982
03983 static const string NAME;
03984 };
03985
03986
03993 class BilateralProcessor:public Processor
03994 {
03995 public:
03996 void process_inplace(EMData * image);
03997 string get_name() const
03998 {
03999 return NAME;
04000 }
04001
04002 string get_desc() const
04003 {
04004 return "Bilateral processing on 2D or 3D volume data. Bilateral processing does non-linear weighted averaging processing within a certain window. ";
04005 }
04006
04007 static Processor *NEW()
04008 {
04009 return new BilateralProcessor();
04010 }
04011
04012 TypeDict get_param_types() const
04013 {
04014 TypeDict d;
04015 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.");
04016 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.");
04017 d.put("niter", EMObject::INT, "how many times to apply this processing on your data.");
04018 d.put("half_width", EMObject::INT, "processing window size = (2 * half_widthh + 1) ^ 3.");
04019 return d;
04020 }
04021
04022 static const string NAME;
04023 };
04024
04027 class NormalizeProcessor:public Processor
04028 {
04029 public:
04030 void process_inplace(EMData * image);
04031
04032 static string get_group_desc()
04033 {
04034 return "Base class for normalization processors. Each specific normalization processor needs to define how to calculate mean and how to calculate sigma.";
04035 }
04036
04037 protected:
04038 virtual float calc_sigma(EMData * image) const;
04039 virtual float calc_mean(EMData * image) const = 0;
04040 };
04041
04044 class NormalizeUnitProcessor:public NormalizeProcessor
04045 {
04046 public:
04047 string get_name() const
04048 {
04049 return NAME;
04050 }
04051
04052 static Processor *NEW()
04053 {
04054 return new NormalizeUnitProcessor();
04055 }
04056
04057 string get_desc() const
04058 {
04059 return "Normalize an image so its vector length is 1.0.";
04060 }
04061
04062 static const string NAME;
04063
04064 protected:
04065 float calc_sigma(EMData * image) const;
04066 float calc_mean(EMData * image) const;
04067 };
04068
04069 inline float NormalizeUnitProcessor::calc_mean(EMData *) const { return 0; }
04070
04073 class NormalizeUnitSumProcessor:public NormalizeProcessor
04074 {
04075 public:
04076 string get_name() const
04077 {
04078 return NAME;
04079 }
04080
04081 static Processor *NEW()
04082 {
04083 return new NormalizeUnitSumProcessor();
04084 }
04085
04086 string get_desc() const
04087 {
04088 return "Normalize an image so its elements sum to 1.0 (fails if mean=0)";
04089 }
04090
04091 static const string NAME;
04092
04093 protected:
04094 float calc_sigma(EMData * image) const;
04095 float calc_mean(EMData * image) const;
04096 };
04097
04098 inline float NormalizeUnitSumProcessor::calc_mean(EMData *) const { return 0; }
04099
04100
04103 class NormalizeStdProcessor:public NormalizeProcessor
04104 {
04105 public:
04106 string get_name() const
04107 {
04108 return NAME;
04109 }
04110
04111 static Processor *NEW()
04112 {
04113 return new NormalizeStdProcessor();
04114 }
04115
04116 string get_desc() const
04117 {
04118 return "do a standard normalization on an image.";
04119 }
04120
04121 static const string NAME;
04122
04123 protected:
04124 float calc_mean(EMData * image) const;
04125 };
04126
04131 class NormalizeMaskProcessor:public NormalizeProcessor
04132 {
04133 public:
04134 string get_name() const
04135 {
04136 return NAME;
04137 }
04138
04139 string get_desc() const
04140 {
04141 return "Uses a 1/0 mask defining a region to use for the zero-normalization.if no_sigma is 1, standard deviation not modified.";
04142 }
04143
04144 static Processor *NEW()
04145 {
04146 return new NormalizeMaskProcessor();
04147 }
04148
04149 TypeDict get_param_types() const
04150 {
04151 TypeDict d;
04152 d.put("mask", EMObject::EMDATA, "the 1/0 mask defining a region to use for the zero-normalization");
04153 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");
04154 return d;
04155 }
04156
04157 static const string NAME;
04158
04159 protected:
04160 float calc_sigma(EMData * image) const;
04161 float calc_mean(EMData * image) const;
04162 };
04163
04169 class NormalizeRampNormVar: public Processor
04170 {
04171 public:
04172 string get_name() const
04173 {
04174 return NAME;
04175 }
04176
04177 static Processor *NEW()
04178 {
04179 return new NormalizeRampNormVar();
04180 }
04181
04182 string get_desc() const
04183 {
04184 return "First call filter.ramp on the image, then make the mean 0 and norm 1";
04185 }
04186
04187 void process_inplace(EMData * image);
04188
04189 static const string NAME;
04190 };
04191
04200 class NormalizeByMassProcessor: public Processor
04201 {
04202 public:
04203 string get_name() const
04204 {
04205 return NAME;
04206 }
04207
04208 static Processor *NEW()
04209 {
04210 return new NormalizeByMassProcessor();
04211 }
04212
04213 string get_desc() const
04214 {
04215 return "Normalize the mass of the image assuming a density of 1.35 g/ml (0.81 Da/A^3) (3D only)";
04216 }
04217
04218 TypeDict get_param_types() const
04219 {
04220 TypeDict d;
04221 d.put("apix", EMObject::FLOAT,"Angstrom per pixel of the image. If not set will use the apix_x attribute of the image");
04222 d.put("mass", EMObject::FLOAT,"The approximate mass of protein/structure in kilodaltons");
04223 d.put("thr", EMObject::FLOAT,"The isosurface threshold which encapsulates the structure");
04224 return d;
04225 }
04226
04227 void process_inplace(EMData * image);
04228
04229 static const string NAME;
04230 };
04231
04232
04235 class NormalizeEdgeMeanProcessor:public NormalizeProcessor
04236 {
04237 public:
04238 string get_name() const
04239 {
04240 return NAME;
04241 }
04242
04243 static Processor *NEW()
04244 {
04245 return new NormalizeEdgeMeanProcessor();
04246 }
04247
04248 string get_desc() const
04249 {
04250 return "normalizes an image, mean value equals to edge mean.";
04251 }
04252
04253 static const string NAME;
04254
04255 protected:
04256 float calc_mean(EMData * image) const;
04257 };
04258
04261 class NormalizeCircleMeanProcessor:public NormalizeProcessor
04262 {
04263 public:
04264 string get_name() const
04265 {
04266 return NAME;
04267 }
04268
04269 static Processor *NEW()
04270 {
04271 return new NormalizeCircleMeanProcessor();
04272 }
04273
04274 string get_desc() const
04275 {
04276 return "normalizes an image, mean value equals to mean of 2 pixel circular border.";
04277 }
04278
04279 static const string NAME;
04280
04281 protected:
04282 float calc_mean(EMData * image) const;
04283 };
04284
04287 class NormalizeLREdgeMeanProcessor:public NormalizeProcessor
04288 {
04289 public:
04290 string get_name() const
04291 {
04292 return NAME;
04293 }
04294
04295 static Processor *NEW()
04296 {
04297 return new NormalizeLREdgeMeanProcessor();
04298 }
04299
04300 string get_desc() const
04301 {
04302 return "normalizes an image, uses 2 pixels on left and right edge";
04303 }
04304
04305 static const string NAME;
04306
04307 protected:
04308 float calc_mean(EMData * image) const;
04309 };
04310
04313 class NormalizeMaxMinProcessor:public NormalizeProcessor
04314 {
04315 public:
04316 string get_name() const
04317 {
04318 return NAME;
04319 }
04320
04321 static Processor *NEW()
04322 {
04323 return new NormalizeMaxMinProcessor();
04324 }
04325
04326 string get_desc() const
04327 {
04328 return "normalizes an image. mean -> (maxval-minval)/2; std dev = (maxval+minval)/2;";
04329 }
04330
04331 static const string NAME;
04332
04333 protected:
04334 float calc_sigma(EMData * image) const;
04335 float calc_mean(EMData * image) const;
04336 };
04337
04340 class NormalizeRowProcessor:public Processor
04341 {
04342 public:
04343 string get_name() const
04344 {
04345 return NAME;
04346 }
04347
04348 static Processor *NEW()
04349 {
04350 return new NormalizeRowProcessor();
04351 }
04352
04353 string get_desc() const
04354 {
04355 return "normalizes each row in the image individually";
04356 }
04357
04358 static const string NAME;
04359
04360 void process_inplace(EMData * image);
04361 };
04362
04368 class NormalizeToLeastSquareProcessor:public Processor
04369 {
04370 public:
04371 void process_inplace(EMData * image);
04372
04373 string get_name() const
04374 {
04375 return NAME;
04376 }
04377
04378 static Processor *NEW()
04379 {
04380 return new NormalizeToLeastSquareProcessor();
04381 }
04382
04383 TypeDict get_param_types() const
04384 {
04385 TypeDict d;
04386 d.put("to", EMObject::EMDATA, "reference image normalize to");
04387 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)");
04388 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)");
04389 return d;
04390 }
04391
04392 string get_desc() const
04393 {
04394 return "use least square method to normalize";
04395 }
04396
04397 static const string NAME;
04398 };
04399
04402 class RotationalAverageProcessor:public Processor
04403 {
04404 public:
04405 void process_inplace(EMData * image);
04406
04407 string get_name() const
04408 {
04409 return NAME;
04410 }
04411
04412 static Processor *NEW()
04413 {
04414 return new RotationalAverageProcessor();
04415 }
04416
04417 string get_desc() const
04418 {
04419 return "Makes image circularly/spherically symmetric.";
04420 }
04421
04422 static const string NAME;
04423 };
04424
04427 class RotationalSubstractProcessor:public Processor
04428 {
04429 public:
04430 virtual void process_inplace(EMData * image);
04431
04432 virtual string get_name() const
04433 {
04434 return NAME;
04435 }
04436
04437 static Processor *NEW()
04438 {
04439 return new RotationalSubstractProcessor();
04440 }
04441
04442 virtual string get_desc() const
04443 {
04444 return "subtracts circularly/spherically symmetric part of an image.";
04445 }
04446
04447 static const string NAME;
04448 };
04449
04455 class TransposeProcessor:public Processor
04456 {
04457 public:
04458
04463 virtual void process_inplace(EMData * image);
04464
04469 virtual EMData* process(const EMData * const image);
04470
04471 virtual string get_name() const
04472 {
04473 return NAME;
04474 }
04475
04476 static Processor *NEW()
04477 {
04478 return new TransposeProcessor();
04479 }
04480
04481 virtual TypeDict get_param_types() const
04482 {
04483 TypeDict d;
04484 return d;
04485 }
04486
04487 virtual string get_desc() const
04488 {
04489 return "Get the transpose of an image. Works for 2D only";
04490 }
04491
04492 static const string NAME;
04493 };
04494
04495
04499 class FlipProcessor:public Processor
04500 {
04501 public:
04502 virtual void process_inplace(EMData * image);
04503
04504 virtual string get_name() const
04505 {
04506 return NAME;
04507 }
04508
04509 static Processor *NEW()
04510 {
04511 return new FlipProcessor();
04512 }
04513
04514 virtual TypeDict get_param_types() const
04515 {
04516 TypeDict d;
04517 d.put("axis", EMObject::STRING, "'x', 'y', or 'z' axis. 'x' means horizonal flip; 'y' means vertical flip;");
04518 return d;
04519 }
04520
04521 virtual string get_desc() const
04522 {
04523 return "flip an image around an axis.";
04524 }
04525
04526 static const string NAME;
04527 };
04528
04529
04530
04531
04532
04533
04534
04535
04536
04537
04538
04539
04540
04541
04542
04543
04544
04545
04546
04547
04548
04549
04550
04551
04552
04553
04554
04555
04556
04557
04562 class AddNoiseProcessor:public Processor
04563 {
04564 public:
04565 virtual void process_inplace(EMData * image);
04566
04567 virtual string get_name() const
04568 {
04569 return NAME;
04570 }
04571
04572 static Processor *NEW()
04573 {
04574 return new AddNoiseProcessor();
04575 }
04576
04577 virtual TypeDict get_param_types() const
04578 {
04579 TypeDict d;
04580 d.put("noise", EMObject::FLOAT, "noise factor used to generate Gaussian distribution random noise");
04581 d.put("seed", EMObject::INT, "seed for random number generator");
04582 return d;
04583 }
04584
04585 virtual string get_desc() const
04586 {
04587 return "add noise to an image, image multiply by noise then add a random value";
04588 }
04589
04590 static const string NAME;
04591
04592 protected:
04593 virtual float get_sigma(EMData *)
04594 {
04595 return 1.0;
04596 }
04597 };
04598
04601 class AddSigmaNoiseProcessor:public AddNoiseProcessor
04602 {
04603 public:
04604 virtual string get_name() const
04605 {
04606 return NAME;
04607 }
04608
04609 static Processor *NEW()
04610 {
04611 return new AddSigmaNoiseProcessor();
04612 }
04613
04614 virtual string get_desc() const
04615 {
04616 return "add sigma noise.";
04617 }
04618
04619 static const string NAME;
04620
04621 protected:
04622 float get_sigma(EMData * image);
04623 };
04624
04633 class AddRandomNoiseProcessor:public Processor
04634 {
04635 public:
04636 virtual void process_inplace(EMData * image);
04637
04638 virtual string get_name() const
04639 {
04640 return NAME;
04641 }
04642
04643 static Processor *NEW()
04644 {
04645 return new AddRandomNoiseProcessor();
04646 }
04647
04648 virtual TypeDict get_param_types() const
04649 {
04650 TypeDict d;
04651 d.put("n", EMObject::INT);
04652 d.put("x0", EMObject::FLOAT);
04653 d.put("dx", EMObject::FLOAT);
04654 d.put("y", EMObject::FLOATARRAY);
04655 d.put("interpolation", EMObject::INT);
04656 d.put("seed", EMObject::INT, "seed for random number generator");
04657 return d;
04658 }
04659
04660 virtual string get_desc() const
04661 {
04662 return "add spectral noise to a complex image.";
04663 }
04664
04665 static const string NAME;
04666 };
04667
04673 class FourierToCornerProcessor:public Processor
04674 {
04675 public:
04681 virtual void process_inplace(EMData * image);
04682
04683 virtual string get_name() const
04684 {
04685 return NAME;
04686 }
04687
04688 static Processor *NEW()
04689 {
04690 return new FourierToCornerProcessor();
04691 }
04692
04693 virtual string get_desc() const
04694 {
04695 return "Undoes the xform.fourierorigin.tocenter processor";
04696 }
04697
04698 static const string NAME;
04699 };
04700
04701
04713 class FourierToCenterProcessor:public Processor
04714 {
04715 public:
04721 virtual void process_inplace(EMData * image);
04722
04723 virtual string get_name() const
04724 {
04725 return NAME;
04726 }
04727
04728 static Processor *NEW()
04729 {
04730 return new FourierToCenterProcessor();
04731 }
04732
04733 virtual string get_desc() const
04734 {
04735 return "Translates the origin in Fourier space from the corner to the center in y and z - works in 2D and 3D";
04736 }
04737
04738 static const string NAME;
04739 };
04740
04750 class Phase180Processor:public Processor
04751 {
04752 protected:
04765 void swap_corners_180(EMData * image);
04766
04778 void swap_central_slices_180(EMData * image);
04779
04786 void fourier_phaseshift180(EMData * image);
04787
04788 };
04789
04799 class PhaseToCenterProcessor:public Phase180Processor
04800 {
04801 public:
04802 virtual void process_inplace(EMData * image);
04803
04804 virtual string get_name() const
04805 {
04806 return NAME;
04807 }
04808
04809 static Processor *NEW()
04810 {
04811 return new PhaseToCenterProcessor();
04812 }
04813
04814 virtual string get_desc() const
04815 {
04816 return "Undoes the effect of the xform.phaseorigin.tocorner processor";
04817 }
04818
04819 static const string NAME;
04820 };
04821
04829 class PhaseToCornerProcessor:public Phase180Processor
04830 {
04831 public:
04832 virtual void process_inplace(EMData * image);
04833
04834 virtual string get_name() const
04835 {
04836 return NAME;
04837 }
04838
04839 static Processor *NEW()
04840 {
04841 return new PhaseToCornerProcessor();
04842 }
04843
04844 virtual string get_desc() const
04845 {
04846 return "Translates a centered image to the corner in a forward fashion";
04847 }
04848
04849 static const string NAME;
04850 };
04851
04856 class AutoMask2DProcessor:public Processor
04857 {
04858 public:
04859 virtual void process_inplace(EMData * image);
04860
04861 virtual string get_name() const
04862 {
04863 return NAME;
04864 }
04865
04866 static Processor *NEW()
04867 {
04868 return new AutoMask2DProcessor();
04869 }
04870
04871 virtual TypeDict get_param_types() const
04872 {
04873 TypeDict d;
04874 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
04875 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
04876 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
04877 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
04878 d.put("nshells", EMObject::INT, "The number of dilation operations");
04879 d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
04880 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
04881 d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
04882 return d;
04883 }
04884
04885 virtual string get_desc() const
04886 {
04887 return "2D version of mask.auto3d";
04888 }
04889
04890 static const string NAME;
04891 };
04892
04893
04900 class AutoMaskAsymUnit:public Processor
04901 {
04902 public:
04903 virtual void process_inplace(EMData * image);
04904
04905 virtual string get_name() const
04906 {
04907 return NAME;
04908 }
04909
04910 static Processor *NEW()
04911 {
04912 return new AutoMaskAsymUnit();
04913 }
04914
04915 virtual TypeDict get_param_types() const
04916 {
04917 TypeDict d;
04918 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.");
04919 d.put("sym", EMObject::STRING, "The symmetry, for example, d7");
04920 return d;
04921 }
04922
04923 virtual string get_desc() const
04924 {
04925 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.";
04926 }
04927
04928 static const string NAME;
04929 };
04930
04935 class AutoMask3DProcessor:public Processor
04936 {
04937 public:
04938 virtual void process_inplace(EMData * image);
04939
04940 virtual string get_name() const
04941 {
04942 return NAME;
04943 }
04944
04945 static Processor *NEW()
04946 {
04947 return new AutoMask3DProcessor();
04948 }
04949
04950 virtual TypeDict get_param_types() const
04951 {
04952 TypeDict d;
04953 d.put("threshold1", EMObject::FLOAT);
04954 d.put("threshold2", EMObject::FLOAT);
04955 return d;
04956 }
04957
04958 virtual string get_desc() const
04959 {
04960 return "Tries to mask out only interesting density";
04961 }
04962
04963 static void search_nearby(float *dat, float *dat2, int nx, int ny, int nz, float thr);
04964 static void fill_nearby(float *dat2, int nx, int ny, int nz);
04965
04966 static const string NAME;
04967 };
04968
04976 class AutoMask3D2Processor:public Processor
04977 {
04978 public:
04979 virtual void process_inplace(EMData * image);
04980
04981 virtual string get_name() const
04982 {
04983 return NAME;
04984 }
04985
04986 static Processor *NEW()
04987 {
04988 return new AutoMask3D2Processor();
04989 }
04990
04991 virtual string get_desc() const
04992 {
04993 return "Tries to mask out only interesting density using something akin to a flood file approach.";
04994 }
04995
04996 virtual TypeDict get_param_types() const
04997 {
04998 TypeDict d;
04999 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
05000 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
05001 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
05002 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
05003 d.put("nshells", EMObject::INT, "The number of dilation operations");
05004 d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
05005 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
05006 d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
05007 return d;
05008 }
05009
05010 static const string NAME;
05011 };
05012
05016 class AddMaskShellProcessor:public Processor
05017 {
05018 public:
05019 virtual void process_inplace(EMData * image);
05020
05021 virtual string get_name() const
05022 {
05023 return NAME;
05024 }
05025
05026 virtual string get_desc() const
05027 {
05028 return "Add additional shells/rings to an existing 1/0 mask image";
05029 }
05030
05031 static Processor *NEW()
05032 {
05033 return new AddMaskShellProcessor();
05034 }
05035
05036 virtual TypeDict get_param_types() const
05037 {
05038 TypeDict d;
05039 d.put("nshells", EMObject::INT, "number of shells to add");
05040 return d;
05041 }
05042
05043 static const string NAME;
05044 };
05045
05050 class PhaseToMassCenterProcessor:public Processor
05051 {
05052 public:
05053 virtual void process_inplace(EMData * image);
05054
05055 virtual string get_name() const
05056 {
05057 return NAME;
05058 }
05059
05060 static Processor *NEW()
05061 {
05062 return new PhaseToMassCenterProcessor();
05063 }
05064
05065 virtual string get_desc() const
05066 {
05067 return "centers the image the center of mass, which is calculated using Fourier phases, ignores old dx, dy.";
05068 }
05069
05070 virtual TypeDict get_param_types() const
05071 {
05072 TypeDict d;
05073 d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05074 return d;
05075 }
05076
05077 static const string NAME;
05078 };
05079
05084 class ToMassCenterProcessor:public Processor
05085 {
05086 public:
05087 virtual void process_inplace(EMData * image);
05088
05089 virtual string get_name() const
05090 {
05091 return NAME;
05092 }
05093
05094 static Processor *NEW()
05095 {
05096 return new ToMassCenterProcessor();
05097 }
05098
05099 virtual string get_desc() const
05100 {
05101 return "ToMassCenterProcessor centers image at center of mass. Note: includes only values > mean+0.75*sigma";
05102 }
05103
05104 virtual TypeDict get_param_types() const
05105 {
05106 TypeDict d;
05107 d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05108
05109 return d;
05110 }
05111
05112 static const string NAME;
05113 };
05114
05118 class ACFCenterProcessor:public Processor
05119 {
05120 public:
05121 virtual void process_inplace(EMData * image);
05122
05123 virtual string get_name() const
05124 {
05125 return NAME;
05126 }
05127
05128 static Processor *NEW()
05129 {
05130 return new ACFCenterProcessor();
05131 }
05132
05133 virtual string get_desc() const
05134 {
05135 return "Center image using self-convolution.";
05136 }
05137
05138 virtual TypeDict get_param_types() const
05139 {
05140 TypeDict d;
05141 return d;
05142 }
05143
05144 static const string NAME;
05145 };
05146
05151 class SNRProcessor:public Processor
05152 {
05153 public:
05154 virtual void process_inplace(EMData * image);
05155
05156 virtual string get_name() const
05157 {
05158 return NAME;
05159 }
05160
05161 static Processor *NEW()
05162 {
05163 return new SNRProcessor();
05164 }
05165
05166 virtual string get_desc() const
05167 {
05168 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.";
05169 }
05170
05171 virtual TypeDict get_param_types() const
05172 {
05173 TypeDict d;
05174 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");
05175 d.put("snrfile", EMObject::STRING, "structure factor file name");
05176 return d;
05177 }
05178
05179 static const string NAME;
05180 };
05181
05185 class FileFourierProcessor:public Processor
05186 {
05187 public:
05188 virtual void process_inplace(EMData * image);
05189
05190 virtual string get_name() const
05191 {
05192 return NAME;
05193 }
05194
05195 virtual string get_desc() const
05196 {
05197 return "A fourier processor specified in a 2 column text file.";
05198 }
05199
05200 static Processor *NEW()
05201 {
05202 return new FileFourierProcessor();
05203 }
05204
05205 virtual TypeDict get_param_types() const
05206 {
05207 TypeDict d;
05208 d.put("filename", EMObject::STRING, "file name for a 2 column text file which specified a radial function data array.");
05209 return d;
05210 }
05211
05212 static const string NAME;
05213 };
05214
05225 class SymSearchProcessor:public Processor
05226 {
05227 public:
05228 virtual void process_inplace(EMData * image);
05229
05230 virtual string get_name() const
05231 {
05232 return NAME;
05233 }
05234
05235 virtual string get_desc() const
05236 {
05237 return "Identifiy the best symmetry in the given symmetry list for each pixel and then apply the best symmetry to each pixel.";
05238 }
05239
05240 static Processor *NEW()
05241 {
05242 return new SymSearchProcessor();
05243 }
05244
05245 virtual TypeDict get_param_types() const
05246 {
05247 TypeDict d;
05248 d.put("sym", EMObject::STRINGARRAY, "the list of symmetries to search");
05249 d.put("thresh", EMObject::FLOAT, "the minimal level of symmetry to be accepted (0-1)");
05250 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");
05251 d.put("symlabel_map", EMObject::EMDATA, "the optional return map when output_symlabel=1");
05252 return d;
05253 }
05254
05255 static const string NAME;
05256 };
05257
05263 class LocalNormProcessor:public Processor
05264 {
05265 public:
05266 void process_inplace(EMData * image);
05267
05268 virtual string get_name() const
05269 {
05270 return NAME;
05271 }
05272
05273 static Processor *NEW()
05274 {
05275 return new LocalNormProcessor();
05276 }
05277
05278 virtual string get_desc() const
05279 {
05280 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 normalization size similar to an lp= value.";
05281 }
05282
05283 virtual TypeDict get_param_types() const
05284 {
05285 TypeDict d;
05286 d.put("threshold", EMObject::FLOAT, "an isosurface threshold at which all desired features are visible");
05287 d.put("radius", EMObject::FLOAT, "a normalization size similar to an lp= value");
05288 d.put("apix", EMObject::FLOAT, "Angstrom per pixel ratio");
05289 return d;
05290 }
05291
05292 static const string NAME;
05293 };
05294
05299 class IndexMaskFileProcessor:public Processor
05300 {
05301 public:
05302 virtual void process_inplace(EMData * image);
05303
05304 virtual string get_name() const
05305 {
05306 return NAME;
05307 }
05308
05309 static Processor *NEW()
05310 {
05311 return new IndexMaskFileProcessor();
05312 }
05313
05314 virtual TypeDict get_param_types() const
05315 {
05316 TypeDict d;
05317 d.put("filename", EMObject::STRING, "mask image file name");
05318 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");
05319 return d;
05320 }
05321
05322 virtual string get_desc() const
05323 {
05324 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.";
05325 }
05326
05327 static const string NAME;
05328 };
05329
05333 class CoordinateMaskFileProcessor:public Processor
05334 {
05335 public:
05336 virtual void process_inplace(EMData * image);
05337
05338 virtual string get_name() const
05339 {
05340 return NAME;
05341 }
05342
05343 static Processor *NEW()
05344 {
05345 return new CoordinateMaskFileProcessor();
05346 }
05347
05348 virtual string get_desc() const
05349 {
05350 return "Multiplies the image by the specified file using pixel coordinates instead of pixel indices. The images can be different size.";
05351 }
05352
05353 virtual TypeDict get_param_types() const
05354 {
05355 TypeDict d;
05356 d.put("filename", EMObject::STRING, "mask image file name");
05357 return d;
05358 }
05359
05360 static const string NAME;
05361 };
05362
05373 class PaintProcessor:public Processor
05374 {
05375 public:
05376 PaintProcessor():x(0), y(0), z(0),r1(0), v1(0.0), r2(0), v2(0.0)
05377 {
05378 }
05379
05380 virtual string get_name() const
05381 {
05382 return NAME;
05383 }
05384
05385 static Processor *NEW()
05386 {
05387 return new PaintProcessor();
05388 }
05389
05390 virtual string get_desc() const
05391 {
05392 return "Paints a circle with a decaying edge into the image. r<r1 -> v1, r1<r<r2 -> (v1,v2), r>r2 unchanged";
05393 }
05394
05395 virtual TypeDict get_param_types() const
05396 {
05397 TypeDict d;
05398 d.put("x", EMObject::INT, "x coordinate for Center of circle");
05399 d.put("y", EMObject::INT, "y coordinate for Center of circle");
05400 d.put("z", EMObject::INT, "z coordinate for Center of circle");
05401 d.put("r1", EMObject::INT, "Inner radius");
05402 d.put("v1", EMObject::FLOAT, "Inner value");
05403 d.put("r2", EMObject::INT, "Outter radius");
05404 d.put("v2", EMObject::FLOAT, "Outer Value");
05405 return d;
05406 }
05407
05408 virtual void set_params(const Dict & new_params)
05409 {
05410 params = new_params;
05411
05412 if (params.has_key("x")) x = params["x"];
05413 if (params.has_key("y")) y = params["y"];
05414 if (params.has_key("z")) z = params["z"];
05415 if (params.has_key("r1")) r1 = params["r1"];
05416 if (params.has_key("r2")) r2 = params["r2"];
05417 if (params.has_key("v1")) v1 = params["v1"];
05418 if (params.has_key("v2")) v2 = params["v2"];
05419 }
05420
05421 static const string NAME;
05422
05423 protected:
05424 virtual void process_inplace(EMData *image);
05425
05426 int x,y,z,r1;
05427 float v1;
05428 int r2;
05429 float v2;
05430
05431 };
05432
05433
05438 class DirectionalSumProcessor : public Processor
05439 {
05440 public:
05441 virtual string get_name() const
05442 {
05443 return NAME;
05444 }
05445
05446 static Processor *NEW()
05447 {
05448 return new DirectionalSumProcessor();
05449 }
05450
05454 virtual EMData* process(const EMData* const image);
05455
05459 virtual void process_inplace(EMData* image ) {
05460 throw InvalidCallException("The directional sum processor does not work inplace");
05461 }
05462
05463 virtual TypeDict get_param_types() const
05464 {
05465 TypeDict d;
05466 d.put("direction", EMObject::STRING,"The direction of the sum, either x,y or z");
05467 return d;
05468 }
05469
05470 string get_desc() const
05471 {
05472 return "Calculates the projection of the image along one of the axial directions, either x, y or z";
05473 }
05474
05475 static const string NAME;
05476 };
05477
05485 class WatershedProcessor:public Processor
05486 {
05487 public:
05488 virtual void process_inplace(EMData * image);
05489
05490 virtual string get_name() const
05491 {
05492 return NAME;
05493 }
05494
05495 static Processor *NEW()
05496 {
05497 return new WatershedProcessor();
05498 }
05499
05500 virtual string get_desc() const
05501 {
05502 return "Does a watershed";
05503 }
05504
05505 virtual TypeDict get_param_types() const
05506 {
05507 TypeDict d;
05508 d.put("xpoints", EMObject::FLOATARRAY,"x coordinates");
05509 d.put("ypoints", EMObject::FLOATARRAY,"y coordinates");
05510 d.put("zpoints", EMObject::FLOATARRAY,"z coordinates");
05511 d.put("minval", EMObject::FLOAT,"min value");
05512 return d;
05513 }
05514
05515 static const string NAME;
05516
05517 private:
05518 vector<Vec3i > watershed(EMData* mask, EMData* image, const float& threshold, const Vec3i& cordinate, const int mask_value);
05519 vector<Vec3i > find_region(EMData* mask,const vector<Vec3i >& coords, const int mask_value, vector<Vec3i >& region);
05520
05521 };
05522
05532 template<class Type>
05533 class BinaryOperateProcessor : public Processor{
05534 public:
05539 virtual void process_inplace(EMData * image) {
05540 if ( ! params.has_key("with") ) throw InvalidParameterException("You must supply the \"with\" parameter");
05541 EMData* with = params["with"];
05542
05543 if ( with->get_xsize() != image->get_xsize() || with->get_ysize() != image->get_ysize() || with->get_zsize() != image->get_zsize() )
05544 throw ImageDimensionException("The images you are operating on do not have the same dimensions");
05545
05546 float* image_data = image->get_data();
05547 float* with_data = with->get_data();
05548
05549 std::transform(image_data,image_data+image->get_size(),with_data,image_data,Type::binary_operate);
05550 image->update();
05551 }
05552
05553 virtual string get_name() const
05554 {
05555 return op.get_name();
05556 }
05557
05558 virtual string get_desc() const
05559 {
05560 return op.get_desc();
05561 }
05562
05563 static Processor *NEW()
05564 {
05565 return new BinaryOperateProcessor<Type>();
05566 }
05567
05568 virtual TypeDict get_param_types() const
05569 {
05570 TypeDict d;
05571 d.put("with", EMObject::EMDATA,"The second image");
05572 return d;
05573 }
05574
05575 static const string NAME;
05576 private:
05577 Type op;
05578 };
05579
05580 class MaxPixelOperator {
05581 public:
05582 string get_name() const
05583 {
05584 return NAME;
05585 }
05586
05587 string get_desc() const
05588 {
05589 return "Compares pixels in two images, returning an image with the maximum pixel value in each pixel location";
05590 }
05591
05592 static float binary_operate(const float& left, const float& right) {
05593 if (left > right) return left;
05594 return right;
05595 }
05596
05597 static const string NAME;
05598 };
05599
05600 class MinPixelOperator {
05601 public:
05602 string get_name() const
05603 {
05604 return NAME;
05605 }
05606
05607 string get_desc() const
05608 {
05609 return "Compares pixels in two images, returning an image with the minimum pixel value in each pixel location";
05610 }
05611
05612 static float binary_operate(const float& left, const float& right) {
05613 if (left < right) return left;
05614 return right;
05615 }
05616
05617 static const string NAME;
05618 };
05619
05623 class MatchSFProcessor:public FourierAnlProcessor
05624 {
05625 public:
05626
05627 virtual string get_name() const
05628 {
05629 return NAME;
05630 }
05631
05632 virtual string get_desc() const
05633 {
05634 return "Filters the image so its 1-D power spectrum matches a second image";
05635 }
05636
05637 static Processor *NEW()
05638 {
05639 return new MatchSFProcessor();
05640 }
05641
05642 virtual TypeDict get_param_types() const
05643 {
05644 TypeDict d;
05645 d.put("to", EMObject::EMDATA, "The image to match with. Make sure apix values are correct.");
05646 return d;
05647 }
05648
05649 static const string NAME;
05650
05651 protected:
05652 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05653 };
05654
05655
05660 class SetSFProcessor:public FourierAnlProcessor
05661 {
05662 public:
05663
05664 virtual string get_name() const
05665 {
05666 return NAME;
05667 }
05668
05669 virtual string get_desc() const
05670 {
05671 return "Filters the image so its 1-D power spectrum matches a supplied X-Y curve";
05672 }
05673
05674 static Processor *NEW()
05675 {
05676 return new SetSFProcessor();
05677 }
05678
05679 virtual TypeDict get_param_types() const
05680 {
05681 TypeDict d;
05682 d.put("strucfac", EMObject::XYDATA, "An XYData object contaning the curve to be imposed as a function of S");
05683 d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
05684 return d;
05685 }
05686
05687 static const string NAME;
05688
05689 protected:
05690 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05691 };
05692
05696 class SmartMaskProcessor:public Processor
05697 {
05698 public:
05699 virtual void process_inplace(EMData * image);
05700
05701 virtual string get_name() const
05702 {
05703 return NAME;
05704 }
05705
05706 static Processor *NEW()
05707 {
05708 return new SmartMaskProcessor();
05709 }
05710
05711 virtual string get_desc() const
05712 {
05713 return "Smart mask processor.";
05714 }
05715
05716 virtual TypeDict get_param_types() const
05717 {
05718 TypeDict d;
05719 d.put("mask", EMObject::FLOAT, "mask value");
05720 return d;
05721 }
05722
05723 static const string NAME;
05724 };
05725
05730 class IterBinMaskProcessor:public Processor
05731 {
05732 public:
05733 virtual void process_inplace(EMData * image);
05734
05735 virtual string get_name() const
05736 {
05737 return NAME;
05738 }
05739
05740 virtual string get_desc() const
05741 {
05742 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.";
05743 }
05744
05745 static Processor *NEW()
05746 {
05747 return new IterBinMaskProcessor();
05748 }
05749
05750 virtual TypeDict get_param_types() const
05751 {
05752 TypeDict d;
05753 d.put("val1", EMObject::FLOAT, "number of pixels to expand");
05754 d.put("val2", EMObject::FLOAT, "number of Gaussian pixels to expand, following the first expansion");
05755 return d;
05756 }
05757
05758 static const string NAME;
05759 };
05760
05763 class TestImageProcessor : public Processor
05764 {
05765 public:
05766 static string get_group_desc()
05767 {
05768 return "Base class for a group of 'processors' used to create test image.";
05769 }
05770
05771 protected:
05772 void preprocess(EMData * image);
05773 int nx, ny, nz;
05774 };
05775
05784 class TestImagePureGaussian : public TestImageProcessor
05785 {
05786 public:
05787 virtual void process_inplace(EMData * image);
05788
05789 virtual string get_name() const
05790 {
05791 return NAME;
05792 }
05793
05794 virtual string get_desc() const
05795 {
05796 return "Replace a source image as a strict Gaussian ";
05797 }
05798
05799 static Processor * NEW()
05800 {
05801 return new TestImagePureGaussian();
05802 }
05803
05804 virtual TypeDict get_param_types() const
05805 {
05806 TypeDict d;
05807 d.put("x_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on x direction");
05808 d.put("y_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on y direction");
05809 d.put("z_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on z direction");
05810 d.put("x_center", EMObject::FLOAT, "center for this Gaussian blob on x direction" );
05811 d.put("y_center", EMObject::FLOAT, "center for this Gaussian blob on y direction" );
05812 d.put("z_center", EMObject::FLOAT, "center for this Gaussian blob on z direction" );
05813 return d;
05814 }
05815
05816 static const string NAME;
05817 };
05818
05822 class TestImageFourierNoiseGaussian : public TestImageProcessor
05823 {
05824 public:
05825 virtual void process_inplace(EMData * image);
05826
05827 virtual string get_name() const
05828 {
05829 return NAME;
05830 }
05831
05832 virtual string get_desc() const
05833 {
05834 return "Replace a source image with pink Fourier noise, based on a Gaussian. Random phase.";
05835 }
05836
05837 static Processor * NEW()
05838 {
05839 return new TestImageFourierNoiseGaussian();
05840 }
05841
05842 virtual TypeDict get_param_types() const
05843 {
05844 TypeDict d;
05845 d.put("sigma", EMObject::FLOAT, "sigma value");
05846 return d;
05847 }
05848
05849 static const string NAME;
05850 };
05851
05856 class TestImageFourierNoiseProfile : public TestImageProcessor
05857 {
05858 public:
05859 virtual void process_inplace(EMData * image);
05860
05861 virtual string get_name() const
05862 {
05863 return NAME;
05864 }
05865
05866 virtual string get_desc() const
05867 {
05868 return "Replace a source image with Fourier noise using amplitude information that is stored in a profile.";
05869 }
05870
05871 static Processor * NEW()
05872 {
05873 return new TestImageFourierNoiseProfile();
05874 }
05875
05876 virtual TypeDict get_param_types() const
05877 {
05878 TypeDict d;
05879 d.put("profile", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
05880 return d;
05881 }
05882
05883 static const string NAME;
05884 };
05885
05886
05891 class CTFSNRWeightProcessor : public TestImageProcessor
05892 {
05893 public:
05894 virtual void process_inplace(EMData * image);
05895
05896 virtual string get_name() const
05897 {
05898 return NAME;
05899 }
05900
05901 virtual string get_desc() const
05902 {
05903 return "Weight the amplitudes of an image based on radial noise and snr curves ";
05904 }
05905
05906 static Processor * NEW()
05907 {
05908 return new CTFSNRWeightProcessor();
05909 }
05910
05911 virtual TypeDict get_param_types() const
05912 {
05913 TypeDict d;
05914 d.put("noise", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
05915 d.put("snr", EMObject::FLOATARRAY, "Squared amplitude divided by squared noise amplitude. As in, what is the EMAN2CTF.snr attribute");
05916 d.put("boost", EMObject::FLOAT, "Multiplicative signal boost");
05917 return d;
05918 }
05919
05920 static const string NAME;
05921 };
05922
05923
05924
05929 class TestImageLineWave : public TestImageProcessor
05930 {
05931 public:
05932 virtual void process_inplace(EMData * image);
05933
05934 virtual string get_name() const
05935 {
05936 return NAME;
05937 }
05938
05939 virtual string get_desc() const
05940 {
05941 return "Insert an oscillating sine wave into the pixel data";
05942 }
05943
05944 static Processor * NEW()
05945 {
05946 return new TestImageLineWave();
05947 }
05948
05949 virtual TypeDict get_param_types() const
05950 {
05951 TypeDict d;
05952 d.put("period", EMObject::FLOAT, "The period of the oscillating sine wave. Default 10.");
05953 return d;
05954 }
05955
05956 static const string NAME;
05957 };
05958
05959
05967 class TestTomoImage : public TestImageProcessor
05968 {
05969 public:
05973 virtual void process_inplace(EMData * image);
05974
05975 virtual string get_name() const
05976 {
05977 return NAME;
05978 }
05979
05980 virtual string get_desc() const
05981 {
05982 return "Make an image consisting various objects, useful for tomographic testing";
05983 }
05984
05985 static Processor * NEW()
05986 {
05987 return new TestTomoImage();
05988 }
05989
05990 static const string NAME;
05991
05992 private:
05993 void insert_solid_ellipse( EMData* image, const Region& region, const float& value, const Transform& t3d = Transform() );
05994 void insert_hollow_ellipse( EMData* image, const Region& region, const float& value, const int& radius, const Transform& t3d = Transform() );
05995 void insert_rectangle( EMData* image, const Region& region, const float& value, const Transform& t3d = Transform() );
05996 };
05997
06005 class TestImageGradient : public TestImageProcessor
06006 {
06007 public:
06008 virtual void process_inplace(EMData * image);
06009
06010 virtual string get_name() const
06011 {
06012 return NAME;
06013 }
06014
06015 virtual string get_desc() const
06016 {
06017 return "Make a gradient image of the form y=mx+b, where x is any of the image axes.";
06018 }
06019
06020 static Processor * NEW()
06021 {
06022 return new TestImageGradient();
06023 }
06024
06025 virtual TypeDict get_param_types() const
06026 {
06027 TypeDict d;
06028 d.put("axis", EMObject::STRING, "The axis the will be used to determine pixel values. Must be x,y or z");
06029 d.put("m", EMObject::FLOAT, "m in the equation m*axis+b. Default is 1.0");
06030 d.put("b", EMObject::FLOAT, "b in the equation m*axis+b. Default is 0.0");
06031 return d;
06032 }
06033
06034 static const string NAME;
06035 };
06036
06044 class TestImageAxes : public TestImageProcessor
06045 {
06046 public:
06051 virtual void process_inplace(EMData * image);
06052
06053 virtual string get_name() const
06054 {
06055 return NAME;
06056 }
06057
06058 virtual string get_desc() const
06059 {
06060 return "Make an image consisting of a single cross";
06061 }
06062
06063 static Processor * NEW()
06064 {
06065 return new TestImageAxes();
06066 }
06067
06068 virtual TypeDict get_param_types() const
06069 {
06070 TypeDict d;
06071 d.put("int", EMObject::FLOAT, "radius of the lines emanating from the origin");
06072 d.put("fill", EMObject::FLOAT, "value to make non-zero pixels");
06073 return d;
06074 }
06075
06076 static const string NAME;
06077 };
06078
06084 class TestImageGaussian : public TestImageProcessor
06085 {
06086 public:
06087 virtual void process_inplace(EMData * image);
06088
06089 virtual string get_name() const
06090 {
06091 return NAME;
06092 }
06093
06094 virtual string get_desc() const
06095 {
06096 return "Replace a source image as a Gaussian Blob";
06097 }
06098
06099 static Processor * NEW()
06100 {
06101 return new TestImageGaussian();
06102 }
06103
06104 virtual TypeDict get_param_types() const
06105 {
06106 TypeDict d;
06107 d.put("sigma", EMObject::FLOAT, "sigma value for this Gaussian blob");
06108 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06109 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06110 return d;
06111 }
06112
06113 static const string NAME;
06114 };
06115
06118 class TestImageScurve : public TestImageProcessor
06119 {
06120 public:
06121 virtual void process_inplace(EMData * image);
06122
06123 virtual string get_name() const
06124 {
06125 return NAME;
06126 }
06127
06128 virtual string get_desc() const
06129 {
06130 return "Replace a source image with a lumpy S-curve used for alignment testing";
06131 }
06132
06133 static Processor * NEW()
06134 {
06135 return new TestImageScurve();
06136 }
06137
06138 virtual TypeDict get_param_types() const
06139 {
06140 TypeDict d;
06141 return d;
06142 }
06143
06144 static const string NAME;
06145 };
06146
06154 class TestImageSphericalWave : public TestImageProcessor
06155 {
06156 public:
06157 virtual void process_inplace(EMData * image);
06158
06159 virtual string get_name() const
06160 {
06161 return NAME;
06162 }
06163
06164 virtual string get_desc() const
06165 {
06166 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)";
06167 }
06168
06169 static Processor * NEW()
06170 {
06171 return new TestImageSphericalWave();
06172 }
06173
06174 virtual TypeDict get_param_types() const
06175 {
06176 TypeDict d;
06177 d.put("wavelength", EMObject::FLOAT, "cos(2*pi*r/wavelength+phase)");
06178 d.put("phase", EMObject::FLOAT, "in radians");
06179 d.put("x", EMObject::FLOAT, "center of the spherical wave");
06180 d.put("y", EMObject::FLOAT, "center of the spherical wave");
06181 d.put("z", EMObject::FLOAT, "center of the spherical wave");
06182 return d;
06183 }
06184
06185 static const string NAME;
06186 };
06187
06188
06197 class TestImageSinewave : public TestImageProcessor
06198 {
06199 public:
06200 virtual void process_inplace(EMData * image);
06201
06202 virtual string get_name() const
06203 {
06204 return NAME;
06205 }
06206
06207 virtual string get_desc() const
06208 {
06209 return "Replace a source image as a sine wave in specified wave length";
06210 }
06211
06212 static Processor * NEW()
06213 {
06214 return new TestImageSinewave();
06215 }
06216
06217 virtual TypeDict get_param_types() const
06218 {
06219 TypeDict d;
06220 d.put("wavelength", EMObject::FLOAT, "wavelength in equation sin(x*2*PI/wavelength - phase*180/PI)");
06221 d.put("axis", EMObject::STRING, "(optional) specify a major axis for asymmetric features, default x axis");
06222 d.put("phase", EMObject::FLOAT, "(optional) the phase in equation sin(x*2*PI/wavelength - phase*180/PI)");
06223 d.put("az", EMObject::FLOAT, "(optional) angle in degree. for 2D image, this is the rotated angle of the image, \
06224 in 3D image, it's az for euler angle. default is zero");
06225 d.put("alt", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, alt for euler angle, default is zero");
06226 d.put("phi", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, phi for euler angle, default is zero");
06227 return d;
06228 }
06229
06230 static const string NAME;
06231 };
06232
06239 class TestImageSinewaveCircular : 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 as a circular sine wave in specified wave length";
06252 }
06253
06254 static Processor * NEW()
06255 {
06256 return new TestImageSinewaveCircular();
06257 }
06258
06259 virtual TypeDict get_param_types() const
06260 {
06261 TypeDict d;
06262 d.put("wavelength", EMObject::FLOAT, "(required)this value is the d in function |sin(x/d)|, unit: pixel");
06263 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06264 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06265 d.put("phase", EMObject::FLOAT, "(optional)phase for sine wave, default is 0");
06266 return d;
06267 }
06268
06269 static const string NAME;
06270 };
06271
06278 class TestImageSquarecube : public TestImageProcessor
06279 {
06280 public:
06281 virtual void process_inplace(EMData * image);
06282
06283 virtual string get_name() const
06284 {
06285 return NAME;
06286 }
06287
06288 virtual string get_desc() const
06289 {
06290 return "Replace a source image as a square or cube depends on 2D or 3D of the source image";
06291 }
06292
06293 static Processor * NEW()
06294 {
06295 return new TestImageSquarecube();
06296 }
06297
06298 virtual TypeDict get_param_types() const
06299 {
06300 TypeDict d;
06301 d.put("edge_length", EMObject::FLOAT, "edge length of the square or cube, unit: pixel");
06302 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06303 d.put("odd_edge", EMObject::FLOAT, "edge length for the asymmetric axis");
06304 d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank");
06305 return d;
06306 }
06307
06308 static const string NAME;
06309 };
06310
06318 class TestImageEllipse : public TestImageProcessor
06319 {
06320 public:
06321 virtual void process_inplace(EMData * image);
06322
06323 virtual string get_name() const
06324 {
06325 return NAME;
06326 }
06327
06328 virtual string get_desc() const
06329 {
06330 return "Insert an ellipse into the image.";
06331 }
06332
06333 static Processor * NEW()
06334 {
06335 return new TestImageEllipse();
06336 }
06337
06338 virtual TypeDict get_param_types() const
06339 {
06340 TypeDict d;
06341 d.put("a", EMObject::FLOAT, "equatorial radii along x axes");
06342 d.put("b", EMObject::FLOAT, "equatorial radii along y axes");
06343 d.put("c", EMObject::FLOAT, "polar radius");
06344 d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06345 d.put("fill", EMObject::FLOAT, "value you want to fill in ellipse, default to 1.0");
06346 return d;
06347 }
06348
06349 static const string NAME;
06350 };
06351
06363 class TestImageHollowEllipse : 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 "Insert a hollow ellipse into the image.";
06376 }
06377
06378 static Processor * NEW()
06379 {
06380 return new TestImageHollowEllipse();
06381 }
06382
06383 virtual TypeDict get_param_types() const
06384 {
06385 TypeDict d;
06386 d.put("xwidth", EMObject::FLOAT, "inner equatorial radii along x axes");
06387 d.put("ywidth", EMObject::FLOAT, "inner equatorial radii along y axes");
06388 d.put("zwidth", EMObject::FLOAT, "inner polar radius");
06389 d.put("a", EMObject::FLOAT, "outter equatorial radii along x axes");
06390 d.put("b", EMObject::FLOAT, "outter equatorial radii along y axes");
06391 d.put("c", EMObject::FLOAT, "outter polar radius");
06392 d.put("width",EMObject::FLOAT, "width - specify the width or specify each width explicitly - xwidth, ywidth, zwidth");
06393 d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06394 d.put("fill", EMObject::FLOAT, "value you want to fill in hollow ellipse, default to 1.0");
06395 return d;
06396 }
06397
06398 static const string NAME;
06399 };
06400
06407 class TestImageCirclesphere : public TestImageProcessor
06408 {
06409 public:
06410 virtual void process_inplace(EMData * image);
06411
06412 virtual string get_name() const
06413 {
06414 return NAME;
06415 }
06416
06417 virtual string get_desc() const
06418 {
06419 return "Replace a source image as a circle or sphere depends on 2D or 3D of the source image";
06420 }
06421
06422 static Processor * NEW()
06423 {
06424 return new TestImageCirclesphere();
06425 }
06426
06427 virtual TypeDict get_param_types() const
06428 {
06429 TypeDict d;
06430 d.put("radius", EMObject::FLOAT, "radius of circle or sphere, unit: pixel");
06431 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06432 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06433 d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank.");
06434 return d;
06435 }
06436
06437 static const string NAME;
06438 };
06439
06444 class TestImageNoiseUniformRand : public TestImageProcessor
06445 {
06446 public:
06447 virtual void process_inplace(EMData * image);
06448
06449 virtual string get_name() const
06450 {
06451 return NAME;
06452 }
06453
06454 virtual string get_desc() const
06455 {
06456 return "Replace a source image as a uniform random noise, random number generated from gsl_rng_mt19937, the pixel value is [0, 1)";
06457 }
06458
06459 static Processor * NEW()
06460 {
06461 return new TestImageNoiseUniformRand();
06462 }
06463
06464 virtual TypeDict get_param_types() const
06465 {
06466 TypeDict d;
06467 d.put("seed", EMObject::INT, "seed for random number generator");
06468 return d;
06469 }
06470
06471 static const string NAME;
06472 };
06473
06484 class TestImageNoiseGauss : public TestImageProcessor
06485 {
06486 public:
06487 virtual void process_inplace(EMData * image);
06488
06489 virtual string get_name() const
06490 {
06491 return NAME;
06492 }
06493
06494 virtual string get_desc() const
06495 {
06496 return "Replace a source image as a random noise, the random value is gaussian distributed";
06497 }
06498
06499 static Processor * NEW()
06500 {
06501 return new TestImageNoiseGauss();
06502 }
06503
06504 virtual TypeDict get_param_types() const
06505 {
06506 TypeDict d;
06507 d.put("sigma", EMObject::FLOAT, "sigma value of gausian distributed noise, default is 0.5");
06508 d.put("mean", EMObject::FLOAT, "mean value of gausian distributed noise, default is zero.");
06509 d.put("seed", EMObject::INT, "the seed for random number generator, default is not to reseed.");
06510
06511 return d;
06512 }
06513
06514 static const string NAME;
06515 };
06516
06521 class TestImageCylinder : public TestImageProcessor
06522 {
06523 public:
06524 virtual void process_inplace(EMData * image);
06525
06526 virtual string get_name() const
06527 {
06528 return NAME;
06529 }
06530
06531 virtual string get_desc() const
06532 {
06533 return "Replace a source image as a cylinder";
06534 }
06535
06536 static Processor * NEW()
06537 {
06538 return new TestImageCylinder();
06539 }
06540
06541 virtual TypeDict get_param_types() const
06542 {
06543 TypeDict d;
06544 d.put("radius", EMObject::FLOAT, "radius for the cylinder");
06545 d.put("height", EMObject::FLOAT, "height for the cylinder, by default it's the nz");
06546
06547 return d;
06548 }
06549
06550 static const string NAME;
06551 };
06552
06558 class CCDNormProcessor:public Processor
06559 {
06560 public:
06561 virtual void process_inplace(EMData * image);
06562
06563 virtual string get_name() const
06564 {
06565 return NAME;
06566 }
06567
06568 static Processor *NEW()
06569 {
06570 return new CCDNormProcessor();
06571 }
06572
06573 virtual string get_desc() const
06574 {
06575 return "normalize the 4 quadrants of a CCD image";
06576 }
06577
06578 virtual TypeDict get_param_types() const
06579 {
06580 TypeDict d;
06581 d.put("width", EMObject::INT, "number of pixels on either side of the seam to sample");
06582 return d;
06583 }
06584
06585 static const string NAME;
06586 };
06587
06595 class WaveletProcessor:public Processor
06596 {
06597 public:
06598 virtual void process_inplace(EMData * image);
06599
06600 virtual string get_name() const
06601 {
06602 return NAME;
06603 }
06604
06605 static Processor *NEW()
06606 {
06607 return new WaveletProcessor();
06608 }
06609
06610 virtual TypeDict get_param_types() const
06611 {
06612 TypeDict d;
06613 d.put("type", EMObject::STRING, "'daub', 'harr' or 'bspl'");
06614 d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06615 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)");
06616 return d;
06617 }
06618
06619 virtual string get_desc() const
06620 {
06621 return "Computes the DWT (discrete wavelet transform) of an image in one of 3 possible bases";
06622 }
06623
06624 static const string NAME;
06625 };
06626
06642 class TomoTiltEdgeMaskProcessor : public Processor
06643 {
06644 public:
06645 virtual void process_inplace(EMData* image);
06646
06647 virtual string get_name() const
06648 {
06649 return NAME;
06650 }
06651
06652 static Processor *NEW()
06653 {
06654 return new TomoTiltEdgeMaskProcessor();
06655 }
06656
06657 virtual TypeDict get_param_types() const
06658 {
06659 TypeDict d;
06660 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");
06661 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.");
06662 d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06663 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.");
06664 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)");
06665 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");
06666 return d;
06667 }
06668
06669 virtual string get_desc() const
06670 {
06671 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.";
06672 }
06673
06674 static const string NAME;
06675
06676 private:
06677 class GaussianFunctoid
06678 {
06679 public:
06680 GaussianFunctoid(const float sigma, const float mean = 0.0) : m_mean(mean), m_sigma_squared(sigma*sigma) {}
06681 ~GaussianFunctoid() {}
06682
06683 float operator()(const float distance )
06684 {
06685 return exp( -(distance-m_mean)*(distance-m_mean)/ (m_sigma_squared ));
06686 }
06687 private:
06688 float m_mean, m_sigma_squared;
06689 };
06690
06691 };
06692
06707 class TomoTiltAngleWeightProcessor : public Processor
06708 {
06709 public:
06710 virtual void process_inplace(EMData* image);
06711
06712 virtual string get_name() const
06713 {
06714 return NAME;
06715 }
06716
06717 static Processor *NEW()
06718 {
06719 return new TomoTiltAngleWeightProcessor();
06720 }
06721
06722 virtual TypeDict get_param_types() const
06723 {
06724 TypeDict d;
06725 d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06726 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");
06727 return d;
06728 }
06729
06730 virtual string get_desc() const
06731 {
06732 return "Weights the image by 1/cos(angle)";
06733 }
06734
06735 static const string NAME;
06736
06737 };
06738
06742 class FFTProcessor : public Processor
06743 {
06744 public:
06745 void process_inplace(EMData * image);
06746
06747 string get_name() const
06748 {
06749 return NAME;
06750 }
06751
06752 static Processor *NEW()
06753 {
06754 return new FFTProcessor();
06755 }
06756
06757 TypeDict get_param_types() const
06758 {
06759 TypeDict d;
06760 d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06761 return d;
06762 }
06763
06764 string get_desc() const
06765 {
06766 return "Computes the DFFT (Discrete Fast Fourier Transform) of an image";
06767 }
06768
06769 static const string NAME;
06770 };
06771
06776 class RadialProcessor : public Processor
06777 {
06778 public:
06779 void process_inplace(EMData * image);
06780
06781 string get_name() const
06782 {
06783 return NAME;
06784 }
06785
06786 static Processor *NEW()
06787 {
06788 return new RadialProcessor();
06789 }
06790
06791 TypeDict get_param_types() const
06792 {
06793 TypeDict d;
06794 d.put("table", EMObject::FLOATARRAY, "Radial array of floats, 1 float/pixel");
06795 return d;
06796 }
06797
06798 string get_desc() const
06799 {
06800 return "Multiply a real-space image by a radial function. 1 value / pixel, extending to corner. Missing values -> 0.";
06801 }
06802
06803 static const string NAME;
06804 };
06805
06812 class HistogramBin : public Processor
06813 {
06814 public:
06815 HistogramBin() : default_bins(1024) {}
06816
06817 void process_inplace(EMData * image);
06818
06819 string get_name() const
06820 {
06821 return NAME;
06822 }
06823
06824 static Processor *NEW()
06825 {
06826 return new HistogramBin();
06827 }
06828
06829 TypeDict get_param_types() const
06830 {
06831 TypeDict d;
06832 d.put("nbins", EMObject::INT, "The number of bins the pixel values will be compressed into");
06833 d.put("debug", EMObject::BOOL, "Outputs debugging information (number of pixels per bin)");
06834 return d;
06835 }
06836
06837 string get_desc() const
06838 {
06839 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";
06840 }
06841
06842 static const string NAME;
06843
06844 protected:
06845 int default_bins;
06846 };
06847
06848 class ModelHelixProcessor : public Processor
06849 {
06850 protected:
06851 float radprofile(float r, int type);
06852 };
06853
06854 class ModelEMCylinderProcessor : public ModelHelixProcessor
06855 {
06856 public:
06857 void process_inplace(EMData * in);
06858
06859 string get_name() const
06860 {
06861 return NAME;
06862 }
06863
06864 static Processor *NEW()
06865 {
06866 return new ModelEMCylinderProcessor();
06867 }
06868
06869 string get_desc() const
06870 {
06871 return "Adds a cylinder with a radial density profile similar to that of an alpha helix.";
06872 }
06873
06874 virtual TypeDict get_param_types() const
06875 {
06876 TypeDict d;
06877 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");
06878 d.put("length", EMObject::FLOAT, "cylinder length in angstroms, defaults to 3 turns (16.2 Angstroms)");
06879 d.put("x0", EMObject::INT, "x coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06880 d.put("y0", EMObject::INT, "y coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06881 d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06882
06883 return d;
06884 }
06885
06886 static const string NAME;
06887 };
06888
06889 class ApplyPolynomialProfileToHelix : public ModelHelixProcessor
06890 {
06891 public:
06892 void process_inplace(EMData * in);
06893
06894 string get_name() const
06895 {
06896 return NAME;
06897 }
06898
06899 static Processor *NEW()
06900 {
06901 return new ApplyPolynomialProfileToHelix();
06902 }
06903
06904 string get_desc() const
06905 {
06906 return "Finds the CM of each z-axis slice and applies a polynomial radial profile about it.";
06907 }
06908 virtual TypeDict get_param_types() const
06909 {
06910 TypeDict d;
06911 d.put("length", EMObject::FLOAT, "Helix length in angstroms.");
06912 d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06913 return d;
06914 }
06915
06916 static const string NAME;
06917 };
06918
06919 class BinarySkeletonizerProcessor : public Processor
06920 {
06921 public:
06922 virtual EMData* process(EMData * image);
06923 virtual void process_inplace(EMData * image);
06924
06925 virtual string get_name() const
06926 {
06927 return NAME;
06928
06929 }
06930 static Processor *NEW()
06931 {
06932 return new BinarySkeletonizerProcessor();
06933 }
06934 string get_desc() const
06935 {
06936 return "Creates a skeleton of the 3D image by considering whether density is above or below a threshold value.";
06937 }
06938 virtual TypeDict get_param_types() const
06939 {
06940 TypeDict d;
06941 d.put("threshold", EMObject::FLOAT, "Threshold value.");
06942 d.put("min_curve_width", EMObject::INT, "Minimum curve width.");
06943 d.put("min_surface_width", EMObject::INT, "Minimum surface width.");
06944 d.put("mark_surfaces", EMObject::BOOL, "Mark surfaces with a value of 2.0f, whereas curves are 1.0f.");
06945 return d;
06946 }
06947 static const string NAME;
06948 };
06949
06950 #ifdef EMAN2_USING_CUDA
06951
06956 class CudaMultProcessor: public Processor
06957 {
06958 public:
06959
06960 virtual void process_inplace(EMData * image);
06961
06962 virtual string get_name() const
06963 {
06964 return NAME;
06965 }
06966
06967 static Processor *NEW()
06968 {
06969 return new CudaMultProcessor();
06970 }
06971
06972 virtual TypeDict get_param_types() const
06973 {
06974 TypeDict d;
06975 d.put("scale", EMObject::FLOAT, "The amount to multiply each pixel by");
06976 return d;
06977 }
06978
06979 virtual string get_desc() const
06980 {
06981 return "Multiplies each pixel by a constant value";
06982 }
06983
06984 static const string NAME;
06985
06986 protected:
06987 };
06988
06994 class CudaCorrelationProcessor: public Processor
06995 {
06996 public:
06997
06998 virtual void process_inplace(EMData * image);
06999
07000 string get_name() const
07001 {
07002 return NAME;
07003 }
07004
07005 static Processor *NEW()
07006 {
07007 return new CudaCorrelationProcessor();
07008 }
07009
07010 virtual TypeDict get_param_types() const
07011 {
07012 TypeDict d;
07013 d.put("with", EMObject::EMDATA, "That which to perform the cross correlation with.");
07014 return d;
07015 }
07016
07017 virtual string get_desc() const
07018 {
07019 return "Performs Fourier based cross correlation on the GPU";
07020 }
07021
07022 static const string NAME;
07023
07024 protected:
07025 };
07026
07027
07028
07029
07030
07031
07032 class MPICUDA_kmeans {
07033 public:
07034 MPICUDA_kmeans();
07035 ~MPICUDA_kmeans();
07036 int setup(int extm, int extN, int extn, int extK, int extn_start);
07037 void append_flat_image(EMData* im, int pos);
07038 int init_mem(int numdev);
07039 void compute_im2();
07040 int random_ASG(long int rnd);
07041 vector<int> get_ASG();
07042 vector<int> get_asg();
07043 void compute_NC();
07044 vector<int> get_NC();
07045 void set_ASG(const vector <int>& ASG);
07046 void set_NC(const vector <int>& NC);
07047 int get_ct_im_mv();
07048 void set_T(float extT);
07049 float get_T();
07050 void compute_AVE();
07051 void set_AVE(EMData* im, int pos);
07052 vector<EMData*> get_AVE();
07053 int one_iter();
07054 int one_iter_SA();
07055 vector<float> compute_ji();
07056 vector<float> compute_criterion(const vector <float>& Ji);
07057 int shutdown();
07058 private:
07059
07060 int m;
07061 int N;
07062 int n;
07063 int K;
07064 int nb_part;
07065 int n_start;
07066 int size_im;
07067 int size_IM;
07068 int size_AVE;
07069 int size_dist;
07070 int BLOCK_SIZE;
07071 int NB;
07072 int ins_BLOCK;
07073 int ite;
07074 float T;
07075
07076 int ct_im_mv;
07077
07078 float* h_IM;
07079 float* h_im;
07080 float* h_AVE;
07081 float* h_dist;
07082 float* h_AVE2;
07083 float* h_im2;
07084 unsigned short int* h_ASG;
07085 unsigned short int* h_asg;
07086 unsigned int* h_NC;
07087 int* params;
07088
07089 float* d_im;
07090 float* d_AVE;
07091 float* d_dist;
07092 };
07093
07094 #endif //EMAN2_USING_CUDA
07095
07096 #if 0
07097
07098 class XYZProcessor:public Processor
07099 {
07100 public:
07101 void process_inplace(EMData * image);
07102
07103 string get_name() const
07104 {
07105 return NAME;
07106 }
07107
07108 static Processor *NEW()
07109 {
07110 return new XYZProcessor();
07111 }
07112
07113 string get_desc() const
07114 {
07115 return "N/A";
07116 }
07117
07118 TypeDict get_param_types() const
07119 {
07120 TypeDict d;
07121 return d;
07122 }
07123
07124 static const string NAME;
07125 };
07126
07127
07128 #endif
07129
07130
07131 int multi_processors(EMData * image, vector < string > processornames);
07132 void dump_processors();
07133 map<string, vector<string> > dump_processors_list();
07134 map<string, vector<string> > group_processors();
07135
07136 template <> Factory < Processor >::Factory();
07137 }
07138
07139 #endif //eman_filter_h__
07140
07141
07142