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 DistanceSegmentProcessor: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("thr",EMObject::FLOAT,"Optional : Isosurface threshold value. Pixels below this will not be segment centers (default = 0.9)");
00694 d.put("minsegsep",EMObject::FLOAT,"Required: Minimum segment separation in pixels. Segments too close will trigger a reseed");
00695 d.put("maxsegsep",EMObject::FLOAT,"Required: Maximum segment separation in pixels. Segments too close will trigger a reseed");
00696 d.put("verbose",EMObject::INT,"Be verbose while running");
00697 return d;
00698 }
00699
00700 static Processor *NEW()
00701 {
00702 return new DistanceSegmentProcessor();
00703 }
00704
00705 string get_desc() const
00706 {
00707 return "Segments a volume into pieces separated by distances in the specified range.";
00708 }
00709
00710 static const string NAME;
00711
00712 };
00713
00720 class KmeansSegmentProcessor:public Processor
00721 {
00722 public:
00723 string get_name() const
00724 {
00725 return NAME;
00726 }
00727
00728 virtual EMData* process(const EMData * const image);
00729 void process_inplace( EMData * image);
00730
00731 TypeDict get_param_types() const
00732 {
00733 TypeDict d ;
00734 d.put("nseg", EMObject::INT, "Number of segments to divide the image into. default=12" );
00735 d.put("thr",EMObject::FLOAT,"Isosurface threshold value. Pixels below this will not be segmented");
00736 d.put("ampweight",EMObject::INT,"If set, will weight centers by voxel amplitude. default = 1");
00737 d.put("maxsegsize",EMObject::FLOAT,"Maximum radial distance from segment center to member voxel. Default=10000");
00738 d.put("minsegsep",EMObject::FLOAT,"Minimum segment separation. Segments too close will trigger a reseed");
00739 d.put("maxiter",EMObject::FLOAT,"Maximum number of iterations to run before stopping. Default=100");
00740 d.put("maxvoxmove",EMObject::FLOAT,"Maximum number of voxels that can move before quitting. Default=25");
00741 d.put("verbose",EMObject::INT,"Be verbose while running");
00742 return d;
00743 }
00744
00745 static Processor *NEW()
00746 {
00747 return new KmeansSegmentProcessor();
00748 }
00749
00750 string get_desc() const
00751 {
00752 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.";
00753 }
00754
00755 static const string NAME;
00756
00757 };
00758
00759
00766 class Wiener2DFourierProcessor:public Processor
00767 {
00768 public:
00769 string get_name() const
00770 {
00771 return NAME;
00772 }
00773
00774 virtual EMData* process(const EMData * const image);
00775
00776 void process_inplace(EMData *image);
00777
00778 void set_params(const Dict & new_params)
00779 {
00780 params = new_params;
00781 ctf = params["ctf"];
00782
00783 }
00784
00785 TypeDict get_param_types() const
00786 {
00787 TypeDict d;
00788 d.put("ctf", EMObject::EMDATA, "Ctf object to use for Wiener filter parameters");
00789 return d;
00790 }
00791
00792 static Processor *NEW()
00793 {
00794 return new Wiener2DFourierProcessor();
00795 }
00796
00797 string get_desc() const
00798 {
00799 return "Applies a 2-D Wiener filter to an image based on its Ctf parameters";
00800 }
00801
00802 static const string NAME;
00803
00804 protected:
00805 Ctf *ctf;
00806 };
00807
00808 class LinearRampFourierProcessor:public FourierProcessor
00809 {
00810 public:
00811 virtual string get_name() const
00812 {
00813 return NAME;
00814 }
00815
00816 virtual string get_desc() const
00817 {
00818 return "";
00819 }
00820
00821 static Processor *NEW()
00822 {
00823 return new LinearRampFourierProcessor();
00824 }
00825
00826 static const string NAME;
00827
00828 protected:
00829 virtual void create_radial_func(vector < float >&radial_mask) const ;
00830 };
00831
00834 class LowpassAutoBProcessor:public FourierAnlProcessor
00835 {
00836 public:
00837 string get_name() const
00838 {
00839 return NAME;
00840 }
00841
00842 static Processor *NEW()
00843 {
00844 return new LowpassAutoBProcessor();
00845 }
00846
00847 string get_desc() const
00848 {
00849 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.";
00850 }
00851
00852 static const string NAME;
00853
00854 virtual TypeDict get_param_types() const
00855 {
00856 TypeDict d = FourierAnlProcessor::get_param_types();
00857 d.put("bfactor", EMObject::FLOAT, "B-factor in terms of e^-(B s^2/4)");
00858 d.put("noisecutoff", EMObject::FLOAT, "Spatial frequency past which inverse-B will not be applied");
00859
00860 d.put("verbose", EMObject::INT, "Print information about the determined B-factor");
00861 return d;
00862 }
00863
00864 protected:
00865 virtual void preprocess(EMData * image) {
00866 if(params.has_key("apix")) {
00867 image->set_attr("apix_x", (float)params["apix"]);
00868 image->set_attr("apix_y", (float)params["apix"]);
00869 image->set_attr("apix_z", (float)params["apix"]);
00870 }
00871 float apix=(float)image->get_attr("apix_x");
00872
00873 const Dict dict = image->get_attr_dict();
00874 if (params.has_key("cutoff_abs")) {
00875 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00876 }
00877 else if( params.has_key("cutoff_freq") ) {
00878 float val = (float)params["cutoff_freq"] * apix;
00879 params["cutoff_abs"] = val;
00880 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00881 }
00882 else if( params.has_key("cutoff_pixels") ) {
00883 float val = 0.5f*(float)params["cutoff_pixels"] / (float)dict["nx"];
00884 params["cutoff_abs"] = val;
00885 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00886 }
00887 }
00888
00889 void create_radial_func(vector < float >&radial_mask,EMData *image) const;
00890 };
00891
00894 class HighpassAutoPeakProcessor:public FourierAnlProcessor
00895 {
00896 public:
00897 string get_name() const
00898 {
00899 return NAME;
00900 }
00901 static Processor *NEW()
00902 {
00903 return new HighpassAutoPeakProcessor();
00904 }
00905
00906 string get_desc() const
00907 {
00908 return "Attempts to automatically remove the low resolution peak present in virtually all cryoEM data.";
00909 }
00910
00911 static const string NAME;
00912
00913 protected:
00914 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
00915 virtual void preprocess(EMData * image);
00916 float highpass;
00917 };
00918
00923 class LinearRampProcessor:public FourierProcessor
00924 {
00925 public:
00926 LinearRampProcessor():intercept(0), slope(0)
00927 {
00928 }
00929
00930 string get_name() const
00931 {
00932 return NAME;
00933 }
00934 static Processor *NEW()
00935 {
00936 return new LinearRampProcessor();
00937 }
00938
00939 string get_desc() const
00940 {
00941 return "processor radial function: f(x) = slope * x + intercept;";
00942 }
00943
00944 void set_params(const Dict & new_params)
00945 {
00946 params = new_params;
00947 intercept = params["intercept"];
00948 slope = params["slope"];
00949 }
00950
00951 TypeDict get_param_types() const
00952 {
00953 TypeDict d;
00954 d.put("intercept", EMObject::FLOAT, "intercept in 'f(x) = slope * x + intercept'");
00955 d.put("slope", EMObject::FLOAT, "slope in 'f(x) = slope * x + intercept'");
00956 return d;
00957 }
00958
00959 static const string NAME;
00960
00961 protected:
00962 void create_radial_func(vector < float >&radial_mask) const;
00963
00964 private:
00965 float intercept;
00966 float slope;
00967 };
00968
00971 class RealPixelProcessor:public Processor
00972 {
00973 public:
00974 RealPixelProcessor():value(0), maxval(1), mean(0), sigma(0)
00975 {
00976 }
00977 void process_inplace(EMData * image);
00978
00979 virtual void set_params(const Dict & new_params)
00980 {
00981 params = new_params;
00982 if (params.size() == 1) {
00983 vector < EMObject > dict_values = params.values();
00984 value = dict_values[0];
00985 }
00986 }
00987
00988 static string get_group_desc()
00989 {
00990 return "The base class for real space processor working on individual pixels. The processor won't consider the pixel's coordinates and neighbors.";
00991 }
00992
00993 protected:
00994 virtual void process_pixel(float *x) const = 0;
00995 virtual void calc_locals(EMData *)
00996 {
00997 }
00998 virtual void normalize(EMData *) const
00999 {
01000 }
01001
01002 float value;
01003 float maxval;
01004 float mean;
01005 float sigma;
01006 };
01007
01010 class AbsoluateValueProcessor:public RealPixelProcessor
01011 {
01012 public:
01013 string get_name() const
01014 {
01015 return NAME;
01016 }
01017 static Processor *NEW()
01018 {
01019 return new AbsoluateValueProcessor();
01020 }
01021
01022 static const string NAME;
01023
01024 protected:
01025 void process_pixel(float *x) const
01026 {
01027 *x = fabs(*x);
01028 }
01029
01030 string get_desc() const
01031 {
01032 return "f(x) = |x|";
01033 }
01034 };
01035
01036
01039 class BooleanProcessor:public RealPixelProcessor
01040 {
01041 public:
01042 string get_name() const
01043 {
01044 return NAME;
01045 }
01046 static Processor *NEW()
01047 {
01048 return new BooleanProcessor();
01049 }
01050
01051 string get_desc() const
01052 {
01053 return "f(x) = 0 if x = 0; f(x) = 1 if x != 0;";
01054 }
01055
01056 static const string NAME;
01057
01058 protected:
01059 void process_pixel(float *x) const
01060 {
01061 if (*x != 0)
01062 {
01063 *x = 1.0;
01064 }
01065 }
01066 };
01067
01071 class InvertCarefullyProcessor:public RealPixelProcessor
01072 {
01073 public:
01074 string get_name() const
01075 {
01076 return NAME;
01077 }
01078 static Processor *NEW()
01079 {
01080 return new InvertCarefullyProcessor();
01081 }
01082
01083 void set_params(const Dict & new_params)
01084 {
01085 params = new_params;
01086 zero_to = params.set_default("zero_to",0.0f);
01087 }
01088
01089 TypeDict get_param_types() const
01090 {
01091 TypeDict d;
01092 d.put("zero_to", EMObject::FLOAT, "Inverted zero values are set to this value, default is 0.");
01093 return d;
01094 }
01095
01096 string get_desc() const
01097 {
01098 return "if f(x) != 0: f(x) = 1/f(x) else: f(x) = zero_to";
01099 }
01100
01101 static const string NAME;
01102
01103 protected:
01104 void process_pixel(float *x) const
01105 {
01106 if (*x == 0) *x = zero_to;
01107 else *x = 1/(*x);
01108 }
01109 private:
01110 float zero_to;
01111 };
01112
01116 class ValuePowProcessor:public RealPixelProcessor
01117 {
01118 public:
01119 string get_name() const
01120 {
01121 return NAME;
01122 }
01123 static Processor *NEW()
01124 {
01125 return new ValuePowProcessor();
01126 }
01127
01128 void set_params(const Dict & new_params)
01129 {
01130 params = new_params;
01131 pwr = params["pow"];
01132 }
01133
01134 TypeDict get_param_types() const
01135 {
01136 TypeDict d;
01137 d.put("pow", EMObject::FLOAT, "Each pixel is raised to this power");
01138 return d;
01139 }
01140
01141 string get_desc() const
01142 {
01143 return "f(x) = x ^ pow;";
01144 }
01145
01146 static const string NAME;
01147
01148 protected:
01149 void process_pixel(float *x) const
01150 {
01151 if (*x<0 && pwr!=(int)pwr) *x=0;
01152 else (*x) = pow(*x,pwr);
01153 }
01154 private:
01155 float pwr;
01156 };
01157
01160 class ValueSquaredProcessor:public RealPixelProcessor
01161 {
01162 public:
01163 string get_name() const
01164 {
01165 return NAME;
01166 }
01167 static Processor *NEW()
01168 {
01169 return new ValueSquaredProcessor();
01170 }
01171
01172
01173 string get_desc() const
01174 {
01175 return "f(x) = x * x;";
01176 }
01177
01178 static const string NAME;
01179
01180 protected:
01181 void process_pixel(float *x) const
01182 {
01183 (*x) *= (*x);
01184 }
01185 };
01186
01189 class ValueSqrtProcessor:public RealPixelProcessor
01190 {
01191 public:
01192 string get_name() const
01193 {
01194 return NAME;
01195 }
01196 static Processor *NEW()
01197 {
01198 return new ValueSqrtProcessor();
01199 }
01200
01201 string get_desc() const
01202 {
01203 return "f(x) = sqrt(x)";
01204 }
01205
01206 static const string NAME;
01207
01208 protected:
01209 void process_pixel(float *x) const
01210 {
01211 *x = sqrt(*x);
01212 }
01213 };
01214
01218 class ToZeroProcessor:public RealPixelProcessor
01219 {
01220 public:
01221 string get_name() const
01222 {
01223 return NAME;
01224 }
01225 static Processor *NEW()
01226 {
01227 return new ToZeroProcessor();
01228 }
01229 TypeDict get_param_types() const
01230 {
01231 TypeDict d;
01232 d.put("minval", EMObject::FLOAT, "Everything below this value is set to zero");
01233 return d;
01234 }
01235
01236 string get_desc() const
01237 {
01238 return "f(x) = x if x >= minval; f(x) = 0 if x < minval.";
01239 }
01240
01241 static const string NAME;
01242
01243 protected:
01244 inline void process_pixel(float *x) const
01245 {
01246 if (*x < value) {
01247 *x = 0;
01248 }
01249 }
01250 };
01251
01257 class Rotate180Processor:public Processor
01258 {
01259 public:
01260 string get_name() const
01261 {
01262 return NAME;
01263 }
01264 static Processor *NEW()
01265 {
01266 return new Rotate180Processor();
01267 }
01268
01272 void process_inplace(EMData* image);
01273
01274 string get_desc() const
01275 {
01276 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.";
01277 }
01278
01279 static const string NAME;
01280 };
01281
01288 class TransformProcessor:public Processor
01289 {
01290 public:
01291 virtual string get_name() const
01292 {
01293 return NAME;
01294 }
01295 static Processor *NEW()
01296 {
01297 return new TransformProcessor();
01298 }
01299
01304 virtual void process_inplace(EMData* image);
01305
01310 virtual EMData* process(const EMData* const image);
01311
01312 virtual TypeDict get_param_types() const
01313 {
01314 TypeDict d;
01315 d.put("transform", EMObject::TRANSFORM, "The Transform object that will be applied to the image" );
01316 return d;
01317 }
01318
01319 virtual string get_desc() const
01320 {
01321 return "The image is transformed using Transform parameter.";
01322 }
01323
01324 static const string NAME;
01325
01326 private:
01327 float* transform(const EMData* const image, const Transform& t) const;
01328
01329
01330
01331
01332 void assert_valid_aspect(const EMData* const image) const;
01333 };
01334
01342 class IntTranslateProcessor:public Processor
01343 {
01344 public:
01345 virtual string get_name() const
01346 {
01347 return NAME;
01348 }
01349
01350 static Processor *NEW()
01351 {
01352 return new IntTranslateProcessor();
01353 }
01354
01359 virtual void process_inplace(EMData* image);
01360
01365 virtual EMData* process(const EMData* const image);
01366
01367 virtual TypeDict get_param_types() const
01368 {
01369 TypeDict d;
01370 d.put("trans", EMObject::INTARRAY, "The displacement array, can be length 1-3" );
01371 return d;
01372 }
01373
01374 virtual string get_desc() const
01375 {
01376 return "The image is translated an integer amount";
01377 }
01378
01379 static const string NAME;
01380
01381 private:
01385 void assert_valid_aspect(const vector<int>& translation, const EMData* const image) const;
01386
01392 Region get_clip_region(vector<int>& translation, const EMData* const image) const;
01393 };
01394
01401 class ScaleTransformProcessor:public Processor
01402 {
01403 public:
01404 virtual string get_name() const
01405 {
01406 return NAME;
01407 }
01408 static Processor *NEW()
01409 {
01410 return new ScaleTransformProcessor();
01411 }
01412
01417 virtual void process_inplace(EMData* image);
01418
01423 virtual EMData* process(const EMData* const image);
01424
01425 virtual TypeDict get_param_types() const
01426 {
01427 TypeDict d;
01428 d.put("scale", EMObject::FLOAT, "The amount by which to scale" );
01429 d.put("clip", EMObject::INT, "The length of each output dimension. Non sophisticated, output dimensions can't be different" );
01432 return d;
01433 }
01434
01435 virtual string get_desc() const
01436 {
01437 return "The image is scaled with the clip variable in mind, being sure to preserve as much pixel information as possible.";
01438 }
01439
01440 static const string NAME;
01441 };
01442
01449 class ClampingProcessor :public Processor
01450 {
01451 public:
01452 ClampingProcessor() : default_max(1.0), default_min(0.0) {}
01453
01454 string get_name() const
01455 {
01456 return NAME;
01457 }
01458 static Processor *NEW()
01459 {
01460 return new ClampingProcessor();
01461 }
01462
01463 void process_inplace(EMData *image);
01464
01465 TypeDict get_param_types() const
01466 {
01467 TypeDict d;
01468 d.put("minval", EMObject::FLOAT, "The pixel values that bounds the smallest pixel value in the output image" );
01469 d.put("maxval", EMObject::FLOAT, "The pixel values that bounds the largest pixel value in the output image" );
01470 d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01471 return d;
01472 }
01473
01474 string get_desc() const
01475 {
01476 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.";
01477 }
01478
01479 static const string NAME;
01480
01481 protected:
01482 float default_max, default_min;
01483 };
01484
01490 class NSigmaClampingProcessor : public ClampingProcessor
01491 {
01492 public:
01493 NSigmaClampingProcessor() : default_sigma(2.0) {}
01494
01495 string get_name() const
01496 {
01497 return NAME;
01498 }
01499
01500 static Processor *NEW()
01501 {
01502 return new NSigmaClampingProcessor();
01503 }
01504
01505 TypeDict get_param_types() const
01506 {
01507 TypeDict d;
01508 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" );
01509 d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01510 return d;
01511 }
01512
01513 void process_inplace(EMData *image);
01514
01515 string get_desc() const
01516 {
01517 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.";
01518 }
01519
01520 static const string NAME;
01521
01522 protected:
01523 float default_sigma;
01524 };
01525
01529 class ToMinvalProcessor:public Processor
01530 {
01531 public:
01532 string get_name() const
01533 {
01534 return NAME;
01535 }
01536 static Processor *NEW()
01537 {
01538 return new ToMinvalProcessor();
01539 }
01540
01541 void process_inplace(EMData *image);
01542
01543 TypeDict get_param_types() const
01544 {
01545 TypeDict d;
01546 d.put("minval", EMObject::FLOAT, "Everything below this value is set to this value");
01547 d.put("newval", EMObject::FLOAT, "If set, values below minval will be set to newval instead of minval ");
01548 return d;
01549 }
01550
01551 string get_desc() const
01552 {
01553 return "f(x) = x if x >= minval; f(x) = minval|newval if x < minval.";
01554 }
01555
01556 static const string NAME;
01557
01558 protected:
01559
01560 };
01561
01562
01563
01567 class CutToZeroProcessor:public RealPixelProcessor
01568 {
01569 public:
01570 string get_name() const
01571 {
01572 return NAME;
01573 }
01574 static Processor *NEW()
01575 {
01576 return new CutToZeroProcessor();
01577 }
01578 TypeDict get_param_types() const
01579 {
01580 TypeDict d;
01581 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" );
01582 return d;
01583 }
01584
01585 string get_desc() const
01586 {
01587 return "f(x) = x-minval if x >= minval; f(x) = 0 if x < minval.";
01588 }
01589
01590 static const string NAME;
01591
01592 protected:
01593 void process_pixel(float *x) const
01594 {
01595 *x = *x - value;
01596 if (*x < 0) {
01597 *x = 0;
01598 }
01599 }
01600 };
01601
01605 class BinarizeProcessor:public RealPixelProcessor
01606 {
01607 public:
01608 string get_name() const
01609 {
01610 return NAME;
01611 }
01612 static Processor *NEW()
01613 {
01614 return new BinarizeProcessor();
01615 }
01616 TypeDict get_param_types() const
01617 {
01618 TypeDict d;
01619 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" );
01620 return d;
01621 }
01622
01623 string get_desc() const
01624 {
01625 return "f(x) = 0 if x < value; f(x) = 1 if x >= value.";
01626 }
01627
01628 static const string NAME;
01629
01630 protected:
01631 void process_pixel(float *x) const
01632 {
01633 if (*x < value)
01634 {
01635 *x = 0;
01636 }
01637 else
01638 {
01639 *x = 1;
01640 }
01641 }
01642 };
01643
01651 class BinarizeFourierProcessor:public Processor
01652 {
01653 public:
01654 virtual string get_name() const
01655 {
01656 return NAME;
01657 }
01658 static Processor *NEW()
01659 {
01660 return new BinarizeFourierProcessor();
01661 }
01662
01667 virtual void process_inplace(EMData* image);
01668
01669 virtual TypeDict get_param_types() const
01670 {
01671 TypeDict d;
01672 d.put("value", EMObject::FLOAT, "The Fourier amplitude threshold cutoff" );
01673 return d;
01674 }
01675
01676 virtual string get_desc() const
01677 {
01678 return "f(k) = 0 + 0i if ||f(k)|| < value; f(k) = a + bi if ||f(k)|| >= value.";
01679 }
01680
01681 static const string NAME;
01682 };
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01728 class CollapseProcessor:public RealPixelProcessor
01729 {
01730 public:
01731 string get_name() const
01732 {
01733 return NAME;
01734 }
01735 static Processor *NEW()
01736 {
01737 return new CollapseProcessor();
01738 }
01739
01740 void set_params(const Dict & new_params)
01741 {
01742 params = new_params;
01743 range = params["range"];
01744 value = params["value"];
01745 }
01746
01747 TypeDict get_param_types() const
01748 {
01749 TypeDict d;
01750 d.put("range", EMObject::FLOAT, "The range about 'value' which will be collapsed to 'value'");
01751 d.put("value", EMObject::FLOAT, "The pixel value where the focus of the collapse operation is");
01752 return d;
01753 }
01754
01755 string get_desc() const
01756 {
01757 return "f(x): if v-r<x<v+r -> v; if x>v+r -> x-r; if x<v-r -> x+r";
01758 }
01759
01760 static const string NAME;
01761
01762 protected:
01763 void process_pixel(float *x) const
01764 {
01765 if (*x>value+range) *x-=range;
01766 else if (*x<value-range) *x+=range;
01767 else *x=value;
01768 }
01769 float range;
01770 };
01771
01776 class LinearXformProcessor:public RealPixelProcessor
01777 {
01778 public:
01779 LinearXformProcessor():shift(0), scale(0)
01780 {
01781 }
01782
01783 string get_name() const
01784 {
01785 return NAME;
01786 }
01787 static Processor *NEW()
01788 {
01789 return new LinearXformProcessor();
01790 }
01791
01792 void set_params(const Dict & new_params)
01793 {
01794 params = new_params;
01795 shift = params.get("shift");
01796 scale = params.get("scale");
01797 }
01798
01799 TypeDict get_param_types() const
01800 {
01801 TypeDict d;
01802 d.put("shift", EMObject::FLOAT, "The amount to shift pixel values by before scaling");
01803 d.put("scale", EMObject::FLOAT, "The scaling factor to be applied to pixel values");
01804 return d;
01805 }
01806
01807 string get_desc() const
01808 {
01809 return "linear transform processor: f(x) = x * scale + shift. This is equivalent to a regular contrast stretching operation";
01810 }
01811
01812 static const string NAME;
01813
01814 protected:
01815 void process_pixel(float *x) const
01816 {
01817 *x = (*x) * scale + shift;
01818 }
01819
01820 private:
01821 float shift;
01822 float scale;
01823 };
01824
01829 class ExpProcessor:public RealPixelProcessor
01830 {
01831 public:
01832 ExpProcessor():low(0), high(0)
01833 {
01834 }
01835
01836 string get_name() const
01837 {
01838 return NAME;
01839 }
01840
01841 static Processor *NEW()
01842 {
01843 return new ExpProcessor();
01844 }
01845
01846 void set_params(const Dict & new_params)
01847 {
01848 params = new_params;
01849 low = params.get("low");
01850 high = params.get("high");
01851 }
01852
01853 TypeDict get_param_types() const
01854 {
01855 TypeDict d;
01856 d.put("low", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
01857 d.put("high", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
01858 return d;
01859 }
01860
01861 string get_desc() const
01862 {
01863 return "f(x) = exp( x / low - high)";
01864 }
01865
01866 static const string NAME;
01867
01868 protected:
01872 void process_pixel(float *x) const
01873 {
01874 float v = *x / low - high;
01875 if (v > 40) {
01876 v = 40;
01877 }
01878 *x = exp(v);
01879 }
01880
01881 private:
01882 float low;
01883 float high;
01884 };
01885
01889 class FiniteProcessor:public RealPixelProcessor
01890 {
01891 public:
01892 FiniteProcessor():to(0)
01893 {
01894 }
01895
01896 string get_name() const
01897 {
01898 return NAME;
01899 }
01900
01901 static Processor *NEW()
01902 {
01903 return new FiniteProcessor();
01904 }
01905
01906 void set_params(const Dict & new_params)
01907 {
01908 if (new_params.has_key("to") )
01909 to = params["to"];
01910 }
01911
01912 TypeDict get_param_types() const
01913 {
01914 TypeDict d;
01915 d.put("to", EMObject::FLOAT, "Pixels which are not finite will be set to this value");
01916 return d;
01917 }
01918
01919 string get_desc() const
01920 {
01921 return "f(x) = f(x) if f(x) is finite | to if f(x) is not finite";
01922 }
01923
01924 static const string NAME;
01925
01926 protected:
01930 void process_pixel(float *x) const;
01931 private:
01932 float to;
01933 };
01934
01939 class RangeThresholdProcessor:public RealPixelProcessor
01940 {
01941 public:
01942 RangeThresholdProcessor():low(0), high(0)
01943 {
01944 }
01945
01946 string get_name() const
01947 {
01948 return NAME;
01949 }
01950 static Processor *NEW()
01951 {
01952 return new RangeThresholdProcessor();
01953 }
01954
01955 void set_params(const Dict & new_params)
01956 {
01957 params = new_params;
01958 low = params.get("low");
01959 high = params.get("high");
01960 }
01961
01962 TypeDict get_param_types() const
01963 {
01964 TypeDict d;
01965 d.put("low", EMObject::FLOAT, "The lower limit of the range that will be set to 1");
01966 d.put("high", EMObject::FLOAT, "The upper limit of the range that will be set to 1");
01967 return d;
01968 }
01969
01970 string get_desc() const
01971 {
01972 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";
01973 }
01974
01975 static const string NAME;
01976
01977 protected:
01978 void process_pixel(float *x) const
01979 {
01980 if (*x >= low && *x <= high) {
01981 *x = 1;
01982 }
01983 else {
01984 *x = 0;
01985 }
01986 }
01987 private:
01988 float low;
01989 float high;
01990
01991 };
01992
01997 class SigmaProcessor:public RealPixelProcessor
01998 {
01999 public:
02000 string get_name() const
02001 {
02002 return NAME;
02003 }
02004 static Processor *NEW()
02005 {
02006 return new SigmaProcessor();
02007 }
02008
02009 void set_params(const Dict & new_params)
02010 {
02011 params = new_params;
02012 value1 = params.get("value1");
02013 value2 = params.get("value2");
02014 }
02015
02016 TypeDict get_param_types() const
02017 {
02018 TypeDict d;
02019 d.put("value1", EMObject::FLOAT, "A number reflecting total standard deviations in the right direction");
02020 d.put("value2", EMObject::FLOAT, "A number reflecting total standard deviations in the left direction");
02021 return d;
02022 }
02023
02024 string get_desc() const
02025 {
02026 return "f(x) = mean if x<(mean-v2*sigma) or x>(mean+v1*sigma); else f(x) = x;";
02027 }
02028
02029 static const string NAME;
02030
02031 protected:
02032 void process_pixel(float *x) const
02033 {
02034 if (*x < (mean - value2 * sigma) || *x > (mean + value1 * sigma))
02035 {
02036 *x = mean;
02037 }
02038 }
02039
02040 private:
02041 float value1;
02042 float value2;
02043 };
02044
02047 class LogProcessor:public RealPixelProcessor
02048 {
02049 public:
02050 string get_name() const
02051 {
02052 return NAME;
02053 }
02054 static Processor *NEW()
02055 {
02056 return new LogProcessor();
02057 }
02058
02059 string get_desc() const
02060 {
02061 return "f(x) = log10(x) if x > 0; else f(x) = 0;";
02062 }
02063
02064 static const string NAME;
02065
02066 protected:
02067 void process_pixel(float *x) const
02068 {
02069 if (*x > 0)
02070 {
02071 *x = log10(*x);
02072 }
02073 else
02074 {
02075 *x = 0;
02076 }
02077 }
02078 };
02079
02082 class CoordinateProcessor:public Processor
02083 {
02084 public:
02085 CoordinateProcessor():nx(0), ny(0), nz(0), mean(0), sigma(0), maxval(0), is_complex(false)
02086 {
02087 }
02088 void process_inplace(EMData * image);
02089
02090 static string get_group_desc()
02091 {
02092 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().";
02093 }
02094
02095 protected:
02096 virtual void process_pixel(float *pixel, int xi, int yi, int zi) const = 0;
02097 virtual void calc_locals(EMData *)
02098 {
02099 }
02100 virtual bool is_valid() const
02101 {
02102 return true;
02103 }
02104
02105 int nx;
02106 int ny;
02107 int nz;
02108 float mean;
02109 float sigma;
02110 float maxval;
02111
02112 bool is_complex;
02113 };
02114
02122 class CircularMaskProcessor:public CoordinateProcessor
02123 {
02124 public:
02125 CircularMaskProcessor():inner_radius(0), outer_radius(0), inner_radius_square(0),
02126 outer_radius_square(0), dx(0), dy(0), dz(0), xc(0), yc(0), zc(0)
02127 {
02128 }
02129
02130 void set_params(const Dict & new_params)
02131 {
02132 params = new_params;
02133
02134 if (params.has_key("inner_radius")) {
02135 inner_radius = params["inner_radius"];
02136 inner_radius_square = inner_radius * inner_radius;
02137 }
02138 else {
02139 inner_radius = -1;
02140 inner_radius_square = -1;
02141 }
02142
02143 if (params.has_key("outer_radius")) {
02144 outer_radius = params["outer_radius"];
02145 outer_radius_square = outer_radius * outer_radius;
02146 }
02147 else {
02148 outer_radius = INT_MAX;
02149 outer_radius_square = INT_MAX;
02150 }
02151
02152 if (params.has_key("xc")) xc = params["xc"];
02153 if (params.has_key("yc")) yc = params["yc"];
02154 if (params.has_key("zc")) zc = params["zc"];
02155 if (params.has_key("dx")) dx = params["dx"];
02156 if (params.has_key("dy")) dy = params["dy"];
02157 if (params.has_key("dz")) dz = params["dz"];
02158 }
02159
02160 string get_desc() const
02161 {
02162 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().";
02163 }
02164
02165 TypeDict get_param_types() const
02166 {
02167 TypeDict d;
02168
02169 d.put("inner_radius", EMObject::INT, "inner mask radius. optional, default=-1");
02170 d.put("outer_radius", EMObject::INT, "outer mask radius");
02171
02172 d.put("dx", EMObject::FLOAT,
02173 "Modify mask center by dx relative to the default center nx/2");
02174 d.put("dy", EMObject::FLOAT,
02175 "Modify mask center by dy relative to the default center ny/2");
02176 d.put("dz", EMObject::FLOAT,
02177 "Modify mask center by dz relative to the default center nz/2");
02178
02179 return d;
02180 }
02181 protected:
02182 void calc_locals(EMData * image);
02183
02184 bool is_valid() const
02185 {
02186 return (!is_complex);
02187 }
02188
02189 void process_pixel(float *pixel, int xi, int yi, int zi) const
02190 {
02191 float dist = (xi - xc) * (xi - xc) + (yi - yc) * (yi - yc) + (zi - zc) * (zi - zc);
02192 process_dist_pixel(pixel, dist);
02193 }
02194
02195 virtual void process_dist_pixel(float *pixel, float dist) const = 0;
02196
02197 int inner_radius;
02198 int outer_radius;
02199 int inner_radius_square;
02200 int outer_radius_square;
02201 float dx, dy, dz;
02202 float xc, yc, zc;
02203 };
02204
02208 class MaskSharpProcessor:public CircularMaskProcessor
02209 {
02210 public:
02211 MaskSharpProcessor():value(0)
02212 {
02213 }
02214
02215 string get_name() const
02216 {
02217 return NAME;
02218 }
02219 static Processor *NEW()
02220 {
02221 return new MaskSharpProcessor();
02222 }
02223
02224 void set_params(const Dict & new_params)
02225 {
02226 CircularMaskProcessor::set_params(new_params);
02227 value = params.set_default("value",0.0f);
02228 }
02229
02230 TypeDict get_param_types() const
02231 {
02232 TypeDict d = CircularMaskProcessor::get_param_types();
02233 d.put("value", EMObject::FLOAT, "step cutoff to this value. Default is 0.");
02234 return d;
02235 }
02236
02237 string get_desc() const
02238 {
02239 return "step cutoff to a user-given value in both inner and outer circles.";
02240 }
02241
02242 static const string NAME;
02243
02244 protected:
02245 void process_dist_pixel(float *pixel, float dist) const
02246 {
02247 if (dist >= outer_radius_square || dist < inner_radius_square)
02248 {
02249 *pixel = value;
02250 }
02251 }
02252
02253 float value;
02254 };
02255
02256
02260 class MaskEdgeMeanProcessor:public CircularMaskProcessor
02261 {
02262 public:
02263 string get_name() const
02264 {
02265 return NAME;
02266 }
02267 static Processor *NEW()
02268 {
02269 return new MaskEdgeMeanProcessor();
02270 }
02271
02272 void set_params(const Dict & new_params)
02273 {
02274 CircularMaskProcessor::set_params(new_params);
02275 ring_width = params["ring_width"];
02276 if (ring_width == 0) {
02277 ring_width = 1;
02278 }
02279 }
02280
02281 TypeDict get_param_types() const
02282 {
02283 TypeDict d = CircularMaskProcessor::get_param_types();
02284 d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02285 return d;
02286 }
02287
02288 string get_desc() const
02289 {
02290 return "A step cutoff to the the mean value in a ring centered on the outer radius";
02291 }
02292
02293 static const string NAME;
02294
02295 protected:
02296 void calc_locals(EMData * image);
02297
02298
02299 void process_dist_pixel(float *pixel, float dist) const
02300 {
02301 if (dist >= outer_radius_square || dist < inner_radius_square){
02302 *pixel = ring_avg;
02303 }
02304 }
02305
02306 private:
02307 int ring_width;
02308 float ring_avg;
02309 };
02310
02313 class MaskNoiseProcessor:public CircularMaskProcessor
02314 {
02315 public:
02316 string get_name() const
02317 {
02318 return NAME;
02319 }
02320 static Processor *NEW()
02321 {
02322 return new MaskNoiseProcessor();
02323 }
02324
02325 string get_desc() const
02326 {
02327 return "fills masked region";
02328 }
02329
02330 static const string NAME;
02331
02332 protected:
02333 void process_dist_pixel(float *pixel, float dist) const
02334 {
02335 if (dist >= outer_radius_square || dist < inner_radius_square)
02336 {
02337 *pixel = Util::get_gauss_rand(mean, sigma);
02338 }
02339 }
02340 };
02341
02344 class MaskGaussProcessor:public CircularMaskProcessor
02345 {
02346 public:
02347 string get_name() const
02348 {
02349 return NAME;
02350 }
02351 static Processor *NEW()
02352 {
02353 return new MaskGaussProcessor();
02354 }
02355
02356 void set_params(const Dict & new_params)
02357 {
02358 CircularMaskProcessor::set_params(new_params);
02359 exponent = params["exponent"];
02360 if (exponent <= 0.0) {
02361 exponent = 2.0;
02362 }
02363 }
02364
02365 TypeDict get_param_types() const
02366 {
02367 TypeDict d = CircularMaskProcessor::get_param_types();
02368 d.put("exponent", EMObject::FLOAT, "The exponent, f in e^-Bs^f. default 2.0, producing a Gaussian");
02369 return d;
02370 }
02371
02372 string get_desc() const
02373 {
02374 return "a gaussian falloff to zero, radius is the 1/e of the width. If inner_radius>0, then \
02375 outer radius specifies width of Gaussian starting at inner_radius rather than total radius.";
02376 }
02377
02378 static const string NAME;
02379
02380 protected:
02381 float exponent;
02382 void process_dist_pixel(float *pixel, float dist) const
02383 {
02384 if (inner_radius_square>0) {
02385 if (dist>inner_radius_square) {
02386 if (exponent==2.0f) (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,2.0f) / outer_radius_square);
02387 else (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,exponent) / pow((float)outer_radius_square,exponent/2.0f));
02388 }
02389 }
02390 else {
02391 if (exponent==2.0f) (*pixel) *= exp(-dist / outer_radius_square);
02392 else (*pixel) *= exp(-pow(dist,exponent/2.0f) / pow((float)outer_radius_square,exponent/2.0f));
02393 }
02394 }
02395 };
02396
02403 class MaskGaussNonuniformProcessor:public CoordinateProcessor
02404 {
02405 public:
02406 MaskGaussNonuniformProcessor():radius_x(0), radius_y(0), radius_z(0), gauss_width(0)
02407 {
02408 }
02409
02410 void set_params(const Dict & new_params)
02411 {
02412 params = new_params;
02413
02414 if (params.has_key("radius_x")) radius_x=params["radius_x"];
02415 else radius_x=5.0;
02416
02417 if (params.has_key("radius_y")) radius_y=params["radius_y"];
02418 else radius_y=5.0;
02419
02420 if (params.has_key("radius_z")) radius_z=params["radius_z"];
02421 else radius_z=5.0;
02422
02423 if (params.has_key("gauss_width")) gauss_width=params["gauss_width"];
02424 else gauss_width=0.05f;
02425 }
02426
02427 TypeDict get_param_types() const
02428 {
02429 TypeDict d;
02430
02431 d.put("radius_x", EMObject::INT, "x-axis radius");
02432 d.put("radius_y", EMObject::INT, "y-axis radius");
02433 d.put("radius_z", EMObject::INT, "z-axis radius");
02434 d.put("gauss_width", EMObject::FLOAT, "Gaussian falloff width, relative to each radius, default 0.05");
02435
02436 return d;
02437 }
02438
02439 string get_name() const
02440 {
02441 return NAME;
02442 }
02443 static Processor *NEW()
02444 {
02445 return new MaskGaussNonuniformProcessor();
02446 }
02447
02448 string get_desc() const
02449 {
02450 return "A Gaussian falloff to zero. Nonisotropic, specify inner radius for x,y,z and Gaussian falloff width. Falloff \
02451 width is also nonisotropic and relative to the radii, with 1 being equal to the radius on that axis.";
02452 }
02453
02454 static const string NAME;
02455
02456 protected:
02457 void process_pixel(float *pixel, int xi, int yi, int zi) const
02458 {
02459 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);
02460 if (dist>1.0) (*pixel)*=exp(-pow((sqrt(dist)-1.0f)/gauss_width,2.0f));
02461 }
02462
02463 float radius_x,radius_y,radius_z,gauss_width;
02464 };
02465
02470 class MaskGaussInvProcessor:public CircularMaskProcessor
02471 {
02472 public:
02473 TypeDict get_param_types() const
02474 {
02475 TypeDict d = CircularMaskProcessor::get_param_types();
02476 d.put("gauss_width", EMObject::FLOAT, "Used to calculate the constant factor - gauss_width / (ny*ny)" );
02477 d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02478 return d;
02479 }
02480
02481 string get_name() const
02482 {
02483 return NAME;
02484 }
02485
02486 static Processor *NEW()
02487 {
02488 return new MaskGaussInvProcessor();
02489 }
02490
02491 string get_desc() const
02492 {
02493 return "f(x) = f(x) / exp(-radius*radius * gauss_width / (ny*ny))";
02494 }
02495
02496 static const string NAME;
02497
02498 protected:
02499 void calc_locals(EMData *)
02500 {
02501 float gauss_width = params["gauss_width"];
02502 slice_value = gauss_width / (ny * ny);
02503 }
02504
02505 void process_dist_pixel(float *pixel, float dist) const
02506 {
02507 (*pixel) /= exp(-dist * slice_value);
02508 }
02509 private:
02510 float slice_value;
02511 };
02512
02513
02518 class LinearPyramidProcessor:public Processor
02519 {
02520 public:
02521 string get_name() const
02522 {
02523 return NAME;
02524 }
02525
02526 void process_inplace(EMData *image);
02527
02528 static Processor *NEW()
02529 {
02530 return new LinearPyramidProcessor();
02531 }
02532
02533 string get_desc() const
02534 {
02535 return "Multiplies image by a 'linear pyramid', 1-(|x-xsize/2|*|y-ysize/2|*4/(xsize*ysize))";
02536 }
02537
02538 static const string NAME;
02539 };
02540
02541
02544 class MakeRadiusSquaredProcessor:public CircularMaskProcessor
02545 {
02546 public:
02547 string get_name() const
02548 {
02549 return NAME;
02550 }
02551 static Processor *NEW()
02552 {
02553 return new MakeRadiusSquaredProcessor();
02554 }
02555
02556 string get_desc() const
02557 {
02558 return "overwrites input, f(x) = radius * radius";
02559 }
02560
02561 static const string NAME;
02562
02563 protected:
02564 void process_dist_pixel(float *pixel, float dist) const
02565 {
02566 *pixel = dist;
02567 }
02568 };
02569
02572 class MakeRadiusProcessor:public CircularMaskProcessor
02573 {
02574 public:
02575 string get_name() const
02576 {
02577 return NAME;
02578 }
02579 static Processor *NEW()
02580 {
02581 return new MakeRadiusProcessor();
02582 }
02583
02584 string get_desc() const
02585 {
02586 return "overwrites input, f(x) = radius;";
02587 }
02588
02589 static const string NAME;
02590
02591 protected:
02592 void process_dist_pixel(float *pixel, float dist) const
02593 {
02594 *pixel = sqrt(dist);
02595 }
02596 };
02597
02600 class ComplexPixelProcessor:public Processor
02601 {
02602 public:
02603 void process_inplace(EMData * image);
02604
02605 static string get_group_desc()
02606 {
02607 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.";
02608 }
02609
02610 protected:
02611 virtual void process_pixel(float *x) const = 0;
02612 };
02613
02616 class ComplexNormPixel:public ComplexPixelProcessor
02617 {
02618 public:
02619 string get_name() const
02620 {
02621 return NAME;
02622 }
02623 static Processor *NEW()
02624 {
02625 return new ComplexNormPixel();
02626 }
02627
02628 string get_desc() const
02629 {
02630 return "Each Fourier pixel will be normalized. ie - amp=1, phase=unmodified. Useful for performing phase-residual-like computations with dot products.";
02631 }
02632
02633 static const string NAME;
02634
02635 protected:
02636 void process_pixel(float *x) const
02637 {
02638 *x=1.0;
02639 }
02640 };
02641
02645 class AreaProcessor:public Processor
02646 {
02647 public:
02648 AreaProcessor():areasize(0), kernel(0), nx(0), ny(0), nz(0)
02649 {
02650 }
02651
02652 void process_inplace(EMData * image);
02653
02654 void set_params(const Dict & new_params)
02655 {
02656 params = new_params;
02657 areasize = params["areasize"];
02658 }
02659
02660 TypeDict get_param_types() const
02661 {
02662 TypeDict d;
02663 d.put("areasize", EMObject::INT, "The width of the area to process (not radius)");
02664 return d;
02665 }
02666
02667 string get_desc() const
02668 {
02669 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().";
02670 }
02671
02672 protected:
02673 virtual void process_pixel(float *pixel, float, float, float, float *area_matrix) const
02674 {
02675 for (int i = 0; i < matrix_size; i++)
02676 {
02677 *pixel += area_matrix[i] * kernel[i];
02678 }
02679 }
02680
02681 virtual void create_kernel() const = 0;
02682
02683 int areasize;
02684 int matrix_size;
02685 float *kernel;
02686 int nx;
02687 int ny;
02688 int nz;
02689 };
02690
02693 class LaplacianProcessor:public AreaProcessor
02694 {
02695 public:
02696 string get_name() const
02697 {
02698 return NAME;
02699 }
02700 static Processor *NEW()
02701 {
02702 return new LaplacianProcessor();
02703 }
02704
02705 string get_desc() const
02706 {
02707 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).";
02708 }
02709
02710 static const string NAME;
02711
02712 protected:
02713 void create_kernel() const;
02714
02715 };
02716
02719 class ZeroConstantProcessor:public AreaProcessor
02720 {
02721 public:
02722 string get_name() const
02723 {
02724 return NAME;
02725 }
02726 static Processor *NEW()
02727 {
02728 return new ZeroConstantProcessor();
02729 }
02730
02731 string get_desc() const
02732 {
02733 return "Contraction of data, if any nearest neighbor is 0, value -> 0, generally used iteratively";
02734 }
02735
02736 static const string NAME;
02737
02738 protected:
02739 void process_pixel(float *pixel, float, float, float, float *matrix) const
02740 {
02741 if (*pixel != 0)
02742 {
02743 if (*pixel == matrix[1] || *pixel == matrix[3] || *pixel == matrix[5] ||
02744 *pixel == matrix[7] || matrix[1] == 0 || matrix[3] == 0 ||
02745 matrix[5] == 0 || matrix[7] == 0) {
02746 *pixel = 0;
02747 }
02748 }
02749 }
02750
02751 void create_kernel() const
02752 {
02753 }
02754 };
02755
02764 class BoxStatProcessor:public Processor
02765 {
02766 public:
02767 void process_inplace(EMData * image);
02768
02769 static string get_group_desc()
02770 {
02771 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).";
02772 }
02773
02774 TypeDict get_param_types() const
02775 {
02776 TypeDict d;
02777 d.put("radius", EMObject::INT, "The radius of the search box, default is 1 which results in a 3x3 box (3 = 2xradius + 1)");
02778 return d;
02779 }
02780
02781 protected:
02782 virtual void process_pixel(float *pixel, const float *array, int n) const = 0;
02783 };
02784
02785
02788 class BoxMedianProcessor:public BoxStatProcessor
02789 {
02790 public:
02791 string get_name() const
02792 {
02793 return NAME;
02794 }
02795 static Processor *NEW()
02796 {
02797 return new BoxMedianProcessor();
02798 }
02799
02800 string get_desc() const
02801 {
02802 return "A processor for noise reduction. pixel = median of values surrounding pixel.";
02803 }
02804
02805 static const string NAME;
02806
02807 protected:
02808 void process_pixel(float *pixel, const float *array, int n) const
02809 {
02810 float *data = new float[n];
02811 memcpy(data, array, sizeof(float) * n);
02812
02813 for (int i = 0; i <= n / 2; i++)
02814 {
02815 for (int j = i + 1; j < n; j++)
02816 {
02817 if (data[i] < data[j]) {
02818 float t = data[i];
02819 data[i] = data[j];
02820 data[j] = t;
02821 }
02822 }
02823 }
02824
02825 if (n % 2 != 0)
02826 {
02827 *pixel = data[n / 2];
02828 }
02829 else {
02830 *pixel = (data[n / 2] + data[n / 2 - 1]) / 2;
02831 }
02832 if( data )
02833 {
02834 delete[]data;
02835 data = 0;
02836 }
02837 }
02838 };
02839
02842 class BoxSigmaProcessor:public BoxStatProcessor
02843 {
02844 public:
02845 string get_name() const
02846 {
02847 return NAME;
02848 }
02849 static Processor *NEW()
02850 {
02851 return new BoxSigmaProcessor();
02852 }
02853
02854 string get_desc() const
02855 {
02856 return "pixel = standard deviation of values surrounding pixel.";
02857 }
02858
02859 static const string NAME;
02860
02861 protected:
02862 void process_pixel(float *pixel, const float *data, int n) const
02863 {
02864 float sum = 0;
02865 float square_sum = 0;
02866 for (int i = 0; i < n; i++)
02867 {
02868 sum += data[i];
02869 square_sum += data[i] * data[i];
02870 }
02871
02872 float mean = sum / n;
02873 *pixel = sqrt(square_sum / n - mean * mean);
02874 }
02875 };
02876
02879 class BoxMaxProcessor:public BoxStatProcessor
02880 {
02881 public:
02882 string get_name() const
02883 {
02884 return NAME;
02885 }
02886 static Processor *NEW()
02887 {
02888 return new BoxMaxProcessor();
02889 }
02890
02891 string get_desc() const
02892 {
02893 return "peak processor: pixel = max of values surrounding pixel.";
02894 }
02895
02896 static const string NAME;
02897
02898 protected:
02899 void process_pixel(float *pixel, const float *data, int n) const
02900 {
02901 float maxval = -FLT_MAX;
02902 for (int i = 0; i < n; i++)
02903 {
02904 if (data[i] > maxval) {
02905 maxval = data[i];
02906 }
02907 }
02908 *pixel = maxval;
02909 }
02910 };
02911
02914 class MinusPeakProcessor:public BoxStatProcessor
02915 {
02916 public:
02917 string get_name() const
02918 {
02919 return NAME;
02920 }
02921 static Processor *NEW()
02922 {
02923 return new MinusPeakProcessor();
02924 }
02925
02926 string get_desc() const
02927 {
02928 return "peak processor: pixel = pixel - max of values surrounding pixel. This is a sort of positive peak-finding algorithm.";
02929 }
02930
02931 static const string NAME;
02932
02933 protected:
02934 void process_pixel(float *pixel, const float *data, int n) const
02935 {
02936 float maxval = -FLT_MAX;
02937 for (int i = 0; i < n; i++)
02938 {
02939 if (data[i] > maxval) {
02940 maxval = data[i];
02941 }
02942 }
02943 *pixel -= maxval;
02944 }
02945 };
02946
02950 class PeakOnlyProcessor:public BoxStatProcessor
02951 {
02952 public:
02953 string get_name() const
02954 {
02955 return NAME;
02956 }
02957 static Processor *NEW()
02958 {
02959 return new PeakOnlyProcessor();
02960 }
02961 void set_params(const Dict & new_params)
02962 {
02963 params = new_params;
02964 npeaks = params["npeaks"];
02965 if (npeaks == 0) {
02966 npeaks = 1;
02967 }
02968 }
02969
02970 TypeDict get_param_types() const
02971 {
02972 TypeDict d;
02973 d.put("npeaks", EMObject::INT, "the number of surrounding peaks allow to >= pixel values");
02974 return d;
02975 }
02976
02977 string get_desc() const
02978 {
02979 return "peak processor -> if npeaks or more surrounding values >= value, value->0";
02980 }
02981
02982 static const string NAME;
02983
02984 protected:
02985 void process_pixel(float *pixel, const float *data, int n) const
02986 {
02987 int r = 0;
02988
02989 for (int i = 0; i < n; i++)
02990 {
02991 if (data[i] >= *pixel) {
02992 r++;
02993 }
02994 }
02995
02996 if (r > npeaks)
02997 {
02998 *pixel = 0;
02999 }
03000 }
03001 private:
03002 int npeaks;
03003 };
03004
03009 class DiffBlockProcessor:public Processor
03010 {
03011 public:
03012 void process_inplace(EMData * image);
03013
03014 string get_name() const
03015 {
03016 return NAME;
03017 }
03018 static Processor *NEW()
03019 {
03020 return new DiffBlockProcessor();
03021 }
03022
03023 string get_desc() const
03024 {
03025 return "averages over cal_half_width, then sets the value in a local block";
03026 }
03027
03028 TypeDict get_param_types() const
03029 {
03030 TypeDict d;
03031 d.put("cal_half_width", EMObject::FLOAT, "cal_half_width is dx/dy for calculating an average");
03032 d.put("fill_half_width", EMObject::FLOAT, "fill_half_width is dx/dy for fill/step");
03033 return d;
03034 }
03035
03036 static const string NAME;
03037 };
03038
03043 class CutoffBlockProcessor:public Processor
03044 {
03045 public:
03046 void process_inplace(EMData * image);
03047
03048 string get_name() const
03049 {
03050 return NAME;
03051 }
03052 static Processor *NEW()
03053 {
03054 return new CutoffBlockProcessor();
03055 }
03056
03057 TypeDict get_param_types() const
03058 {
03059 TypeDict d;
03060 d.put("value1", EMObject::FLOAT, "val1 is dx/dy");
03061 d.put("value2", EMObject::FLOAT, "val2 is lowpass freq cutoff in pixels");
03062 return d;
03063 }
03064
03065 string get_desc() const
03066 {
03067 return "Block processor, val1 is dx/dy, val2 is lp freq cutoff in pixels. Mystery processor.";
03068 }
03069
03070 static const string NAME;
03071 };
03072
03078 class BooleanShrinkProcessor
03079 {
03080 protected:
03088 template<class LogicOp>
03089 EMData* process(const EMData *const image, Dict& params);
03090
03097 template<class LogicOp>
03098 void process_inplace(EMData * image, Dict& params);
03099
03100 };
03101
03110 class MaxShrinkProcessor:public BooleanShrinkProcessor, public Processor
03111 {
03112 public:
03119 virtual EMData* process(const EMData *const image)
03120 {
03121 return BooleanShrinkProcessor::process<GreaterThan>(image, params);
03122 }
03123
03124
03125 virtual void process_inplace(EMData * image)
03126 {
03127 BooleanShrinkProcessor::process_inplace<GreaterThan>(image, params);
03128 }
03129
03130 string get_desc() const
03131 {
03132 return "Shrink an image by a given amount (default 2), using the maximum value found in the pixel neighborhood.";
03133 }
03134
03135 string get_name() const
03136 {
03137 return NAME;
03138 }
03139 static Processor *NEW()
03140 {
03141 return new MaxShrinkProcessor();
03142 }
03143
03144 TypeDict get_param_types() const
03145 {
03146 TypeDict d;
03147 d.put("n", EMObject::INT, "The shrink factor");
03148 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03149 return d;
03150 }
03151
03152 static const string NAME;
03153
03154 private:
03155 struct GreaterThan
03156 {
03157 inline bool operator()(float left,float right) const { return left > right; }
03158 inline float get_start_val() { return -10000000; }
03159 };
03160 };
03161
03170 class MinShrinkProcessor:public BooleanShrinkProcessor, public Processor
03171 {
03172 public:
03179 virtual EMData* process(const EMData *const image)
03180 {
03181 return BooleanShrinkProcessor::process<LessThan>(image, params);
03182 }
03183
03184
03185 virtual void process_inplace(EMData * image)
03186 {
03187 BooleanShrinkProcessor::process_inplace<LessThan>(image, params);
03188 }
03189 string get_desc() const
03190 {
03191 return "Shrink an image by a given amount (default 2), using the minimum value found in the pixel neighborhood.";
03192 }
03193
03194 string get_name() const
03195 {
03196 return NAME;
03197 }
03198 static Processor *NEW()
03199 {
03200 return new MinShrinkProcessor();
03201 }
03202
03203 TypeDict get_param_types() const
03204 {
03205 TypeDict d;
03206 d.put("n", EMObject::INT, "The shrink factor");
03207 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03208 return d;
03209 }
03210
03211 static const string NAME;
03212
03213 private:
03214 struct LessThan
03215 {
03216 inline bool operator()(float left,float right) const { return left < right; }
03217 inline float get_start_val() { return 9999999999.0f; }
03218 };
03219 };
03220
03227 class MeanShrinkProcessor : public Processor
03228 {
03229 public:
03240 virtual EMData* process(const EMData *const image);
03241
03248 virtual void process_inplace(EMData * image);
03249
03250 string get_desc() const
03251 {
03252 return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
03253 }
03254
03255 virtual string get_name() const
03256 {
03257 return NAME;
03258 }
03259 static Processor *NEW()
03260 {
03261 return new MeanShrinkProcessor();
03262 }
03263
03264 virtual TypeDict get_param_types() const
03265 {
03266 TypeDict d;
03267 d.put("n", EMObject::FLOAT, "The shrink factor");
03268 return d;
03269 }
03270
03271 static const string NAME;
03272
03273 private:
03281 void accrue_mean(EMData* to, const EMData *const from, const int shrinkfactor);
03282
03289 void accrue_mean_one_p_five(EMData* to, const EMData * const from);
03290 };
03291
03292
03299 class MedianShrinkProcessor : public Processor
03300 {
03301 public:
03312 virtual EMData* process(const EMData *const image);
03313
03320 virtual void process_inplace(EMData * image);
03321
03322 string get_desc() const
03323 {
03324 return "Shrink an image by a given amount , using the median value found in the pixel neighborhood.";
03325 }
03326
03327 virtual string get_name() const
03328 {
03329 return NAME;
03330 }
03331 static Processor *NEW()
03332 {
03333 return new MedianShrinkProcessor();
03334 }
03335
03336 virtual TypeDict get_param_types() const
03337 {
03338 TypeDict d;
03339 d.put("n", EMObject::INT, "The shrink factor");
03340 return d;
03341 }
03342
03343 static const string NAME;
03344
03345 private:
03353 void accrue_median(EMData* to, const EMData* const from,const int shrink_factor);
03354 };
03355
03356
03365 class FFTResampleProcessor : public Processor
03366 {
03367 public:
03368 virtual EMData* process(const EMData *const image);
03369
03370 virtual void process_inplace(EMData * image);
03371
03372 string get_desc() const
03373 {
03374 return "Robust resampling of an image by clipping its Fourier transform.";
03375 }
03376
03377 string get_name() const
03378 {
03379 return NAME;
03380 }
03381 static Processor *NEW()
03382 {
03383 return new FFTResampleProcessor();
03384 }
03385
03386 TypeDict get_param_types() const
03387 {
03388 TypeDict d;
03389 d.put("n", EMObject::FLOAT, "The sample rate. Less than one enlarges the image, greater than one shrinks it.");
03390 return d;
03391 }
03392
03393 static const string NAME;
03394
03395 private:
03402 void fft_resample(EMData* to, const EMData *const from, const float& sample_rate);
03403
03404 };
03405
03408 class GradientRemoverProcessor:public Processor
03409 {
03410 public:
03411 void process_inplace(EMData * image);
03412
03413 string get_name() const
03414 {
03415 return NAME;
03416 }
03417 static Processor *NEW()
03418 {
03419 return new GradientRemoverProcessor();
03420 }
03421
03422 string get_desc() const
03423 {
03424 return "Gradient remover, does a rough plane fit to find linear gradients.";
03425 }
03426
03427 static const string NAME;
03428 };
03429
03438 class GradientPlaneRemoverProcessor:public Processor
03439 {
03440 public:
03441 void process_inplace(EMData * image);
03442
03443 string get_name() const
03444 {
03445 return NAME;
03446 }
03447 static Processor *NEW()
03448 {
03449 return new GradientPlaneRemoverProcessor();
03450 }
03451
03452 string get_desc() const
03453 {
03454 return "Remove gradient by least square plane fit";
03455 }
03456
03457 TypeDict get_param_types() const
03458 {
03459 TypeDict d;
03460 d.put("mask", EMObject::EMDATA, "mask object: nonzero pixel positions will be used to fit plane. default = 0");
03461 d.put("changeZero", EMObject::INT, "if zero pixels are modified when removing gradient. default = 0");
03462 d.put("planeParam", EMObject::FLOATARRAY, "fitted plane parameters output");
03463 return d;
03464 }
03465
03466 static const string NAME;
03467 };
03468
03469
03476 class FlattenBackgroundProcessor:public Processor
03477 {
03478 public:
03479 void process_inplace(EMData * image);
03480
03481 string get_name() const
03482 {
03483 return NAME;
03484 }
03485
03486 static Processor *NEW()
03487 {
03488 return new FlattenBackgroundProcessor();
03489 }
03490
03491 string get_desc() const
03492 {
03493 return "Flattens the background by subtracting the local mean";
03494 }
03495
03496 TypeDict get_param_types() const
03497 {
03498 TypeDict d;
03499 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");
03500 d.put("radius", EMObject::INT, "The radius of circle/sphere that defines the local neighborhood. Exclusive of the mask argument");
03501 return d;
03502 }
03503
03504 static const string NAME;
03505 };
03506
03507
03510 class RampProcessor:public Processor
03511 {
03512 public:
03513 void process_inplace(EMData * image);
03514
03515 string get_name() const
03516 {
03517 return NAME;
03518 }
03519 static Processor *NEW()
03520 {
03521 return new RampProcessor();
03522 }
03523
03524 string get_desc() const
03525 {
03526 return "Ramp processor -- Fits a least-squares plane "
03527 "to the picture, and subtracts the plane from "
03528 "the picture. A wedge-shaped overall density "
03529 "profile can thus be removed from the picture.";
03530 }
03531
03532 static const string NAME;
03533 };
03534
03537 class VerticalStripeProcessor:public Processor
03538 {
03539 public:
03540 void process_inplace(EMData * image);
03541
03542 string get_name() const
03543 {
03544 return NAME;
03545 }
03546
03547 static Processor *NEW()
03548 {
03549 return new VerticalStripeProcessor();
03550 }
03551
03552 string get_desc() const
03553 {
03554 return "Tries to fix images scanned on the zeiss for poor ccd normalization.";
03555 }
03556
03557 static const string NAME;
03558 };
03559
03562 class RealToFFTProcessor:public Processor
03563 {
03564 public:
03565 void process_inplace(EMData *image);
03566
03567 string get_name() const
03568 {
03569 return NAME;
03570 }
03571
03572 static Processor *NEW()
03573 {
03574 return new RealToFFTProcessor();
03575 }
03576
03577 string get_desc() const
03578 {
03579 return "This will replace the image with a full-circle 2D fft amplitude rendering. Note that this renders amplitude, when intensity is more common.";
03580 }
03581
03582 static const string NAME;
03583 };
03584
03585
03588 class SigmaZeroEdgeProcessor:public Processor
03589 {
03590 public:
03591 void process_inplace(EMData * image);
03592
03593 string get_name() const
03594 {
03595 return NAME;
03596 }
03597 static Processor *NEW()
03598 {
03599 return new SigmaZeroEdgeProcessor();
03600 }
03601
03602 string get_desc() const
03603 {
03604 return "Fill zeroes at edges with nearest horizontal/vertical value.";
03605 }
03606
03607 static const string NAME;
03608 };
03609
03615 class BeamstopProcessor:public Processor
03616 {
03617 public:
03618 void process_inplace(EMData * image);
03619
03620 string get_name() const
03621 {
03622 return NAME;
03623 }
03624
03625 static Processor *NEW()
03626 {
03627 return new BeamstopProcessor();
03628 }
03629
03630 string get_desc() const
03631 {
03632 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.";
03633 }
03634
03635 TypeDict get_param_types() const
03636 {
03637 TypeDict d;
03638 d.put("value1", EMObject::FLOAT, "sig multiplier");
03639 d.put("value2", EMObject::FLOAT, "x of center");
03640 d.put("value3", EMObject::FLOAT, "y of center");
03641 return d;
03642 }
03643
03644 static const string NAME;
03645 };
03646
03649 class MeanZeroEdgeProcessor:public Processor
03650 {
03651 public:
03652 void process_inplace(EMData * image);
03653
03654 string get_name() const
03655 {
03656 return NAME;
03657 }
03658
03659 static Processor *NEW()
03660 {
03661 return new MeanZeroEdgeProcessor();
03662 }
03663
03664 string get_desc() const
03665 {
03666 return "Fill zeroes at edges with nearest horizontal/vertical value damped towards Mean2.";
03667 }
03668
03669 static const string NAME;
03670 };
03671
03672
03675 class AverageXProcessor:public Processor
03676 {
03677 public:
03678 void process_inplace(EMData * image);
03679
03680 string get_name() const
03681 {
03682 return NAME;
03683 }
03684
03685 static Processor *NEW()
03686 {
03687 return new AverageXProcessor();
03688 }
03689
03690 string get_desc() const
03691 {
03692 return "Average along Y and replace with average";
03693 }
03694
03695 static const string NAME;
03696 };
03697
03701 class DecayEdgeProcessor:public Processor
03702 {
03703 public:
03704 void process_inplace(EMData * image);
03705 string get_name() const
03706 {
03707 return NAME;
03708 }
03709
03710 static Processor *NEW()
03711 {
03712 return new DecayEdgeProcessor();
03713 }
03714
03715 string get_desc() const
03716 {
03717 return "Decay edges of image to zero";
03718 }
03719
03720 TypeDict get_param_types() const
03721 {
03722 TypeDict d;
03723 d.put("width", EMObject::INT, "Width of the decay region around the edge of the image in pixels");
03724 return d;
03725 }
03726
03727 static const string NAME;
03728 };
03729
03736 class ZeroEdgeRowProcessor:public Processor
03737 {
03738 public:
03739 void process_inplace(EMData * image);
03740 string get_name() const
03741 {
03742 return NAME;
03743 }
03744
03745 static Processor *NEW()
03746 {
03747 return new ZeroEdgeRowProcessor();
03748 }
03749
03750 string get_desc() const
03751 {
03752 return "zero edges of image on top and bottom, and on left and right.";
03753 }
03754
03755 TypeDict get_param_types() const
03756 {
03757 TypeDict d;
03758 d.put("x0", EMObject::INT, "The number of columns to zero from left");
03759 d.put("x1", EMObject::INT, "The number of columns to zero from right");
03760 d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
03761 d.put("y1", EMObject::INT, "The number of rows to zero from the top");
03762 return d;
03763 }
03764
03765 static const string NAME;
03766 };
03767
03776 class ZeroEdgePlaneProcessor:public Processor
03777 {
03778 public:
03779 void process_inplace(EMData * image);
03780 string get_name() const
03781 {
03782 return NAME;
03783 }
03784
03785 static Processor *NEW()
03786 {
03787 return new ZeroEdgePlaneProcessor();
03788 }
03789
03790 string get_desc() const
03791 {
03792 return "zero edges of volume on all sides";
03793 }
03794
03795 TypeDict get_param_types() const
03796 {
03797 TypeDict d;
03798 d.put("x0", EMObject::INT, "The number of columns to zero from left");
03799 d.put("x1", EMObject::INT, "The number of columns to zero from right");
03800 d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
03801 d.put("y1", EMObject::INT, "The number of rows to zero from the top");
03802 d.put("z0", EMObject::INT, "The number of slices to zero from the bottom");
03803 d.put("z1", EMObject::INT, "The number of slices to zero from the top");
03804 return d;
03805 }
03806
03807 static const string NAME;
03808 };
03809
03810
03817 class BilateralProcessor:public Processor
03818 {
03819 public:
03820 void process_inplace(EMData * image);
03821 string get_name() const
03822 {
03823 return NAME;
03824 }
03825
03826 string get_desc() const
03827 {
03828 return "Bilateral processing on 2D or 3D volume data. Bilateral processing does non-linear weighted averaging processing within a certain window. ";
03829 }
03830
03831 static Processor *NEW()
03832 {
03833 return new BilateralProcessor();
03834 }
03835
03836 TypeDict get_param_types() const
03837 {
03838 TypeDict d;
03839 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.");
03840 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.");
03841 d.put("niter", EMObject::INT, "how many times to apply this processing on your data.");
03842 d.put("half_width", EMObject::INT, "processing window size = (2 * half_widthh + 1) ^ 3.");
03843 return d;
03844 }
03845
03846 static const string NAME;
03847 };
03848
03851 class NormalizeProcessor:public Processor
03852 {
03853 public:
03854 void process_inplace(EMData * image);
03855
03856 static string get_group_desc()
03857 {
03858 return "Base class for normalization processors. Each specific normalization processor needs to define how to calculate mean and how to calculate sigma.";
03859 }
03860
03861 protected:
03862 virtual float calc_sigma(EMData * image) const;
03863 virtual float calc_mean(EMData * image) const = 0;
03864 };
03865
03868 class NormalizeUnitProcessor:public NormalizeProcessor
03869 {
03870 public:
03871 string get_name() const
03872 {
03873 return NAME;
03874 }
03875
03876 static Processor *NEW()
03877 {
03878 return new NormalizeUnitProcessor();
03879 }
03880
03881 string get_desc() const
03882 {
03883 return "Normalize an image so its vector length is 1.0.";
03884 }
03885
03886 static const string NAME;
03887
03888 protected:
03889 float calc_sigma(EMData * image) const;
03890 float calc_mean(EMData * image) const;
03891 };
03892
03893 inline float NormalizeUnitProcessor::calc_mean(EMData *) const { return 0; }
03894
03897 class NormalizeUnitSumProcessor:public NormalizeProcessor
03898 {
03899 public:
03900 string get_name() const
03901 {
03902 return NAME;
03903 }
03904
03905 static Processor *NEW()
03906 {
03907 return new NormalizeUnitSumProcessor();
03908 }
03909
03910 string get_desc() const
03911 {
03912 return "Normalize an image so its elements sum to 1.0 (fails if mean=0)";
03913 }
03914
03915 static const string NAME;
03916
03917 protected:
03918 float calc_sigma(EMData * image) const;
03919 float calc_mean(EMData * image) const;
03920 };
03921
03922 inline float NormalizeUnitSumProcessor::calc_mean(EMData *) const { return 0; }
03923
03924
03927 class NormalizeStdProcessor:public NormalizeProcessor
03928 {
03929 public:
03930 string get_name() const
03931 {
03932 return NAME;
03933 }
03934
03935 static Processor *NEW()
03936 {
03937 return new NormalizeStdProcessor();
03938 }
03939
03940 string get_desc() const
03941 {
03942 return "do a standard normalization on an image.";
03943 }
03944
03945 static const string NAME;
03946
03947 protected:
03948 float calc_mean(EMData * image) const;
03949 };
03950
03955 class NormalizeMaskProcessor:public NormalizeProcessor
03956 {
03957 public:
03958 string get_name() const
03959 {
03960 return NAME;
03961 }
03962
03963 string get_desc() const
03964 {
03965 return "Uses a 1/0 mask defining a region to use for the zero-normalization.if no_sigma is 1, standard deviation not modified.";
03966 }
03967
03968 static Processor *NEW()
03969 {
03970 return new NormalizeMaskProcessor();
03971 }
03972
03973 TypeDict get_param_types() const
03974 {
03975 TypeDict d;
03976 d.put("mask", EMObject::EMDATA, "the 1/0 mask defining a region to use for the zero-normalization");
03977 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");
03978 return d;
03979 }
03980
03981 static const string NAME;
03982
03983 protected:
03984 float calc_sigma(EMData * image) const;
03985 float calc_mean(EMData * image) const;
03986 };
03987
03993 class NormalizeRampNormVar: public Processor
03994 {
03995 public:
03996 string get_name() const
03997 {
03998 return NAME;
03999 }
04000
04001 static Processor *NEW()
04002 {
04003 return new NormalizeRampNormVar();
04004 }
04005
04006 string get_desc() const
04007 {
04008 return "First call filter.ramp on the image, then make the mean 0 and norm 1";
04009 }
04010
04011 void process_inplace(EMData * image);
04012
04013 static const string NAME;
04014 };
04015
04024 class NormalizeByMassProcessor: public Processor
04025 {
04026 public:
04027 string get_name() const
04028 {
04029 return NAME;
04030 }
04031
04032 static Processor *NEW()
04033 {
04034 return new NormalizeByMassProcessor();
04035 }
04036
04037 string get_desc() const
04038 {
04039 return "Normalize the mass of the image assuming a density of 1.35 g/ml (0.81 Da/A^3) (3D only)";
04040 }
04041
04042 TypeDict get_param_types() const
04043 {
04044 TypeDict d;
04045 d.put("apix", EMObject::FLOAT,"Angstrom per pixel of the image. If not set will use the apix_x attribute of the image");
04046 d.put("mass", EMObject::FLOAT,"The approximate mass of protein/structure in kilodaltons");
04047 d.put("thr", EMObject::FLOAT,"The isosurface threshold which encapsulates the structure");
04048 return d;
04049 }
04050
04051 void process_inplace(EMData * image);
04052
04053 static const string NAME;
04054 };
04055
04056
04059 class NormalizeEdgeMeanProcessor:public NormalizeProcessor
04060 {
04061 public:
04062 string get_name() const
04063 {
04064 return NAME;
04065 }
04066
04067 static Processor *NEW()
04068 {
04069 return new NormalizeEdgeMeanProcessor();
04070 }
04071
04072 string get_desc() const
04073 {
04074 return "normalizes an image, mean value equals to edge mean.";
04075 }
04076
04077 static const string NAME;
04078
04079 protected:
04080 float calc_mean(EMData * image) const;
04081 };
04082
04085 class NormalizeCircleMeanProcessor:public NormalizeProcessor
04086 {
04087 public:
04088 string get_name() const
04089 {
04090 return NAME;
04091 }
04092
04093 static Processor *NEW()
04094 {
04095 return new NormalizeCircleMeanProcessor();
04096 }
04097
04098 string get_desc() const
04099 {
04100 return "normalizes an image, mean value equals to mean of 2 pixel circular border.";
04101 }
04102
04103 static const string NAME;
04104
04105 protected:
04106 float calc_mean(EMData * image) const;
04107 };
04108
04111 class NormalizeLREdgeMeanProcessor:public NormalizeProcessor
04112 {
04113 public:
04114 string get_name() const
04115 {
04116 return NAME;
04117 }
04118
04119 static Processor *NEW()
04120 {
04121 return new NormalizeLREdgeMeanProcessor();
04122 }
04123
04124 string get_desc() const
04125 {
04126 return "normalizes an image, uses 2 pixels on left and right edge";
04127 }
04128
04129 static const string NAME;
04130
04131 protected:
04132 float calc_mean(EMData * image) const;
04133 };
04134
04137 class NormalizeMaxMinProcessor:public NormalizeProcessor
04138 {
04139 public:
04140 string get_name() const
04141 {
04142 return NAME;
04143 }
04144
04145 static Processor *NEW()
04146 {
04147 return new NormalizeMaxMinProcessor();
04148 }
04149
04150 string get_desc() const
04151 {
04152 return "normalizes an image. mean -> (maxval-minval)/2; std dev = (maxval+minval)/2;";
04153 }
04154
04155 static const string NAME;
04156
04157 protected:
04158 float calc_sigma(EMData * image) const;
04159 float calc_mean(EMData * image) const;
04160 };
04161
04164 class NormalizeRowProcessor:public Processor
04165 {
04166 public:
04167 string get_name() const
04168 {
04169 return NAME;
04170 }
04171
04172 static Processor *NEW()
04173 {
04174 return new NormalizeRowProcessor();
04175 }
04176
04177 string get_desc() const
04178 {
04179 return "normalizes each row in the image individually";
04180 }
04181
04182 static const string NAME;
04183
04184 void process_inplace(EMData * image);
04185 };
04186
04192 class NormalizeToLeastSquareProcessor:public Processor
04193 {
04194 public:
04195 void process_inplace(EMData * image);
04196
04197 string get_name() const
04198 {
04199 return NAME;
04200 }
04201
04202 static Processor *NEW()
04203 {
04204 return new NormalizeToLeastSquareProcessor();
04205 }
04206
04207 TypeDict get_param_types() const
04208 {
04209 TypeDict d;
04210 d.put("to", EMObject::EMDATA, "reference image normalize to");
04211 d.put("ignore_zero", EMObject::BOOL, "If set, ignores any pixels which are exactly zero in either image. Defaut = True.");
04212 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)");
04213 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)");
04214 return d;
04215 }
04216
04217 string get_desc() const
04218 {
04219 return "use least square method to normalize";
04220 }
04221
04222 static const string NAME;
04223 };
04224
04227 class RotationalAverageProcessor:public Processor
04228 {
04229 public:
04230 void process_inplace(EMData * image);
04231
04232 string get_name() const
04233 {
04234 return NAME;
04235 }
04236
04237 static Processor *NEW()
04238 {
04239 return new RotationalAverageProcessor();
04240 }
04241
04242 string get_desc() const
04243 {
04244 return "Makes image circularly/spherically symmetric.";
04245 }
04246
04247 static const string NAME;
04248 };
04249
04252 class RotationalSubstractProcessor:public Processor
04253 {
04254 public:
04255 virtual void process_inplace(EMData * image);
04256
04257 virtual string get_name() const
04258 {
04259 return NAME;
04260 }
04261
04262 static Processor *NEW()
04263 {
04264 return new RotationalSubstractProcessor();
04265 }
04266
04267 virtual string get_desc() const
04268 {
04269 return "subtracts circularly/spherically symmetric part of an image.";
04270 }
04271
04272 static const string NAME;
04273 };
04274
04280 class TransposeProcessor:public Processor
04281 {
04282 public:
04283
04288 virtual void process_inplace(EMData * image);
04289
04294 virtual EMData* process(const EMData * const image);
04295
04296 virtual string get_name() const
04297 {
04298 return NAME;
04299 }
04300
04301 static Processor *NEW()
04302 {
04303 return new TransposeProcessor();
04304 }
04305
04306 virtual TypeDict get_param_types() const
04307 {
04308 TypeDict d;
04309 return d;
04310 }
04311
04312 virtual string get_desc() const
04313 {
04314 return "Get the transpose of an image. Works for 2D only";
04315 }
04316
04317 static const string NAME;
04318 };
04319
04320
04324 class FlipProcessor:public Processor
04325 {
04326 public:
04327 virtual void process_inplace(EMData * image);
04328
04329 virtual string get_name() const
04330 {
04331 return NAME;
04332 }
04333
04334 static Processor *NEW()
04335 {
04336 return new FlipProcessor();
04337 }
04338
04339 virtual TypeDict get_param_types() const
04340 {
04341 TypeDict d;
04342 d.put("axis", EMObject::STRING, "'x', 'y', or 'z' axis. 'x' means horizonal flip; 'y' means vertical flip;");
04343 return d;
04344 }
04345
04346 virtual string get_desc() const
04347 {
04348 return "flip an image around an axis.";
04349 }
04350
04351 static const string NAME;
04352 };
04353
04354
04355
04356
04357
04358
04359
04360
04361
04362
04363
04364
04365
04366
04367
04368
04369
04370
04371
04372
04373
04374
04375
04376
04377
04378
04379
04380
04381
04382
04387 class AddNoiseProcessor:public Processor
04388 {
04389 public:
04390 virtual void process_inplace(EMData * image);
04391
04392 virtual string get_name() const
04393 {
04394 return NAME;
04395 }
04396
04397 static Processor *NEW()
04398 {
04399 return new AddNoiseProcessor();
04400 }
04401
04402 virtual TypeDict get_param_types() const
04403 {
04404 TypeDict d;
04405 d.put("noise", EMObject::FLOAT, "noise factor used to generate Gaussian distribution random noise");
04406 d.put("seed", EMObject::INT, "seed for random number generator");
04407 return d;
04408 }
04409
04410 virtual string get_desc() const
04411 {
04412 return "add noise to an image, image multiply by noise then add a random value";
04413 }
04414
04415 static const string NAME;
04416
04417 protected:
04418 virtual float get_sigma(EMData *)
04419 {
04420 return 1.0;
04421 }
04422 };
04423
04426 class AddSigmaNoiseProcessor:public AddNoiseProcessor
04427 {
04428 public:
04429 virtual string get_name() const
04430 {
04431 return NAME;
04432 }
04433
04434 static Processor *NEW()
04435 {
04436 return new AddSigmaNoiseProcessor();
04437 }
04438
04439 virtual string get_desc() const
04440 {
04441 return "add sigma noise.";
04442 }
04443
04444 static const string NAME;
04445
04446 protected:
04447 float get_sigma(EMData * image);
04448 };
04449
04458 class AddRandomNoiseProcessor:public Processor
04459 {
04460 public:
04461 virtual void process_inplace(EMData * image);
04462
04463 virtual string get_name() const
04464 {
04465 return NAME;
04466 }
04467
04468 static Processor *NEW()
04469 {
04470 return new AddRandomNoiseProcessor();
04471 }
04472
04473 virtual TypeDict get_param_types() const
04474 {
04475 TypeDict d;
04476 d.put("n", EMObject::INT);
04477 d.put("x0", EMObject::FLOAT);
04478 d.put("dx", EMObject::FLOAT);
04479 d.put("y", EMObject::FLOATARRAY);
04480 d.put("interpolation", EMObject::INT);
04481 d.put("seed", EMObject::INT, "seed for random number generator");
04482 return d;
04483 }
04484
04485 virtual string get_desc() const
04486 {
04487 return "add spectral noise to a complex image.";
04488 }
04489
04490 static const string NAME;
04491 };
04492
04498 class FourierToCornerProcessor:public Processor
04499 {
04500 public:
04506 virtual void process_inplace(EMData * image);
04507
04508 virtual string get_name() const
04509 {
04510 return NAME;
04511 }
04512
04513 static Processor *NEW()
04514 {
04515 return new FourierToCornerProcessor();
04516 }
04517
04518 virtual string get_desc() const
04519 {
04520 return "Undoes the xform.fourierorigin.tocenter processor";
04521 }
04522
04523 static const string NAME;
04524 };
04525
04526
04538 class FourierToCenterProcessor:public Processor
04539 {
04540 public:
04546 virtual void process_inplace(EMData * image);
04547
04548 virtual string get_name() const
04549 {
04550 return NAME;
04551 }
04552
04553 static Processor *NEW()
04554 {
04555 return new FourierToCenterProcessor();
04556 }
04557
04558 virtual string get_desc() const
04559 {
04560 return "Translates the origin in Fourier space from the corner to the center in y and z - works in 2D and 3D";
04561 }
04562
04563 static const string NAME;
04564 };
04565
04575 class Phase180Processor:public Processor
04576 {
04577 protected:
04590 void swap_corners_180(EMData * image);
04591
04603 void swap_central_slices_180(EMData * image);
04604
04611 void fourier_phaseshift180(EMData * image);
04612
04613 };
04614
04624 class PhaseToCenterProcessor:public Phase180Processor
04625 {
04626 public:
04627 virtual void process_inplace(EMData * image);
04628
04629 virtual string get_name() const
04630 {
04631 return NAME;
04632 }
04633
04634 static Processor *NEW()
04635 {
04636 return new PhaseToCenterProcessor();
04637 }
04638
04639 virtual string get_desc() const
04640 {
04641 return "Undoes the effect of the xform.phaseorigin.tocorner processor";
04642 }
04643
04644 static const string NAME;
04645 };
04646
04654 class PhaseToCornerProcessor:public Phase180Processor
04655 {
04656 public:
04657 virtual void process_inplace(EMData * image);
04658
04659 virtual string get_name() const
04660 {
04661 return NAME;
04662 }
04663
04664 static Processor *NEW()
04665 {
04666 return new PhaseToCornerProcessor();
04667 }
04668
04669 virtual string get_desc() const
04670 {
04671 return "Translates a centered image to the corner in a forward fashion";
04672 }
04673
04674 static const string NAME;
04675 };
04676
04681 class AutoMask2DProcessor:public Processor
04682 {
04683 public:
04684 virtual void process_inplace(EMData * image);
04685
04686 virtual string get_name() const
04687 {
04688 return NAME;
04689 }
04690
04691 static Processor *NEW()
04692 {
04693 return new AutoMask2DProcessor();
04694 }
04695
04696 virtual TypeDict get_param_types() const
04697 {
04698 TypeDict d;
04699 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
04700 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
04701 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
04702 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
04703 d.put("nshells", EMObject::INT, "The number of dilation operations");
04704 d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
04705 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
04706 d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
04707 return d;
04708 }
04709
04710 virtual string get_desc() const
04711 {
04712 return "2D version of mask.auto3d";
04713 }
04714
04715 static const string NAME;
04716 };
04717
04718
04725 class AutoMaskAsymUnit:public Processor
04726 {
04727 public:
04728 virtual void process_inplace(EMData * image);
04729
04730 virtual string get_name() const
04731 {
04732 return NAME;
04733 }
04734
04735 static Processor *NEW()
04736 {
04737 return new AutoMaskAsymUnit();
04738 }
04739
04740 virtual TypeDict get_param_types() const
04741 {
04742 TypeDict d;
04743 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.");
04744 d.put("sym", EMObject::STRING, "The symmetry, for example, d7");
04745 return d;
04746 }
04747
04748 virtual string get_desc() const
04749 {
04750 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.";
04751 }
04752
04753 static const string NAME;
04754 };
04755
04760 class AutoMask3DProcessor:public Processor
04761 {
04762 public:
04763 virtual void process_inplace(EMData * image);
04764
04765 virtual string get_name() const
04766 {
04767 return NAME;
04768 }
04769
04770 static Processor *NEW()
04771 {
04772 return new AutoMask3DProcessor();
04773 }
04774
04775 virtual TypeDict get_param_types() const
04776 {
04777 TypeDict d;
04778 d.put("threshold1", EMObject::FLOAT);
04779 d.put("threshold2", EMObject::FLOAT);
04780 return d;
04781 }
04782
04783 virtual string get_desc() const
04784 {
04785 return "Tries to mask out only interesting density";
04786 }
04787
04788 static void search_nearby(float *dat, float *dat2, int nx, int ny, int nz, float thr);
04789 static void fill_nearby(float *dat2, int nx, int ny, int nz);
04790
04791 static const string NAME;
04792 };
04793
04801 class AutoMask3D2Processor:public Processor
04802 {
04803 public:
04804 virtual void process_inplace(EMData * image);
04805
04806 virtual string get_name() const
04807 {
04808 return NAME;
04809 }
04810
04811 static Processor *NEW()
04812 {
04813 return new AutoMask3D2Processor();
04814 }
04815
04816 virtual string get_desc() const
04817 {
04818 return "Tries to mask out only interesting density using something akin to a flood file approach.";
04819 }
04820
04821 virtual TypeDict get_param_types() const
04822 {
04823 TypeDict d;
04824 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
04825 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
04826 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
04827 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
04828 d.put("nshells", EMObject::INT, "The number of dilation operations");
04829 d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
04830 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
04831 d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
04832 return d;
04833 }
04834
04835 static const string NAME;
04836 };
04837
04841 class AddMaskShellProcessor:public Processor
04842 {
04843 public:
04844 virtual void process_inplace(EMData * image);
04845
04846 virtual string get_name() const
04847 {
04848 return NAME;
04849 }
04850
04851 virtual string get_desc() const
04852 {
04853 return "Add additional shells/rings to an existing 1/0 mask image";
04854 }
04855
04856 static Processor *NEW()
04857 {
04858 return new AddMaskShellProcessor();
04859 }
04860
04861 virtual TypeDict get_param_types() const
04862 {
04863 TypeDict d;
04864 d.put("nshells", EMObject::INT, "number of shells to add");
04865 return d;
04866 }
04867
04868 static const string NAME;
04869 };
04870
04875 class PhaseToMassCenterProcessor:public Processor
04876 {
04877 public:
04878 virtual void process_inplace(EMData * image);
04879
04880 virtual string get_name() const
04881 {
04882 return NAME;
04883 }
04884
04885 static Processor *NEW()
04886 {
04887 return new PhaseToMassCenterProcessor();
04888 }
04889
04890 virtual string get_desc() const
04891 {
04892 return "centers the image the center of mass, which is calculated using Fourier phases, ignores old dx, dy.";
04893 }
04894
04895 virtual TypeDict get_param_types() const
04896 {
04897 TypeDict d;
04898 d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
04899 return d;
04900 }
04901
04902 static const string NAME;
04903 };
04904
04909 class ToMassCenterProcessor:public Processor
04910 {
04911 public:
04912 virtual void process_inplace(EMData * image);
04913
04914 virtual string get_name() const
04915 {
04916 return NAME;
04917 }
04918
04919 static Processor *NEW()
04920 {
04921 return new ToMassCenterProcessor();
04922 }
04923
04924 virtual string get_desc() const
04925 {
04926 return "ToMassCenterProcessor centers image at center of mass, with a threshold. Only values higher than the threshold are considered.";
04927 }
04928
04929 virtual TypeDict get_param_types() const
04930 {
04931 TypeDict d;
04932 d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
04933 d.put("threshold", EMObject::FLOAT, "Only values larger than the threshold are included in the center of mass computation. Default is 0.");
04934
04935 return d;
04936 }
04937
04938 static const string NAME;
04939 };
04940
04944 class ACFCenterProcessor:public Processor
04945 {
04946 public:
04947 virtual void process_inplace(EMData * image);
04948
04949 virtual string get_name() const
04950 {
04951 return NAME;
04952 }
04953
04954 static Processor *NEW()
04955 {
04956 return new ACFCenterProcessor();
04957 }
04958
04959 virtual string get_desc() const
04960 {
04961 return "Center image using self-convolution.";
04962 }
04963
04964 virtual TypeDict get_param_types() const
04965 {
04966 TypeDict d;
04967 return d;
04968 }
04969
04970 static const string NAME;
04971 };
04972
04977 class SNRProcessor:public Processor
04978 {
04979 public:
04980 virtual void process_inplace(EMData * image);
04981
04982 virtual string get_name() const
04983 {
04984 return NAME;
04985 }
04986
04987 static Processor *NEW()
04988 {
04989 return new SNRProcessor();
04990 }
04991
04992 virtual string get_desc() const
04993 {
04994 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.";
04995 }
04996
04997 virtual TypeDict get_param_types() const
04998 {
04999 TypeDict d;
05000 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");
05001 d.put("snrfile", EMObject::STRING, "structure factor file name");
05002 return d;
05003 }
05004
05005 static const string NAME;
05006 };
05007
05011 class FileFourierProcessor:public Processor
05012 {
05013 public:
05014 virtual void process_inplace(EMData * image);
05015
05016 virtual string get_name() const
05017 {
05018 return NAME;
05019 }
05020
05021 virtual string get_desc() const
05022 {
05023 return "A fourier processor specified in a 2 column text file.";
05024 }
05025
05026 static Processor *NEW()
05027 {
05028 return new FileFourierProcessor();
05029 }
05030
05031 virtual TypeDict get_param_types() const
05032 {
05033 TypeDict d;
05034 d.put("filename", EMObject::STRING, "file name for a 2 column text file which specified a radial function data array.");
05035 return d;
05036 }
05037
05038 static const string NAME;
05039 };
05040
05051 class SymSearchProcessor:public Processor
05052 {
05053 public:
05054 virtual void process_inplace(EMData * image);
05055
05056 virtual string get_name() const
05057 {
05058 return NAME;
05059 }
05060
05061 virtual string get_desc() const
05062 {
05063 return "Identifiy the best symmetry in the given symmetry list for each pixel and then apply the best symmetry to each pixel.";
05064 }
05065
05066 static Processor *NEW()
05067 {
05068 return new SymSearchProcessor();
05069 }
05070
05071 virtual TypeDict get_param_types() const
05072 {
05073 TypeDict d;
05074 d.put("sym", EMObject::STRINGARRAY, "the list of symmetries to search");
05075 d.put("thresh", EMObject::FLOAT, "the minimal level of symmetry to be accepted (0-1)");
05076 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");
05077 d.put("symlabel_map", EMObject::EMDATA, "the optional return map when output_symlabel=1");
05078 return d;
05079 }
05080
05081 static const string NAME;
05082 };
05083
05089 class LocalNormProcessor:public Processor
05090 {
05091 public:
05092 void process_inplace(EMData * image);
05093
05094 virtual string get_name() const
05095 {
05096 return NAME;
05097 }
05098
05099 static Processor *NEW()
05100 {
05101 return new LocalNormProcessor();
05102 }
05103
05104 virtual string get_desc() const
05105 {
05106 return "This processor attempts to perform a 'local normalization' so low density and high density features will be on a more even playing field in an isosurface display. threshold is an isosurface threshold at which all desired features are visible, radius is a feature size over which to equalize.";
05107 }
05108
05109 virtual TypeDict get_param_types() const
05110 {
05111 TypeDict d;
05112 d.put("threshold", EMObject::FLOAT, "an isosurface threshold at which all desired features are visible");
05113 d.put("radius", EMObject::FLOAT, "a normalization size similar to an lp= value");
05114 d.put("apix", EMObject::FLOAT, "Angstrom per pixel ratio");
05115 return d;
05116 }
05117
05118 static const string NAME;
05119 };
05120
05125 class IndexMaskFileProcessor:public Processor
05126 {
05127 public:
05128 virtual void process_inplace(EMData * image);
05129
05130 virtual string get_name() const
05131 {
05132 return NAME;
05133 }
05134
05135 static Processor *NEW()
05136 {
05137 return new IndexMaskFileProcessor();
05138 }
05139
05140 virtual TypeDict get_param_types() const
05141 {
05142 TypeDict d;
05143 d.put("filename", EMObject::STRING, "mask image file name");
05144 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");
05145 return d;
05146 }
05147
05148 virtual string get_desc() const
05149 {
05150 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.";
05151 }
05152
05153 static const string NAME;
05154 };
05155
05159 class CoordinateMaskFileProcessor:public Processor
05160 {
05161 public:
05162 virtual void process_inplace(EMData * image);
05163
05164 virtual string get_name() const
05165 {
05166 return NAME;
05167 }
05168
05169 static Processor *NEW()
05170 {
05171 return new CoordinateMaskFileProcessor();
05172 }
05173
05174 virtual string get_desc() const
05175 {
05176 return "Multiplies the image by the specified file using pixel coordinates instead of pixel indices. The images can be different size.";
05177 }
05178
05179 virtual TypeDict get_param_types() const
05180 {
05181 TypeDict d;
05182 d.put("filename", EMObject::STRING, "mask image file name");
05183 return d;
05184 }
05185
05186 static const string NAME;
05187 };
05188
05199 class PaintProcessor:public Processor
05200 {
05201 public:
05202 PaintProcessor():x(0), y(0), z(0),r1(0), v1(0.0), r2(0), v2(0.0)
05203 {
05204 }
05205
05206 virtual string get_name() const
05207 {
05208 return NAME;
05209 }
05210
05211 static Processor *NEW()
05212 {
05213 return new PaintProcessor();
05214 }
05215
05216 virtual string get_desc() const
05217 {
05218 return "Paints a circle with a decaying edge into the image. r<r1 -> v1, r1<r<r2 -> (v1,v2), r>r2 unchanged";
05219 }
05220
05221 virtual TypeDict get_param_types() const
05222 {
05223 TypeDict d;
05224 d.put("x", EMObject::INT, "x coordinate for Center of circle");
05225 d.put("y", EMObject::INT, "y coordinate for Center of circle");
05226 d.put("z", EMObject::INT, "z coordinate for Center of circle");
05227 d.put("r1", EMObject::INT, "Inner radius");
05228 d.put("v1", EMObject::FLOAT, "Inner value");
05229 d.put("r2", EMObject::INT, "Outter radius");
05230 d.put("v2", EMObject::FLOAT, "Outer Value");
05231 return d;
05232 }
05233
05234 virtual void set_params(const Dict & new_params)
05235 {
05236 params = new_params;
05237
05238 if (params.has_key("x")) x = params["x"];
05239 if (params.has_key("y")) y = params["y"];
05240 if (params.has_key("z")) z = params["z"];
05241 if (params.has_key("r1")) r1 = params["r1"];
05242 if (params.has_key("r2")) r2 = params["r2"];
05243 if (params.has_key("v1")) v1 = params["v1"];
05244 if (params.has_key("v2")) v2 = params["v2"];
05245 }
05246
05247 static const string NAME;
05248
05249 protected:
05250 virtual void process_inplace(EMData *image);
05251
05252 int x,y,z,r1;
05253 float v1;
05254 int r2;
05255 float v2;
05256
05257 };
05258
05259
05264 class DirectionalSumProcessor : public Processor
05265 {
05266 public:
05267 virtual string get_name() const
05268 {
05269 return NAME;
05270 }
05271
05272 static Processor *NEW()
05273 {
05274 return new DirectionalSumProcessor();
05275 }
05276
05280 virtual EMData* process(const EMData* const image);
05281
05285 virtual void process_inplace(EMData* image ) {
05286 throw InvalidCallException("The directional sum processor does not work inplace");
05287 }
05288
05289 virtual TypeDict get_param_types() const
05290 {
05291 TypeDict d;
05292 d.put("axis", EMObject::STRING,"The direction of the sum, either x,y or z. Returned axes are xy, xz or zy.");
05293 d.put("first", EMObject::INT,"The first position along the speficied axis to use in the sum. Neg val -> nx/y/z+first (default=0)");
05294 d.put("last", EMObject::INT,"The last position along the speficied axis to use in the sum. Neg val -> nx/y/z+last (default=-1)");
05295 return d;
05296 }
05297
05298 string get_desc() const
05299 {
05300 return "Calculates the projection of the image along one of the axial directions, either x, y or z";
05301 }
05302
05303 static const string NAME;
05304 };
05305
05313 class WatershedProcessor:public Processor
05314 {
05315 public:
05316 virtual void process_inplace(EMData * image);
05317
05318 virtual string get_name() const
05319 {
05320 return NAME;
05321 }
05322
05323 static Processor *NEW()
05324 {
05325 return new WatershedProcessor();
05326 }
05327
05328 virtual string get_desc() const
05329 {
05330 return "Does a watershed";
05331 }
05332
05333 virtual TypeDict get_param_types() const
05334 {
05335 TypeDict d;
05336 d.put("xpoints", EMObject::FLOATARRAY,"x coordinates");
05337 d.put("ypoints", EMObject::FLOATARRAY,"y coordinates");
05338 d.put("zpoints", EMObject::FLOATARRAY,"z coordinates");
05339 d.put("minval", EMObject::FLOAT,"min value");
05340 return d;
05341 }
05342
05343 static const string NAME;
05344
05345 private:
05346 vector<Vec3i > watershed(EMData* mask, EMData* image, const float& threshold, const Vec3i& cordinate, const int mask_value);
05347 vector<Vec3i > find_region(EMData* mask,const vector<Vec3i >& coords, const int mask_value, vector<Vec3i >& region);
05348
05349 };
05350
05360 template<class Type>
05361 class BinaryOperateProcessor : public Processor{
05362 public:
05367 virtual void process_inplace(EMData * image) {
05368 if ( ! params.has_key("with") ) throw InvalidParameterException("You must supply the \"with\" parameter");
05369 EMData* with = params["with"];
05370
05371 if ( with->get_xsize() != image->get_xsize() || with->get_ysize() != image->get_ysize() || with->get_zsize() != image->get_zsize() )
05372 throw ImageDimensionException("The images you are operating on do not have the same dimensions");
05373
05374 float* image_data = image->get_data();
05375 float* with_data = with->get_data();
05376
05377 std::transform(image_data,image_data+image->get_size(),with_data,image_data,Type::binary_operate);
05378 image->update();
05379 }
05380
05381 virtual string get_name() const
05382 {
05383 return op.get_name();
05384 }
05385
05386 virtual string get_desc() const
05387 {
05388 return op.get_desc();
05389 }
05390
05391 static Processor *NEW()
05392 {
05393 return new BinaryOperateProcessor<Type>();
05394 }
05395
05396 virtual TypeDict get_param_types() const
05397 {
05398 TypeDict d;
05399 d.put("with", EMObject::EMDATA,"The second image");
05400 return d;
05401 }
05402
05403 static const string NAME;
05404 private:
05405 Type op;
05406 };
05407
05408 class MaxPixelOperator {
05409 public:
05410 string get_name() const
05411 {
05412 return NAME;
05413 }
05414
05415 string get_desc() const
05416 {
05417 return "Compares pixels in two images, returning an image with the maximum pixel value in each pixel location";
05418 }
05419
05420 static float binary_operate(const float& left, const float& right) {
05421 if (left > right) return left;
05422 return right;
05423 }
05424
05425 static const string NAME;
05426 };
05427
05428 class MinPixelOperator {
05429 public:
05430 string get_name() const
05431 {
05432 return NAME;
05433 }
05434
05435 string get_desc() const
05436 {
05437 return "Compares pixels in two images, returning an image with the minimum pixel value in each pixel location";
05438 }
05439
05440 static float binary_operate(const float& left, const float& right) {
05441 if (left < right) return left;
05442 return right;
05443 }
05444
05445 static const string NAME;
05446 };
05447
05451 class MatchSFProcessor:public FourierAnlProcessor
05452 {
05453 public:
05454
05455 virtual string get_name() const
05456 {
05457 return NAME;
05458 }
05459
05460 virtual string get_desc() const
05461 {
05462 return "Filters the image so its 1-D power spectrum matches a second image";
05463 }
05464
05465 static Processor *NEW()
05466 {
05467 return new MatchSFProcessor();
05468 }
05469
05470 virtual TypeDict get_param_types() const
05471 {
05472 TypeDict d;
05473 d.put("to", EMObject::EMDATA, "The image to match with. Make sure apix values are correct.");
05474 return d;
05475 }
05476
05477 static const string NAME;
05478
05479 protected:
05480 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05481 };
05482
05483
05488 class SetSFProcessor:public FourierAnlProcessor
05489 {
05490 public:
05491
05492 virtual string get_name() const
05493 {
05494 return NAME;
05495 }
05496
05497 virtual string get_desc() const
05498 {
05499 return "Filters the image so its 1-D power spectrum matches a supplied X-Y curve";
05500 }
05501
05502 static Processor *NEW()
05503 {
05504 return new SetSFProcessor();
05505 }
05506
05507 virtual TypeDict get_param_types() const
05508 {
05509 TypeDict d;
05510 d.put("strucfac", EMObject::XYDATA, "An XYData object contaning the curve to be imposed as a function of S");
05511 d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
05512 return d;
05513 }
05514
05515 static const string NAME;
05516
05517 protected:
05518 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05519 };
05520
05524 class SmartMaskProcessor:public Processor
05525 {
05526 public:
05527 virtual void process_inplace(EMData * image);
05528
05529 virtual string get_name() const
05530 {
05531 return NAME;
05532 }
05533
05534 static Processor *NEW()
05535 {
05536 return new SmartMaskProcessor();
05537 }
05538
05539 virtual string get_desc() const
05540 {
05541 return "Smart mask processor.";
05542 }
05543
05544 virtual TypeDict get_param_types() const
05545 {
05546 TypeDict d;
05547 d.put("mask", EMObject::FLOAT, "mask value");
05548 return d;
05549 }
05550
05551 static const string NAME;
05552 };
05553
05558 class IterBinMaskProcessor:public Processor
05559 {
05560 public:
05561 virtual void process_inplace(EMData * image);
05562
05563 virtual string get_name() const
05564 {
05565 return NAME;
05566 }
05567
05568 virtual string get_desc() const
05569 {
05570 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.";
05571 }
05572
05573 static Processor *NEW()
05574 {
05575 return new IterBinMaskProcessor();
05576 }
05577
05578 virtual TypeDict get_param_types() const
05579 {
05580 TypeDict d;
05581 d.put("val1", EMObject::FLOAT, "number of pixels to expand");
05582 d.put("val2", EMObject::FLOAT, "number of Gaussian pixels to expand, following the first expansion");
05583 return d;
05584 }
05585
05586 static const string NAME;
05587 };
05588
05591 class TestImageProcessor : public Processor
05592 {
05593 public:
05594 static string get_group_desc()
05595 {
05596 return "Base class for a group of 'processors' used to create test image.";
05597 }
05598
05599 protected:
05600 void preprocess(EMData * image);
05601 int nx, ny, nz;
05602 };
05603
05612 class TestImagePureGaussian : public TestImageProcessor
05613 {
05614 public:
05615 virtual void process_inplace(EMData * image);
05616
05617 virtual string get_name() const
05618 {
05619 return NAME;
05620 }
05621
05622 virtual string get_desc() const
05623 {
05624 return "Replace a source image as a strict Gaussian ";
05625 }
05626
05627 static Processor * NEW()
05628 {
05629 return new TestImagePureGaussian();
05630 }
05631
05632 virtual TypeDict get_param_types() const
05633 {
05634 TypeDict d;
05635 d.put("x_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on x direction");
05636 d.put("y_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on y direction");
05637 d.put("z_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on z direction");
05638 d.put("x_center", EMObject::FLOAT, "center for this Gaussian blob on x direction" );
05639 d.put("y_center", EMObject::FLOAT, "center for this Gaussian blob on y direction" );
05640 d.put("z_center", EMObject::FLOAT, "center for this Gaussian blob on z direction" );
05641 return d;
05642 }
05643
05644 static const string NAME;
05645 };
05646
05650 class TestImageFourierNoiseGaussian : public TestImageProcessor
05651 {
05652 public:
05653 virtual void process_inplace(EMData * image);
05654
05655 virtual string get_name() const
05656 {
05657 return NAME;
05658 }
05659
05660 virtual string get_desc() const
05661 {
05662 return "Replace a source image with pink Fourier noise, based on a Gaussian. Random phase.";
05663 }
05664
05665 static Processor * NEW()
05666 {
05667 return new TestImageFourierNoiseGaussian();
05668 }
05669
05670 virtual TypeDict get_param_types() const
05671 {
05672 TypeDict d;
05673 d.put("sigma", EMObject::FLOAT, "sigma value");
05674 return d;
05675 }
05676
05677 static const string NAME;
05678 };
05679
05684 class TestImageFourierNoiseProfile : public TestImageProcessor
05685 {
05686 public:
05687 virtual void process_inplace(EMData * image);
05688
05689 virtual string get_name() const
05690 {
05691 return NAME;
05692 }
05693
05694 virtual string get_desc() const
05695 {
05696 return "Replace a source image with Fourier noise using amplitude information that is stored in a profile.";
05697 }
05698
05699 static Processor * NEW()
05700 {
05701 return new TestImageFourierNoiseProfile();
05702 }
05703
05704 virtual TypeDict get_param_types() const
05705 {
05706 TypeDict d;
05707 d.put("profile", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
05708 return d;
05709 }
05710
05711 static const string NAME;
05712 };
05713
05714
05719 class CTFSNRWeightProcessor : public TestImageProcessor
05720 {
05721 public:
05722 virtual void process_inplace(EMData * image);
05723
05724 virtual string get_name() const
05725 {
05726 return NAME;
05727 }
05728
05729 virtual string get_desc() const
05730 {
05731 return "Weight the amplitudes of an image based on radial noise and snr curves ";
05732 }
05733
05734 static Processor * NEW()
05735 {
05736 return new CTFSNRWeightProcessor();
05737 }
05738
05739 virtual TypeDict get_param_types() const
05740 {
05741 TypeDict d;
05742 d.put("noise", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
05743 d.put("snr", EMObject::FLOATARRAY, "Squared amplitude divided by squared noise amplitude. As in, what is the EMAN2CTF.snr attribute");
05744 d.put("boost", EMObject::FLOAT, "Multiplicative signal boost");
05745 return d;
05746 }
05747
05748 static const string NAME;
05749 };
05750
05751
05752
05757 class TestImageLineWave : public TestImageProcessor
05758 {
05759 public:
05760 virtual void process_inplace(EMData * image);
05761
05762 virtual string get_name() const
05763 {
05764 return NAME;
05765 }
05766
05767 virtual string get_desc() const
05768 {
05769 return "Insert an oscillating sine wave into the pixel data";
05770 }
05771
05772 static Processor * NEW()
05773 {
05774 return new TestImageLineWave();
05775 }
05776
05777 virtual TypeDict get_param_types() const
05778 {
05779 TypeDict d;
05780 d.put("period", EMObject::FLOAT, "The period of the oscillating sine wave. Default 10.");
05781 return d;
05782 }
05783
05784 static const string NAME;
05785 };
05786
05787
05795 class TestTomoImage : public TestImageProcessor
05796 {
05797 public:
05801 virtual void process_inplace(EMData * image);
05802
05803 virtual string get_name() const
05804 {
05805 return NAME;
05806 }
05807
05808 virtual string get_desc() const
05809 {
05810 return "Make an image consisting various objects, useful for tomographic testing";
05811 }
05812
05813 static Processor * NEW()
05814 {
05815 return new TestTomoImage();
05816 }
05817
05818 static const string NAME;
05819
05820 private:
05821 void insert_solid_ellipse( EMData* image, const Region& region, const float& value, const Transform& t3d = Transform() );
05822 void insert_hollow_ellipse( EMData* image, const Region& region, const float& value, const int& radius, const Transform& t3d = Transform() );
05823 void insert_rectangle( EMData* image, const Region& region, const float& value, const Transform& t3d = Transform() );
05824 };
05825
05833 class TestImageGradient : public TestImageProcessor
05834 {
05835 public:
05836 virtual void process_inplace(EMData * image);
05837
05838 virtual string get_name() const
05839 {
05840 return NAME;
05841 }
05842
05843 virtual string get_desc() const
05844 {
05845 return "Make a gradient image of the form y=mx+b, where x is any of the image axes.";
05846 }
05847
05848 static Processor * NEW()
05849 {
05850 return new TestImageGradient();
05851 }
05852
05853 virtual TypeDict get_param_types() const
05854 {
05855 TypeDict d;
05856 d.put("axis", EMObject::STRING, "The axis the will be used to determine pixel values. Must be x,y or z");
05857 d.put("m", EMObject::FLOAT, "m in the equation m*axis+b. Default is 1.0");
05858 d.put("b", EMObject::FLOAT, "b in the equation m*axis+b. Default is 0.0");
05859 return d;
05860 }
05861
05862 static const string NAME;
05863 };
05864
05872 class TestImageAxes : public TestImageProcessor
05873 {
05874 public:
05879 virtual void process_inplace(EMData * image);
05880
05881 virtual string get_name() const
05882 {
05883 return NAME;
05884 }
05885
05886 virtual string get_desc() const
05887 {
05888 return "Make an image consisting of a single cross";
05889 }
05890
05891 static Processor * NEW()
05892 {
05893 return new TestImageAxes();
05894 }
05895
05896 virtual TypeDict get_param_types() const
05897 {
05898 TypeDict d;
05899 d.put("int", EMObject::FLOAT, "radius of the lines emanating from the origin");
05900 d.put("fill", EMObject::FLOAT, "value to make non-zero pixels");
05901 return d;
05902 }
05903
05904 static const string NAME;
05905 };
05906
05912 class TestImageGaussian : public TestImageProcessor
05913 {
05914 public:
05915 virtual void process_inplace(EMData * image);
05916
05917 virtual string get_name() const
05918 {
05919 return NAME;
05920 }
05921
05922 virtual string get_desc() const
05923 {
05924 return "Replace a source image as a Gaussian Blob";
05925 }
05926
05927 static Processor * NEW()
05928 {
05929 return new TestImageGaussian();
05930 }
05931
05932 virtual TypeDict get_param_types() const
05933 {
05934 TypeDict d;
05935 d.put("sigma", EMObject::FLOAT, "sigma value for this Gaussian blob");
05936 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
05937 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
05938 return d;
05939 }
05940
05941 static const string NAME;
05942 };
05943
05946 class TestImageScurve : public TestImageProcessor
05947 {
05948 public:
05949 virtual void process_inplace(EMData * image);
05950
05951 virtual string get_name() const
05952 {
05953 return NAME;
05954 }
05955
05956 virtual string get_desc() const
05957 {
05958 return "Replace a source image with a lumpy S-curve used for alignment testing";
05959 }
05960
05961 static Processor * NEW()
05962 {
05963 return new TestImageScurve();
05964 }
05965
05966 virtual TypeDict get_param_types() const
05967 {
05968 TypeDict d;
05969 return d;
05970 }
05971
05972 static const string NAME;
05973 };
05974
05982 class TestImageSphericalWave : public TestImageProcessor
05983 {
05984 public:
05985 virtual void process_inplace(EMData * image);
05986
05987 virtual string get_name() const
05988 {
05989 return NAME;
05990 }
05991
05992 virtual string get_desc() const
05993 {
05994 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)";
05995 }
05996
05997 static Processor * NEW()
05998 {
05999 return new TestImageSphericalWave();
06000 }
06001
06002 virtual TypeDict get_param_types() const
06003 {
06004 TypeDict d;
06005 d.put("wavelength", EMObject::FLOAT, "cos(2*pi*r/wavelength+phase)");
06006 d.put("phase", EMObject::FLOAT, "in radians");
06007 d.put("x", EMObject::FLOAT, "center of the spherical wave");
06008 d.put("y", EMObject::FLOAT, "center of the spherical wave");
06009 d.put("z", EMObject::FLOAT, "center of the spherical wave");
06010 return d;
06011 }
06012
06013 static const string NAME;
06014 };
06015
06016
06025 class TestImageSinewave : public TestImageProcessor
06026 {
06027 public:
06028 virtual void process_inplace(EMData * image);
06029
06030 virtual string get_name() const
06031 {
06032 return NAME;
06033 }
06034
06035 virtual string get_desc() const
06036 {
06037 return "Replace a source image as a sine wave in specified wave length";
06038 }
06039
06040 static Processor * NEW()
06041 {
06042 return new TestImageSinewave();
06043 }
06044
06045 virtual TypeDict get_param_types() const
06046 {
06047 TypeDict d;
06048 d.put("wavelength", EMObject::FLOAT, "wavelength in equation sin(x*2*PI/wavelength - phase*180/PI)");
06049 d.put("axis", EMObject::STRING, "(optional) specify a major axis for asymmetric features, default x axis");
06050 d.put("phase", EMObject::FLOAT, "(optional) the phase in radians");
06051 d.put("az", EMObject::FLOAT, "(optional) angle in degree. for 2D image, this is the rotated angle of the image, \
06052 in 3D image, it's az for euler angle. default is zero");
06053 d.put("alt", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, alt for euler angle, default is zero");
06054 d.put("phi", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, phi for euler angle, default is zero");
06055 return d;
06056 }
06057
06058 static const string NAME;
06059 };
06060
06067 class TestImageSinewaveCircular : public TestImageProcessor
06068 {
06069 public:
06070 virtual void process_inplace(EMData * image);
06071
06072 virtual string get_name() const
06073 {
06074 return NAME;
06075 }
06076
06077 virtual string get_desc() const
06078 {
06079 return "Replace a source image as a circular sine wave in specified wave length";
06080 }
06081
06082 static Processor * NEW()
06083 {
06084 return new TestImageSinewaveCircular();
06085 }
06086
06087 virtual TypeDict get_param_types() const
06088 {
06089 TypeDict d;
06090 d.put("wavelength", EMObject::FLOAT, "(required)this value is the d in function |sin(x/d)|, unit: pixel");
06091 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06092 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06093 d.put("phase", EMObject::FLOAT, "(optional)phase for sine wave, default is 0");
06094 return d;
06095 }
06096
06097 static const string NAME;
06098 };
06099
06106 class TestImageSquarecube : public TestImageProcessor
06107 {
06108 public:
06109 virtual void process_inplace(EMData * image);
06110
06111 virtual string get_name() const
06112 {
06113 return NAME;
06114 }
06115
06116 virtual string get_desc() const
06117 {
06118 return "Replace a source image as a square or cube depends on 2D or 3D of the source image";
06119 }
06120
06121 static Processor * NEW()
06122 {
06123 return new TestImageSquarecube();
06124 }
06125
06126 virtual TypeDict get_param_types() const
06127 {
06128 TypeDict d;
06129 d.put("edge_length", EMObject::FLOAT, "edge length of the square or cube, unit: pixel");
06130 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06131 d.put("odd_edge", EMObject::FLOAT, "edge length for the asymmetric axis");
06132 d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank");
06133 return d;
06134 }
06135
06136 static const string NAME;
06137 };
06138
06146 class TestImageEllipse : public TestImageProcessor
06147 {
06148 public:
06149 virtual void process_inplace(EMData * image);
06150
06151 virtual string get_name() const
06152 {
06153 return NAME;
06154 }
06155
06156 virtual string get_desc() const
06157 {
06158 return "Insert an ellipse into the image.";
06159 }
06160
06161 static Processor * NEW()
06162 {
06163 return new TestImageEllipse();
06164 }
06165
06166 virtual TypeDict get_param_types() const
06167 {
06168 TypeDict d;
06169 d.put("a", EMObject::FLOAT, "equatorial radius along x axes (major semiaxes)");
06170 d.put("b", EMObject::FLOAT, "equatorial radius along y axes (minor semiaxes)");
06171 d.put("c", EMObject::FLOAT, "polar radius for ellipsoid (x^2/a^2+y^2/b^2+z^2/c^2=1)");
06172 d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06173 d.put("fill", EMObject::FLOAT, "value you want to fill in ellipse, default to 1.0");
06174 return d;
06175 }
06176
06177 static const string NAME;
06178 };
06179
06191 class TestImageHollowEllipse : public TestImageProcessor
06192 {
06193 public:
06194 virtual void process_inplace(EMData * image);
06195
06196 virtual string get_name() const
06197 {
06198 return NAME;
06199 }
06200
06201 virtual string get_desc() const
06202 {
06203 return "Insert a hollow ellipse into the image.";
06204 }
06205
06206 static Processor * NEW()
06207 {
06208 return new TestImageHollowEllipse();
06209 }
06210
06211 virtual TypeDict get_param_types() const
06212 {
06213 TypeDict d;
06214 d.put("xwidth", EMObject::FLOAT, "inner equatorial radii along x axes");
06215 d.put("ywidth", EMObject::FLOAT, "inner equatorial radii along y axes");
06216 d.put("zwidth", EMObject::FLOAT, "inner polar radius");
06217 d.put("a", EMObject::FLOAT, "outter equatorial radii along x axes");
06218 d.put("b", EMObject::FLOAT, "outter equatorial radii along y axes");
06219 d.put("c", EMObject::FLOAT, "outter polar radius");
06220 d.put("width",EMObject::FLOAT, "width - specify the width or specify each width explicitly - xwidth, ywidth, zwidth");
06221 d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06222 d.put("fill", EMObject::FLOAT, "value you want to fill in hollow ellipse, default to 1.0");
06223 return d;
06224 }
06225
06226 static const string NAME;
06227 };
06228
06235 class TestImageCirclesphere : public TestImageProcessor
06236 {
06237 public:
06238 virtual void process_inplace(EMData * image);
06239
06240 virtual string get_name() const
06241 {
06242 return NAME;
06243 }
06244
06245 virtual string get_desc() const
06246 {
06247 return "Replace a source image as a circle or sphere depends on 2D or 3D of the source image";
06248 }
06249
06250 static Processor * NEW()
06251 {
06252 return new TestImageCirclesphere();
06253 }
06254
06255 virtual TypeDict get_param_types() const
06256 {
06257 TypeDict d;
06258 d.put("radius", EMObject::FLOAT, "radius of circle or sphere, unit: pixel");
06259 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06260 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06261 d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank.");
06262 return d;
06263 }
06264
06265 static const string NAME;
06266 };
06267
06272 class TestImageNoiseUniformRand : public TestImageProcessor
06273 {
06274 public:
06275 virtual void process_inplace(EMData * image);
06276
06277 virtual string get_name() const
06278 {
06279 return NAME;
06280 }
06281
06282 virtual string get_desc() const
06283 {
06284 return "Replace a source image as a uniform random noise, random number generated from gsl_rng_mt19937, the pixel value is [0, 1)";
06285 }
06286
06287 static Processor * NEW()
06288 {
06289 return new TestImageNoiseUniformRand();
06290 }
06291
06292 virtual TypeDict get_param_types() const
06293 {
06294 TypeDict d;
06295 d.put("seed", EMObject::INT, "seed for random number generator");
06296 return d;
06297 }
06298
06299 static const string NAME;
06300 };
06301
06312 class TestImageNoiseGauss : public TestImageProcessor
06313 {
06314 public:
06315 virtual void process_inplace(EMData * image);
06316
06317 virtual string get_name() const
06318 {
06319 return NAME;
06320 }
06321
06322 virtual string get_desc() const
06323 {
06324 return "Replace a source image as a random noise, the random value is gaussian distributed";
06325 }
06326
06327 static Processor * NEW()
06328 {
06329 return new TestImageNoiseGauss();
06330 }
06331
06332 virtual TypeDict get_param_types() const
06333 {
06334 TypeDict d;
06335 d.put("sigma", EMObject::FLOAT, "sigma value of gausian distributed noise, default is 0.5");
06336 d.put("mean", EMObject::FLOAT, "mean value of gausian distributed noise, default is zero.");
06337 d.put("seed", EMObject::INT, "the seed for random number generator, default is not to reseed.");
06338
06339 return d;
06340 }
06341
06342 static const string NAME;
06343 };
06344
06349 class TestImageCylinder : public TestImageProcessor
06350 {
06351 public:
06352 virtual void process_inplace(EMData * image);
06353
06354 virtual string get_name() const
06355 {
06356 return NAME;
06357 }
06358
06359 virtual string get_desc() const
06360 {
06361 return "Replace a source image as a cylinder";
06362 }
06363
06364 static Processor * NEW()
06365 {
06366 return new TestImageCylinder();
06367 }
06368
06369 virtual TypeDict get_param_types() const
06370 {
06371 TypeDict d;
06372 d.put("radius", EMObject::FLOAT, "radius for the cylinder");
06373 d.put("height", EMObject::FLOAT, "height for the cylinder, by default it's the nz");
06374
06375 return d;
06376 }
06377
06378 static const string NAME;
06379 };
06380
06386 class CCDNormProcessor:public Processor
06387 {
06388 public:
06389 virtual void process_inplace(EMData * image);
06390
06391 virtual string get_name() const
06392 {
06393 return NAME;
06394 }
06395
06396 static Processor *NEW()
06397 {
06398 return new CCDNormProcessor();
06399 }
06400
06401 virtual string get_desc() const
06402 {
06403 return "normalize the 4 quadrants of a CCD image";
06404 }
06405
06406 virtual TypeDict get_param_types() const
06407 {
06408 TypeDict d;
06409 d.put("width", EMObject::INT, "number of pixels on either side of the seam to sample");
06410 return d;
06411 }
06412
06413 static const string NAME;
06414 };
06415
06423 class WaveletProcessor:public Processor
06424 {
06425 public:
06426 virtual void process_inplace(EMData * image);
06427
06428 virtual string get_name() const
06429 {
06430 return NAME;
06431 }
06432
06433 static Processor *NEW()
06434 {
06435 return new WaveletProcessor();
06436 }
06437
06438 virtual TypeDict get_param_types() const
06439 {
06440 TypeDict d;
06441 d.put("type", EMObject::STRING, "'daub', 'harr' or 'bspl'");
06442 d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06443 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)");
06444 return d;
06445 }
06446
06447 virtual string get_desc() const
06448 {
06449 return "Computes the DWT (discrete wavelet transform) of an image in one of 3 possible bases";
06450 }
06451
06452 static const string NAME;
06453 };
06454
06470 class TomoTiltEdgeMaskProcessor : public Processor
06471 {
06472 public:
06473 virtual void process_inplace(EMData* image);
06474
06475 virtual string get_name() const
06476 {
06477 return NAME;
06478 }
06479
06480 static Processor *NEW()
06481 {
06482 return new TomoTiltEdgeMaskProcessor();
06483 }
06484
06485 virtual TypeDict get_param_types() const
06486 {
06487 TypeDict d;
06488 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");
06489 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.");
06490 d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06491 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.");
06492 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)");
06493 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");
06494 return d;
06495 }
06496
06497 virtual string get_desc() const
06498 {
06499 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.";
06500 }
06501
06502 static const string NAME;
06503
06504 private:
06505 class GaussianFunctoid
06506 {
06507 public:
06508 GaussianFunctoid(const float sigma, const float mean = 0.0) : m_mean(mean), m_sigma_squared(sigma*sigma) {}
06509 ~GaussianFunctoid() {}
06510
06511 float operator()(const float distance )
06512 {
06513 return exp( -(distance-m_mean)*(distance-m_mean)/ (m_sigma_squared ));
06514 }
06515 private:
06516 float m_mean, m_sigma_squared;
06517 };
06518
06519 };
06520
06535 class TomoTiltAngleWeightProcessor : public Processor
06536 {
06537 public:
06538 virtual void process_inplace(EMData* image);
06539
06540 virtual string get_name() const
06541 {
06542 return NAME;
06543 }
06544
06545 static Processor *NEW()
06546 {
06547 return new TomoTiltAngleWeightProcessor();
06548 }
06549
06550 virtual TypeDict get_param_types() const
06551 {
06552 TypeDict d;
06553 d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06554 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");
06555 return d;
06556 }
06557
06558 virtual string get_desc() const
06559 {
06560 return "Weights the image by 1/cos(angle)";
06561 }
06562
06563 static const string NAME;
06564
06565 };
06566
06570 class FFTProcessor : public Processor
06571 {
06572 public:
06573 void process_inplace(EMData * image);
06574
06575 string get_name() const
06576 {
06577 return NAME;
06578 }
06579
06580 static Processor *NEW()
06581 {
06582 return new FFTProcessor();
06583 }
06584
06585 TypeDict get_param_types() const
06586 {
06587 TypeDict d;
06588 d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06589 return d;
06590 }
06591
06592 string get_desc() const
06593 {
06594 return "Computes the DFFT (Discrete Fast Fourier Transform) of an image";
06595 }
06596
06597 static const string NAME;
06598 };
06599
06604 class RadialProcessor : public Processor
06605 {
06606 public:
06607 void process_inplace(EMData * image);
06608
06609 string get_name() const
06610 {
06611 return NAME;
06612 }
06613
06614 static Processor *NEW()
06615 {
06616 return new RadialProcessor();
06617 }
06618
06619 TypeDict get_param_types() const
06620 {
06621 TypeDict d;
06622 d.put("table", EMObject::FLOATARRAY, "Radial array of floats, 1 float/pixel");
06623 return d;
06624 }
06625
06626 string get_desc() const
06627 {
06628 return "Multiply a real-space image by a radial function. 1 value / pixel, extending to corner. Missing values -> 0.";
06629 }
06630
06631 static const string NAME;
06632 };
06633
06640 class HistogramBin : public Processor
06641 {
06642 public:
06643 HistogramBin() : default_bins(1024) {}
06644
06645 void process_inplace(EMData * image);
06646
06647 string get_name() const
06648 {
06649 return NAME;
06650 }
06651
06652 static Processor *NEW()
06653 {
06654 return new HistogramBin();
06655 }
06656
06657 TypeDict get_param_types() const
06658 {
06659 TypeDict d;
06660 d.put("nbins", EMObject::INT, "The number of bins the pixel values will be compressed into");
06661 d.put("debug", EMObject::BOOL, "Outputs debugging information (number of pixels per bin)");
06662 return d;
06663 }
06664
06665 string get_desc() const
06666 {
06667 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";
06668 }
06669
06670 static const string NAME;
06671
06672 protected:
06673 int default_bins;
06674 };
06675
06676 class ModelHelixProcessor : public Processor
06677 {
06678 protected:
06679 float radprofile(float r, int type);
06680 };
06681
06682 class ModelEMCylinderProcessor : public ModelHelixProcessor
06683 {
06684 public:
06685 void process_inplace(EMData * in);
06686
06687 string get_name() const
06688 {
06689 return NAME;
06690 }
06691
06692 static Processor *NEW()
06693 {
06694 return new ModelEMCylinderProcessor();
06695 }
06696
06697 string get_desc() const
06698 {
06699 return "Adds a cylinder with a radial density profile similar to that of an alpha helix.";
06700 }
06701
06702 virtual TypeDict get_param_types() const
06703 {
06704 TypeDict d;
06705 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");
06706 d.put("length", EMObject::FLOAT, "cylinder length in angstroms, defaults to 3 turns (16.2 Angstroms)");
06707 d.put("x0", EMObject::INT, "x coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06708 d.put("y0", EMObject::INT, "y coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06709 d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06710
06711 return d;
06712 }
06713
06714 static const string NAME;
06715 };
06716
06717 class ApplyPolynomialProfileToHelix : public ModelHelixProcessor
06718 {
06719 public:
06720 void process_inplace(EMData * in);
06721
06722 string get_name() const
06723 {
06724 return NAME;
06725 }
06726
06727 static Processor *NEW()
06728 {
06729 return new ApplyPolynomialProfileToHelix();
06730 }
06731
06732 string get_desc() const
06733 {
06734 return "Finds the CM of each z-axis slice and applies a polynomial radial profile about it.";
06735 }
06736 virtual TypeDict get_param_types() const
06737 {
06738 TypeDict d;
06739 d.put("length", EMObject::FLOAT, "Helix length in angstroms.");
06740 d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06741 return d;
06742 }
06743
06744 static const string NAME;
06745 };
06746
06747 class BinarySkeletonizerProcessor : public Processor
06748 {
06749 public:
06750 virtual EMData* process(EMData * image);
06751 virtual void process_inplace(EMData * image);
06752
06753 virtual string get_name() const
06754 {
06755 return NAME;
06756
06757 }
06758 static Processor *NEW()
06759 {
06760 return new BinarySkeletonizerProcessor();
06761 }
06762 string get_desc() const
06763 {
06764 return "Creates a skeleton of the 3D image by considering whether density is above or below a threshold value.";
06765 }
06766 virtual TypeDict get_param_types() const
06767 {
06768 TypeDict d;
06769 d.put("threshold", EMObject::FLOAT, "Threshold value.");
06770 d.put("min_curve_width", EMObject::INT, "Minimum curve width.");
06771 d.put("min_surface_width", EMObject::INT, "Minimum surface width.");
06772 d.put("mark_surfaces", EMObject::BOOL, "Mark surfaces with a value of 2.0f, whereas curves are 1.0f.");
06773 return d;
06774 }
06775 static const string NAME;
06776 };
06777
06778 #ifdef EMAN2_USING_CUDA
06779
06784 class CudaMultProcessor: public Processor
06785 {
06786 public:
06787
06788 virtual void process_inplace(EMData * image);
06789
06790 virtual string get_name() const
06791 {
06792 return NAME;
06793 }
06794
06795 static Processor *NEW()
06796 {
06797 return new CudaMultProcessor();
06798 }
06799
06800 virtual TypeDict get_param_types() const
06801 {
06802 TypeDict d;
06803 d.put("scale", EMObject::FLOAT, "The amount to multiply each pixel by");
06804 return d;
06805 }
06806
06807 virtual string get_desc() const
06808 {
06809 return "Multiplies each pixel by a constant value";
06810 }
06811
06812 static const string NAME;
06813
06814 protected:
06815 };
06816
06822 class CudaCorrelationProcessor: public Processor
06823 {
06824 public:
06825
06826 virtual void process_inplace(EMData * image);
06827
06828 string get_name() const
06829 {
06830 return NAME;
06831 }
06832
06833 static Processor *NEW()
06834 {
06835 return new CudaCorrelationProcessor();
06836 }
06837
06838 virtual TypeDict get_param_types() const
06839 {
06840 TypeDict d;
06841 d.put("with", EMObject::EMDATA, "That which to perform the cross correlation with.");
06842 return d;
06843 }
06844
06845 virtual string get_desc() const
06846 {
06847 return "Performs Fourier based cross correlation on the GPU";
06848 }
06849
06850 static const string NAME;
06851
06852 protected:
06853 };
06854
06855
06856
06857
06858
06859
06860 class MPICUDA_kmeans {
06861 public:
06862 MPICUDA_kmeans();
06863 ~MPICUDA_kmeans();
06864 int setup(int extm, int extN, int extn, int extK, int extn_start);
06865 void append_flat_image(EMData* im, int pos);
06866 int init_mem(int numdev);
06867 void compute_im2();
06868 int random_ASG(long int rnd);
06869 vector<int> get_ASG();
06870 vector<int> get_asg();
06871 void compute_NC();
06872 vector<int> get_NC();
06873 void set_ASG(const vector <int>& ASG);
06874 void set_NC(const vector <int>& NC);
06875 int get_ct_im_mv();
06876 void set_T(float extT);
06877 float get_T();
06878 void compute_AVE();
06879 void set_AVE(EMData* im, int pos);
06880 vector<EMData*> get_AVE();
06881 int one_iter();
06882 int one_iter_SA();
06883 vector<float> compute_ji();
06884 vector<float> compute_criterion(const vector <float>& Ji);
06885 int shutdown();
06886 private:
06887
06888 int m;
06889 int N;
06890 int n;
06891 int K;
06892 int nb_part;
06893 int n_start;
06894 int size_im;
06895 int size_IM;
06896 int size_AVE;
06897 int size_dist;
06898 int BLOCK_SIZE;
06899 int NB;
06900 int ins_BLOCK;
06901 int ite;
06902 float T;
06903
06904 int ct_im_mv;
06905
06906 float* h_IM;
06907 float* h_im;
06908 float* h_AVE;
06909 float* h_dist;
06910 float* h_AVE2;
06911 float* h_im2;
06912 unsigned short int* h_ASG;
06913 unsigned short int* h_asg;
06914 unsigned int* h_NC;
06915 int* params;
06916
06917 float* d_im;
06918 float* d_AVE;
06919 float* d_dist;
06920 };
06921
06922 #endif //EMAN2_USING_CUDA
06923
06924 #if 0
06925
06926 class XYZProcessor:public Processor
06927 {
06928 public:
06929 void process_inplace(EMData * image);
06930
06931 string get_name() const
06932 {
06933 return NAME;
06934 }
06935
06936 static Processor *NEW()
06937 {
06938 return new XYZProcessor();
06939 }
06940
06941 string get_desc() const
06942 {
06943 return "N/A";
06944 }
06945
06946 TypeDict get_param_types() const
06947 {
06948 TypeDict d;
06949 return d;
06950 }
06951
06952 static const string NAME;
06953 };
06954
06955
06956 #endif
06957
06958
06959 int multi_processors(EMData * image, vector < string > processornames);
06960 void dump_processors();
06961 map<string, vector<string> > dump_processors_list();
06962 map<string, vector<string> > group_processors();
06963
06964 template <> Factory < Processor >::Factory();
06965 }
06966
06967 #endif //eman_filter_h__
06968
06969
06970