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
00719 class KmeansSegmentProcessor:public Processor
00720 {
00721 public:
00722 string get_name() const
00723 {
00724 return NAME;
00725 }
00726
00727 virtual EMData* process(const EMData * const image);
00728 void process_inplace( EMData * image);
00729
00730 TypeDict get_param_types() const
00731 {
00732 TypeDict d ;
00733 d.put("nseg", EMObject::INT, "Number of segments to divide the image into. default=12" );
00734 d.put("thr",EMObject::FLOAT,"Isosurface threshold value. Pixels below this will not be segmented");
00735 d.put("ampweight",EMObject::INT,"If set, will weight centers by voxel amplitude. default = 1");
00736 d.put("maxsegsize",EMObject::FLOAT,"Maximum radial distance from segment center to member voxel. Default=10000");
00737 d.put("minsegsep",EMObject::FLOAT,"Minimum segment separation. Segments too close will trigger a reseed");
00738 d.put("maxiter",EMObject::FLOAT,"Maximum number of iterations to run before stopping. Default=100");
00739 d.put("maxvoxmove",EMObject::FLOAT,"Maximum number of voxels that can move before quitting. Default=25");
00740 d.put("verbose",EMObject::INT,"Be verbose while running");
00741 return d;
00742 }
00743
00744 static Processor *NEW()
00745 {
00746 return new KmeansSegmentProcessor();
00747 }
00748
00749 string get_desc() const
00750 {
00751 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.";
00752 }
00753
00754 static const string NAME;
00755
00756 };
00757
00758
00765 class Wiener2DFourierProcessor:public Processor
00766 {
00767 public:
00768 string get_name() const
00769 {
00770 return NAME;
00771 }
00772
00773 virtual EMData* process(const EMData * const image);
00774
00775 void process_inplace(EMData *image);
00776
00777 void set_params(const Dict & new_params)
00778 {
00779 params = new_params;
00780 ctf = params["ctf"];
00781
00782 }
00783
00784 TypeDict get_param_types() const
00785 {
00786 TypeDict d;
00787 d.put("ctf", EMObject::EMDATA, "Ctf object to use for Wiener filter parameters");
00788 return d;
00789 }
00790
00791 static Processor *NEW()
00792 {
00793 return new Wiener2DFourierProcessor();
00794 }
00795
00796 string get_desc() const
00797 {
00798 return "Applies a 2-D Wiener filter to an image based on its Ctf parameters";
00799 }
00800
00801 static const string NAME;
00802
00803 protected:
00804 Ctf *ctf;
00805 };
00806
00810 class LowpassFourierProcessor:public FourierProcessor
00811 {
00812 public:
00813 LowpassFourierProcessor():lowpass(0)
00814 {
00815 }
00816
00817 void set_params(const Dict & new_params)
00818 {
00819 params = new_params;
00820 if( params.has_key("lowpass") ) {
00821 lowpass = params["lowpass"];
00822 }
00823
00824 }
00825
00826 TypeDict get_param_types() const
00827 {
00828 TypeDict d = FourierProcessor::get_param_types();
00829 d.put("lowpass", EMObject::FLOAT, "Processor radius in terms of Nyquist (0-.5)");
00830 return d;
00831 }
00832
00833 static string get_group_desc()
00834 {
00835 return "Low-pass processor attenuates amplitudes at high spatial frequencies. It has the result of blurring the image, and of eliminating sharp edges and noise. The base class for all low pass fourier processors.";
00836 }
00837
00838 protected:
00839 virtual void preprocess(EMData * image);
00840 float lowpass;
00841 };
00842
00843 class LinearRampFourierProcessor:public FourierProcessor
00844 {
00845 public:
00846 virtual string get_name() const
00847 {
00848 return NAME;
00849 }
00850
00851 virtual string get_desc() const
00852 {
00853 return "";
00854 }
00855
00856 static Processor *NEW()
00857 {
00858 return new LinearRampFourierProcessor();
00859 }
00860
00861 static const string NAME;
00862
00863 protected:
00864 virtual void create_radial_func(vector < float >&radial_mask) const ;
00865 };
00866
00870 class HighpassFourierProcessor:public FourierProcessor
00871 {
00872 public:
00873 HighpassFourierProcessor():highpass(0)
00874 {
00875 }
00876
00877 void set_params(const Dict & new_params)
00878 {
00879 params = new_params;
00880 if( params.has_key("highpass") ) {
00881 highpass = params["highpass"];
00882 }
00883 }
00884
00885 TypeDict get_param_types() const
00886 {
00887 TypeDict d = FourierProcessor::get_param_types();
00888 d.put("highpass", EMObject::FLOAT, "Processor radius in terms of Nyquist (0-.5)");
00889 return d;
00890 }
00891
00892 static string get_group_desc()
00893 {
00894 return "High-pass processor is rotationally symmetric 2D function. It attenuates amplitudes at low spatial frequencies, and increases amplitudes for high spatial frequencies. It has the result of enhancing the edges in the image while suppressing all slow-moving variations. <br> HighpassFourierProcessor class is the base class for all high pass fourier processors.";
00895 }
00896
00897 protected:
00898 virtual void preprocess(EMData * image);
00899 float highpass;
00900 };
00901
00904 class LowpassSharpCutoffProcessor:public LowpassFourierProcessor
00905 {
00906 public:
00907 string get_name() const
00908 {
00909 return NAME;
00910 }
00911
00912 static Processor *NEW()
00913 {
00914 return new LowpassSharpCutoffProcessor();
00915 }
00916
00917 string get_desc() const
00918 {
00919 return "processor radial function: if x <= lowpass, f(x) = 1; else f(x) = 0;";
00920 }
00921
00922 static const string NAME;
00923
00924 protected:
00925 void create_radial_func(vector < float >&radial_mask) const;
00926 };
00927
00930 class HighpassSharpCutoffProcessor:public HighpassFourierProcessor
00931 {
00932 public:
00933 string get_name() const
00934 {
00935 return NAME;
00936 }
00937
00938 static Processor *NEW()
00939 {
00940 return new HighpassSharpCutoffProcessor();
00941 }
00942
00943 string get_desc() const
00944 {
00945 return "processor radial function: if x >= highpass, f(x) = 1; else f(x) = 0;";
00946 }
00947
00948 static const string NAME;
00949
00950 protected:
00951 void create_radial_func(vector < float >&radial_mask) const;
00952 };
00953
00956 class LowpassGaussProcessor:public LowpassFourierProcessor
00957 {
00958 public:
00959 string get_name() const
00960 {
00961 return NAME;
00962 }
00963
00964 static Processor *NEW()
00965 {
00966 return new LowpassGaussProcessor();
00967 }
00968
00969 string get_desc() const
00970 {
00971 return "processor radial function: if lowpass > 0, f(x) = exp(-x*x/(lowpass*lowpass)); else f(x) = exp(x*x/(lowpass*lowpass));";
00972 }
00973
00974 static const string NAME;
00975
00976 protected:
00977 void create_radial_func(vector < float >&radial_mask) const;
00978 };
00979
00982 class LowpassAutoBProcessor:public FourierAnlProcessor
00983 {
00984 public:
00985 string get_name() const
00986 {
00987 return NAME;
00988 }
00989
00990 static Processor *NEW()
00991 {
00992 return new LowpassAutoBProcessor();
00993 }
00994
00995 string get_desc() const
00996 {
00997 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.";
00998 }
00999
01000 static const string NAME;
01001
01002 virtual TypeDict get_param_types() const
01003 {
01004 TypeDict d = FourierAnlProcessor::get_param_types();
01005 d.put("bfactor", EMObject::FLOAT, "B-factor in terms of e^-(B s^2/4)");
01006 d.put("noisecutoff", EMObject::FLOAT, "Spatial frequency past which inverse-B will not be applied");
01007
01008 d.put("verbose", EMObject::INT, "Print information about the determined B-factor");
01009 return d;
01010 }
01011
01012 protected:
01013 virtual void preprocess(EMData * image) {
01014 if(params.has_key("apix")) {
01015 image->set_attr("apix_x", (float)params["apix"]);
01016 image->set_attr("apix_y", (float)params["apix"]);
01017 image->set_attr("apix_z", (float)params["apix"]);
01018 }
01019 float apix=(float)image->get_attr("apix_x");
01020
01021 const Dict dict = image->get_attr_dict();
01022 if (params.has_key("cutoff_abs")) {
01023 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
01024 }
01025 else if( params.has_key("cutoff_freq") ) {
01026 float val = (float)params["cutoff_freq"] * apix;
01027 params["cutoff_abs"] = val;
01028 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
01029 }
01030 else if( params.has_key("cutoff_pixels") ) {
01031 float val = 0.5f*(float)params["cutoff_pixels"] / (float)dict["nx"];
01032 params["cutoff_abs"] = val;
01033 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
01034 }
01035 }
01036
01037 void create_radial_func(vector < float >&radial_mask,EMData *image) const;
01038 };
01039
01042 class HighpassAutoPeakProcessor:public FourierAnlProcessor
01043 {
01044 public:
01045 string get_name() const
01046 {
01047 return NAME;
01048 }
01049 static Processor *NEW()
01050 {
01051 return new HighpassAutoPeakProcessor();
01052 }
01053
01054 string get_desc() const
01055 {
01056 return "Attempts to automatically remove the low resolution peak present in virtually all cryoEM data.";
01057 }
01058
01059 static const string NAME;
01060
01061 protected:
01062 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
01063 virtual void preprocess(EMData * image);
01064 float highpass;
01065 };
01066
01067
01070 class HighpassGaussProcessor:public HighpassFourierProcessor
01071 {
01072 public:
01073 string get_name() const
01074 {
01075 return NAME;
01076 }
01077 static Processor *NEW()
01078 {
01079 return new HighpassGaussProcessor();
01080 }
01081
01082 string get_desc() const
01083 {
01084 return "processor radial function: f(x) = 1.0-exp(-x*x/(highpass*highpass);";
01085 }
01086
01087 static const string NAME;
01088
01089 protected:
01090 void create_radial_func(vector < float >&radial_mask) const;
01091 };
01092
01095 class LowpassTanhProcessor:public LowpassFourierProcessor
01096 {
01097 public:
01098 string get_name() const
01099 {
01100 return NAME;
01101 }
01102 static Processor *NEW()
01103 {
01104 return new LowpassTanhProcessor();
01105 }
01106
01107 string get_desc() const
01108 {
01109 return "processor radial function: f(x)=tanh(lowpass-x)/2.0 + 0.5;";
01110 }
01111
01112 static const string NAME;
01113
01114 protected:
01115 void create_radial_func(vector < float >&radial_mask) const;
01116 };
01117
01118
01121 class HighpassTanhProcessor:public HighpassFourierProcessor
01122 {
01123 public:
01124 string get_name() const
01125 {
01126 return NAME;
01127 }
01128 static Processor *NEW()
01129 {
01130 return new HighpassTanhProcessor();
01131 }
01132
01133 string get_desc() const
01134 {
01135 return "processor radial function: f(x)=tanh(x-highpass)/2.0+0.5;";
01136 }
01137
01138 static const string NAME;
01139
01140 protected:
01141 void create_radial_func(vector < float >&radial_mask) const;
01142 };
01143
01146 class HighpassButterworthProcessor:public HighpassFourierProcessor
01147 {
01148 public:
01149 string get_name() const
01150 {
01151 return NAME;
01152 }
01153 static Processor *NEW()
01154 {
01155 return new HighpassButterworthProcessor();
01156 }
01157
01158 string get_desc() const
01159 {
01160 return "processor radial function: f(x) = 1/(1+t*t);";
01161 }
01162
01163 static const string NAME;
01164
01165 protected:
01166 void create_radial_func(vector < float >&radial_mask) const;
01167 };
01168
01173 class LinearRampProcessor:public FourierProcessor
01174 {
01175 public:
01176 LinearRampProcessor():intercept(0), slope(0)
01177 {
01178 }
01179
01180 string get_name() const
01181 {
01182 return NAME;
01183 }
01184 static Processor *NEW()
01185 {
01186 return new LinearRampProcessor();
01187 }
01188
01189 string get_desc() const
01190 {
01191 return "processor radial function: f(x) = slope * x + intercept;";
01192 }
01193
01194 void set_params(const Dict & new_params)
01195 {
01196 params = new_params;
01197 intercept = params["intercept"];
01198 slope = params["slope"];
01199 }
01200
01201 TypeDict get_param_types() const
01202 {
01203 TypeDict d;
01204 d.put("intercept", EMObject::FLOAT, "intercept in 'f(x) = slope * x + intercept'");
01205 d.put("slope", EMObject::FLOAT, "slope in 'f(x) = slope * x + intercept'");
01206 return d;
01207 }
01208
01209 static const string NAME;
01210
01211 protected:
01212 void create_radial_func(vector < float >&radial_mask) const;
01213
01214 private:
01215 float intercept;
01216 float slope;
01217 };
01218
01221 class RealPixelProcessor:public Processor
01222 {
01223 public:
01224 RealPixelProcessor():value(0), maxval(1), mean(0), sigma(0)
01225 {
01226 }
01227 void process_inplace(EMData * image);
01228
01229 virtual void set_params(const Dict & new_params)
01230 {
01231 params = new_params;
01232 if (params.size() == 1) {
01233 vector < EMObject > dict_values = params.values();
01234 value = dict_values[0];
01235 }
01236 }
01237
01238 static string get_group_desc()
01239 {
01240 return "The base class for real space processor working on individual pixels. The processor won't consider the pixel's coordinates and neighbors.";
01241 }
01242
01243 protected:
01244 virtual void process_pixel(float *x) const = 0;
01245 virtual void calc_locals(EMData *)
01246 {
01247 }
01248 virtual void normalize(EMData *) const
01249 {
01250 }
01251
01252 float value;
01253 float maxval;
01254 float mean;
01255 float sigma;
01256 };
01257
01260 class AbsoluateValueProcessor:public RealPixelProcessor
01261 {
01262 public:
01263 string get_name() const
01264 {
01265 return NAME;
01266 }
01267 static Processor *NEW()
01268 {
01269 return new AbsoluateValueProcessor();
01270 }
01271
01272 static const string NAME;
01273
01274 protected:
01275 void process_pixel(float *x) const
01276 {
01277 *x = fabs(*x);
01278 }
01279
01280 string get_desc() const
01281 {
01282 return "f(x) = |x|";
01283 }
01284 };
01285
01286
01289 class BooleanProcessor:public RealPixelProcessor
01290 {
01291 public:
01292 string get_name() const
01293 {
01294 return NAME;
01295 }
01296 static Processor *NEW()
01297 {
01298 return new BooleanProcessor();
01299 }
01300
01301 string get_desc() const
01302 {
01303 return "f(x) = 0 if x = 0; f(x) = 1 if x != 0;";
01304 }
01305
01306 static const string NAME;
01307
01308 protected:
01309 void process_pixel(float *x) const
01310 {
01311 if (*x != 0)
01312 {
01313 *x = 1.0;
01314 }
01315 }
01316 };
01317
01321 class InvertCarefullyProcessor:public RealPixelProcessor
01322 {
01323 public:
01324 string get_name() const
01325 {
01326 return NAME;
01327 }
01328 static Processor *NEW()
01329 {
01330 return new InvertCarefullyProcessor();
01331 }
01332
01333 void set_params(const Dict & new_params)
01334 {
01335 params = new_params;
01336 zero_to = params.set_default("zero_to",0.0f);
01337 }
01338
01339 TypeDict get_param_types() const
01340 {
01341 TypeDict d;
01342 d.put("zero_to", EMObject::FLOAT, "Inverted zero values are set to this value, default is 0.");
01343 return d;
01344 }
01345
01346 string get_desc() const
01347 {
01348 return "if f(x) != 0: f(x) = 1/f(x) else: f(x) = zero_to";
01349 }
01350
01351 static const string NAME;
01352
01353 protected:
01354 void process_pixel(float *x) const
01355 {
01356 if (*x == 0) *x = zero_to;
01357 else *x = 1/(*x);
01358 }
01359 private:
01360 float zero_to;
01361 };
01362
01366 class ValuePowProcessor:public RealPixelProcessor
01367 {
01368 public:
01369 string get_name() const
01370 {
01371 return NAME;
01372 }
01373 static Processor *NEW()
01374 {
01375 return new ValuePowProcessor();
01376 }
01377
01378 void set_params(const Dict & new_params)
01379 {
01380 params = new_params;
01381 pwr = params["pow"];
01382 }
01383
01384 TypeDict get_param_types() const
01385 {
01386 TypeDict d;
01387 d.put("pow", EMObject::FLOAT, "Each pixel is raised to this power");
01388 return d;
01389 }
01390
01391 string get_desc() const
01392 {
01393 return "f(x) = x ^ pow;";
01394 }
01395
01396 static const string NAME;
01397
01398 protected:
01399 void process_pixel(float *x) const
01400 {
01401 if (*x<0 && pwr!=(int)pwr) *x=0;
01402 else (*x) = pow(*x,pwr);
01403 }
01404 private:
01405 float pwr;
01406 };
01407
01410 class ValueSquaredProcessor:public RealPixelProcessor
01411 {
01412 public:
01413 string get_name() const
01414 {
01415 return NAME;
01416 }
01417 static Processor *NEW()
01418 {
01419 return new ValueSquaredProcessor();
01420 }
01421
01422
01423 string get_desc() const
01424 {
01425 return "f(x) = x * x;";
01426 }
01427
01428 static const string NAME;
01429
01430 protected:
01431 void process_pixel(float *x) const
01432 {
01433 (*x) *= (*x);
01434 }
01435 };
01436
01439 class ValueSqrtProcessor:public RealPixelProcessor
01440 {
01441 public:
01442 string get_name() const
01443 {
01444 return NAME;
01445 }
01446 static Processor *NEW()
01447 {
01448 return new ValueSqrtProcessor();
01449 }
01450
01451 string get_desc() const
01452 {
01453 return "f(x) = sqrt(x)";
01454 }
01455
01456 static const string NAME;
01457
01458 protected:
01459 void process_pixel(float *x) const
01460 {
01461 *x = sqrt(*x);
01462 }
01463 };
01464
01468 class ToZeroProcessor:public RealPixelProcessor
01469 {
01470 public:
01471 string get_name() const
01472 {
01473 return NAME;
01474 }
01475 static Processor *NEW()
01476 {
01477 return new ToZeroProcessor();
01478 }
01479 TypeDict get_param_types() const
01480 {
01481 TypeDict d;
01482 d.put("minval", EMObject::FLOAT, "Everything below this value is set to zero");
01483 return d;
01484 }
01485
01486 string get_desc() const
01487 {
01488 return "f(x) = x if x >= minval; f(x) = 0 if x < minval.";
01489 }
01490
01491 static const string NAME;
01492
01493 protected:
01494 inline void process_pixel(float *x) const
01495 {
01496 if (*x < value) {
01497 *x = 0;
01498 }
01499 }
01500 };
01501
01507 class Rotate180Processor:public Processor
01508 {
01509 public:
01510 string get_name() const
01511 {
01512 return NAME;
01513 }
01514 static Processor *NEW()
01515 {
01516 return new Rotate180Processor();
01517 }
01518
01522 void process_inplace(EMData* image);
01523
01524 string get_desc() const
01525 {
01526 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.";
01527 }
01528
01529 static const string NAME;
01530 };
01531
01538 class TransformProcessor:public Processor
01539 {
01540 public:
01541 virtual string get_name() const
01542 {
01543 return NAME;
01544 }
01545 static Processor *NEW()
01546 {
01547 return new TransformProcessor();
01548 }
01549
01554 virtual void process_inplace(EMData* image);
01555
01560 virtual EMData* process(const EMData* const image);
01561
01562 virtual TypeDict get_param_types() const
01563 {
01564 TypeDict d;
01565 d.put("transform", EMObject::TRANSFORM, "The Transform object that will be applied to the image" );
01566 return d;
01567 }
01568
01569 virtual string get_desc() const
01570 {
01571 return "The image is transformed using Transform parameter.";
01572 }
01573
01574 static const string NAME;
01575
01576 private:
01577 float* transform(const EMData* const image, const Transform& t) const;
01578
01579
01580
01581
01582 void assert_valid_aspect(const EMData* const image) const;
01583 };
01584
01592 class IntTranslateProcessor:public Processor
01593 {
01594 public:
01595 virtual string get_name() const
01596 {
01597 return NAME;
01598 }
01599
01600 static Processor *NEW()
01601 {
01602 return new IntTranslateProcessor();
01603 }
01604
01609 virtual void process_inplace(EMData* image);
01610
01615 virtual EMData* process(const EMData* const image);
01616
01617 virtual TypeDict get_param_types() const
01618 {
01619 TypeDict d;
01620 d.put("trans", EMObject::INTARRAY, "The displacement array, can be length 1-3" );
01621 return d;
01622 }
01623
01624 virtual string get_desc() const
01625 {
01626 return "The image is translated an integer amount";
01627 }
01628
01629 static const string NAME;
01630
01631 private:
01635 void assert_valid_aspect(const vector<int>& translation, const EMData* const image) const;
01636
01642 Region get_clip_region(vector<int>& translation, const EMData* const image) const;
01643 };
01644
01651 class ScaleTransformProcessor:public Processor
01652 {
01653 public:
01654 virtual string get_name() const
01655 {
01656 return NAME;
01657 }
01658 static Processor *NEW()
01659 {
01660 return new ScaleTransformProcessor();
01661 }
01662
01667 virtual void process_inplace(EMData* image);
01668
01673 virtual EMData* process(const EMData* const image);
01674
01675 virtual TypeDict get_param_types() const
01676 {
01677 TypeDict d;
01678 d.put("scale", EMObject::FLOAT, "The amount by which to scale" );
01679 d.put("clip", EMObject::INT, "The length of each output dimension. Non sophisticated, output dimensions can't be different" );
01682 return d;
01683 }
01684
01685 virtual string get_desc() const
01686 {
01687 return "The image is scaled with the clip variable in mind, being sure to preserve as much pixel information as possible.";
01688 }
01689
01690 static const string NAME;
01691 };
01692
01699 class ClampingProcessor :public Processor
01700 {
01701 public:
01702 ClampingProcessor() : default_max(1.0), default_min(0.0) {}
01703
01704 string get_name() const
01705 {
01706 return NAME;
01707 }
01708 static Processor *NEW()
01709 {
01710 return new ClampingProcessor();
01711 }
01712
01713 void process_inplace(EMData *image);
01714
01715 TypeDict get_param_types() const
01716 {
01717 TypeDict d;
01718 d.put("minval", EMObject::FLOAT, "The pixel values that bounds the smallest pixel value in the output image" );
01719 d.put("maxval", EMObject::FLOAT, "The pixel values that bounds the largest pixel value in the output image" );
01720 d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01721 return d;
01722 }
01723
01724 string get_desc() const
01725 {
01726 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.";
01727 }
01728
01729 static const string NAME;
01730
01731 protected:
01732 float default_max, default_min;
01733 };
01734
01740 class NSigmaClampingProcessor : public ClampingProcessor
01741 {
01742 public:
01743 NSigmaClampingProcessor() : default_sigma(2.0) {}
01744
01745 string get_name() const
01746 {
01747 return NAME;
01748 }
01749
01750 static Processor *NEW()
01751 {
01752 return new NSigmaClampingProcessor();
01753 }
01754
01755 TypeDict get_param_types() const
01756 {
01757 TypeDict d;
01758 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" );
01759 d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01760 return d;
01761 }
01762
01763 void process_inplace(EMData *image);
01764
01765 string get_desc() const
01766 {
01767 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.";
01768 }
01769
01770 static const string NAME;
01771
01772 protected:
01773 float default_sigma;
01774 };
01775
01779 class ToMinvalProcessor:public Processor
01780 {
01781 public:
01782 string get_name() const
01783 {
01784 return NAME;
01785 }
01786 static Processor *NEW()
01787 {
01788 return new ToMinvalProcessor();
01789 }
01790
01791 void process_inplace(EMData *image);
01792
01793 TypeDict get_param_types() const
01794 {
01795 TypeDict d;
01796 d.put("minval", EMObject::FLOAT, "Everything below this value is set to this value");
01797 d.put("newval", EMObject::FLOAT, "If set, values below minval will be set to newval instead of minval ");
01798 return d;
01799 }
01800
01801 string get_desc() const
01802 {
01803 return "f(x) = x if x >= minval; f(x) = minval|newval if x < minval.";
01804 }
01805
01806 static const string NAME;
01807
01808 protected:
01809
01810 };
01811
01812
01813
01817 class CutToZeroProcessor:public RealPixelProcessor
01818 {
01819 public:
01820 string get_name() const
01821 {
01822 return NAME;
01823 }
01824 static Processor *NEW()
01825 {
01826 return new CutToZeroProcessor();
01827 }
01828 TypeDict get_param_types() const
01829 {
01830 TypeDict d;
01831 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" );
01832 return d;
01833 }
01834
01835 string get_desc() const
01836 {
01837 return "f(x) = x-minval if x >= minval; f(x) = 0 if x < minval.";
01838 }
01839
01840 static const string NAME;
01841
01842 protected:
01843 void process_pixel(float *x) const
01844 {
01845 *x = *x - value;
01846 if (*x < 0) {
01847 *x = 0;
01848 }
01849 }
01850 };
01851
01855 class BinarizeProcessor:public RealPixelProcessor
01856 {
01857 public:
01858 string get_name() const
01859 {
01860 return NAME;
01861 }
01862 static Processor *NEW()
01863 {
01864 return new BinarizeProcessor();
01865 }
01866 TypeDict get_param_types() const
01867 {
01868 TypeDict d;
01869 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" );
01870 return d;
01871 }
01872
01873 string get_desc() const
01874 {
01875 return "f(x) = 0 if x < value; f(x) = 1 if x >= value.";
01876 }
01877
01878 static const string NAME;
01879
01880 protected:
01881 void process_pixel(float *x) const
01882 {
01883 if (*x < value)
01884 {
01885 *x = 0;
01886 }
01887 else
01888 {
01889 *x = 1;
01890 }
01891 }
01892 };
01893
01905 class BinarizeFourierProcessor:public Processor
01906 {
01907 public:
01908 virtual string get_name() const
01909 {
01910 return NAME;
01911 }
01912 static Processor *NEW()
01913 {
01914 return new BinarizeFourierProcessor();
01915 }
01916
01923 virtual void process_inplace(EMData* image);
01924
01925 virtual TypeDict get_param_types() const
01926 {
01927 TypeDict d;
01928 d.put("value", EMObject::FLOAT, "The Fourier amplitude threshold cutoff" );
01929 return d;
01930 }
01931
01932 virtual string get_desc() const
01933 {
01934 return "f(k) = 0 + 0i if ||f(k)|| < value; f(k) = 1 + 0i if ||f(k)|| >= value.";
01935 }
01936
01937 static const string NAME;
01938 };
01939
01944 class CollapseProcessor:public RealPixelProcessor
01945 {
01946 public:
01947 string get_name() const
01948 {
01949 return NAME;
01950 }
01951 static Processor *NEW()
01952 {
01953 return new CollapseProcessor();
01954 }
01955
01956 void set_params(const Dict & new_params)
01957 {
01958 params = new_params;
01959 range = params["range"];
01960 value = params["value"];
01961 }
01962
01963 TypeDict get_param_types() const
01964 {
01965 TypeDict d;
01966 d.put("range", EMObject::FLOAT, "The range about 'value' which will be collapsed to 'value'");
01967 d.put("value", EMObject::FLOAT, "The pixel value where the focus of the collapse operation is");
01968 return d;
01969 }
01970
01971 string get_desc() const
01972 {
01973 return "f(x): if v-r<x<v+r -> v; if x>v+r -> x-r; if x<v-r -> x+r";
01974 }
01975
01976 static const string NAME;
01977
01978 protected:
01979 void process_pixel(float *x) const
01980 {
01981 if (*x>value+range) *x-=range;
01982 else if (*x<value-range) *x+=range;
01983 else *x=value;
01984 }
01985 float range;
01986 };
01987
01992 class LinearXformProcessor:public RealPixelProcessor
01993 {
01994 public:
01995 LinearXformProcessor():shift(0), scale(0)
01996 {
01997 }
01998
01999 string get_name() const
02000 {
02001 return NAME;
02002 }
02003 static Processor *NEW()
02004 {
02005 return new LinearXformProcessor();
02006 }
02007
02008 void set_params(const Dict & new_params)
02009 {
02010 params = new_params;
02011 shift = params.get("shift");
02012 scale = params.get("scale");
02013 }
02014
02015 TypeDict get_param_types() const
02016 {
02017 TypeDict d;
02018 d.put("shift", EMObject::FLOAT, "The amount to shift pixel values by before scaling");
02019 d.put("scale", EMObject::FLOAT, "The scaling factor to be applied to pixel values");
02020 return d;
02021 }
02022
02023 string get_desc() const
02024 {
02025 return "linear transform processor: f(x) = x * scale + shift. This is equivalent to a regular contrast stretching operation";
02026 }
02027
02028 static const string NAME;
02029
02030 protected:
02031 void process_pixel(float *x) const
02032 {
02033 *x = (*x) * scale + shift;
02034 }
02035
02036 private:
02037 float shift;
02038 float scale;
02039 };
02040
02045 class ExpProcessor:public RealPixelProcessor
02046 {
02047 public:
02048 ExpProcessor():low(0), high(0)
02049 {
02050 }
02051
02052 string get_name() const
02053 {
02054 return NAME;
02055 }
02056
02057 static Processor *NEW()
02058 {
02059 return new ExpProcessor();
02060 }
02061
02062 void set_params(const Dict & new_params)
02063 {
02064 params = new_params;
02065 low = params.get("low");
02066 high = params.get("high");
02067 }
02068
02069 TypeDict get_param_types() const
02070 {
02071 TypeDict d;
02072 d.put("low", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
02073 d.put("high", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
02074 return d;
02075 }
02076
02077 string get_desc() const
02078 {
02079 return "f(x) = exp( x / low - high)";
02080 }
02081
02082 static const string NAME;
02083
02084 protected:
02088 void process_pixel(float *x) const
02089 {
02090 float v = *x / low - high;
02091 if (v > 40) {
02092 v = 40;
02093 }
02094 *x = exp(v);
02095 }
02096
02097 private:
02098 float low;
02099 float high;
02100 };
02101
02105 class FiniteProcessor:public RealPixelProcessor
02106 {
02107 public:
02108 FiniteProcessor():to(0)
02109 {
02110 }
02111
02112 string get_name() const
02113 {
02114 return NAME;
02115 }
02116
02117 static Processor *NEW()
02118 {
02119 return new FiniteProcessor();
02120 }
02121
02122 void set_params(const Dict & new_params)
02123 {
02124 if (new_params.has_key("to") )
02125 to = params["to"];
02126 }
02127
02128 TypeDict get_param_types() const
02129 {
02130 TypeDict d;
02131 d.put("to", EMObject::FLOAT, "Pixels which are not finite will be set to this value");
02132 return d;
02133 }
02134
02135 string get_desc() const
02136 {
02137 return "f(x) = f(x) if f(x) is finite | to if f(x) is not finite";
02138 }
02139
02140 static const string NAME;
02141
02142 protected:
02146 void process_pixel(float *x) const;
02147 private:
02148 float to;
02149 };
02150
02155 class RangeThresholdProcessor:public RealPixelProcessor
02156 {
02157 public:
02158 RangeThresholdProcessor():low(0), high(0)
02159 {
02160 }
02161
02162 string get_name() const
02163 {
02164 return NAME;
02165 }
02166 static Processor *NEW()
02167 {
02168 return new RangeThresholdProcessor();
02169 }
02170
02171 void set_params(const Dict & new_params)
02172 {
02173 params = new_params;
02174 low = params.get("low");
02175 high = params.get("high");
02176 }
02177
02178 TypeDict get_param_types() const
02179 {
02180 TypeDict d;
02181 d.put("low", EMObject::FLOAT, "The lower limit of the range that will be set to 1");
02182 d.put("high", EMObject::FLOAT, "The upper limit of the range that will be set to 1");
02183 return d;
02184 }
02185
02186 string get_desc() const
02187 {
02188 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";
02189 }
02190
02191 static const string NAME;
02192
02193 protected:
02194 void process_pixel(float *x) const
02195 {
02196 if (*x >= low && *x <= high) {
02197 *x = 1;
02198 }
02199 else {
02200 *x = 0;
02201 }
02202 }
02203 private:
02204 float low;
02205 float high;
02206
02207 };
02208
02213 class SigmaProcessor:public RealPixelProcessor
02214 {
02215 public:
02216 string get_name() const
02217 {
02218 return NAME;
02219 }
02220 static Processor *NEW()
02221 {
02222 return new SigmaProcessor();
02223 }
02224
02225 void set_params(const Dict & new_params)
02226 {
02227 params = new_params;
02228 value1 = params.get("value1");
02229 value2 = params.get("value2");
02230 }
02231
02232 TypeDict get_param_types() const
02233 {
02234 TypeDict d;
02235 d.put("value1", EMObject::FLOAT, "A number reflecting total standard deviations in the right direction");
02236 d.put("value2", EMObject::FLOAT, "A number reflecting total standard deviations in the left direction");
02237 return d;
02238 }
02239
02240 string get_desc() const
02241 {
02242 return "f(x) = mean if x<(mean-v2*sigma) or x>(mean+v1*sigma); else f(x) = x;";
02243 }
02244
02245 static const string NAME;
02246
02247 protected:
02248 void process_pixel(float *x) const
02249 {
02250 if (*x < (mean - value2 * sigma) || *x > (mean + value1 * sigma))
02251 {
02252 *x = mean;
02253 }
02254 }
02255
02256 private:
02257 float value1;
02258 float value2;
02259 };
02260
02263 class LogProcessor:public RealPixelProcessor
02264 {
02265 public:
02266 string get_name() const
02267 {
02268 return NAME;
02269 }
02270 static Processor *NEW()
02271 {
02272 return new LogProcessor();
02273 }
02274
02275 string get_desc() const
02276 {
02277 return "f(x) = log10(x) if x > 0; else f(x) = 0;";
02278 }
02279
02280 static const string NAME;
02281
02282 protected:
02283 void process_pixel(float *x) const
02284 {
02285 if (*x > 0)
02286 {
02287 *x = log10(*x);
02288 }
02289 else
02290 {
02291 *x = 0;
02292 }
02293 }
02294 };
02295
02298 class CoordinateProcessor:public Processor
02299 {
02300 public:
02301 CoordinateProcessor():nx(0), ny(0), nz(0), mean(0), sigma(0), maxval(0), is_complex(false)
02302 {
02303 }
02304 void process_inplace(EMData * image);
02305
02306 static string get_group_desc()
02307 {
02308 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().";
02309 }
02310
02311 protected:
02312 virtual void process_pixel(float *pixel, int xi, int yi, int zi) const = 0;
02313 virtual void calc_locals(EMData *)
02314 {
02315 }
02316 virtual bool is_valid() const
02317 {
02318 return true;
02319 }
02320
02321 int nx;
02322 int ny;
02323 int nz;
02324 float mean;
02325 float sigma;
02326 float maxval;
02327
02328 bool is_complex;
02329 };
02330
02338 class CircularMaskProcessor:public CoordinateProcessor
02339 {
02340 public:
02341 CircularMaskProcessor():inner_radius(0), outer_radius(0), inner_radius_square(0),
02342 outer_radius_square(0), dx(0), dy(0), dz(0), xc(0), yc(0), zc(0)
02343 {
02344 }
02345
02346 void set_params(const Dict & new_params)
02347 {
02348 params = new_params;
02349
02350 if (params.has_key("inner_radius")) {
02351 inner_radius = params["inner_radius"];
02352 inner_radius_square = inner_radius * inner_radius;
02353 }
02354 else {
02355 inner_radius = -1;
02356 inner_radius_square = -1;
02357 }
02358
02359 if (params.has_key("outer_radius")) {
02360 outer_radius = params["outer_radius"];
02361 outer_radius_square = outer_radius * outer_radius;
02362 }
02363 else {
02364 outer_radius = INT_MAX;
02365 outer_radius_square = INT_MAX;
02366 }
02367
02368 if (params.has_key("xc")) xc = params["xc"];
02369 if (params.has_key("yc")) yc = params["yc"];
02370 if (params.has_key("zc")) zc = params["zc"];
02371 if (params.has_key("dx")) dx = params["dx"];
02372 if (params.has_key("dy")) dy = params["dy"];
02373 if (params.has_key("dz")) dz = params["dz"];
02374 }
02375
02376 string get_desc() const
02377 {
02378 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().";
02379 }
02380
02381 TypeDict get_param_types() const
02382 {
02383 TypeDict d;
02384
02385 d.put("inner_radius", EMObject::INT, "inner mask radius. optional, default=-1");
02386 d.put("outer_radius", EMObject::INT, "outer mask radius");
02387
02388 d.put("dx", EMObject::FLOAT,
02389 "Modify mask center by dx relative to the default center nx/2");
02390 d.put("dy", EMObject::FLOAT,
02391 "Modify mask center by dy relative to the default center ny/2");
02392 d.put("dz", EMObject::FLOAT,
02393 "Modify mask center by dz relative to the default center nz/2");
02394
02395 return d;
02396 }
02397 protected:
02398 void calc_locals(EMData * image);
02399
02400 bool is_valid() const
02401 {
02402 return (!is_complex);
02403 }
02404
02405 void process_pixel(float *pixel, int xi, int yi, int zi) const
02406 {
02407 float dist = (xi - xc) * (xi - xc) + (yi - yc) * (yi - yc) + (zi - zc) * (zi - zc);
02408 process_dist_pixel(pixel, dist);
02409 }
02410
02411 virtual void process_dist_pixel(float *pixel, float dist) const = 0;
02412
02413 int inner_radius;
02414 int outer_radius;
02415 int inner_radius_square;
02416 int outer_radius_square;
02417 float dx, dy, dz;
02418 float xc, yc, zc;
02419 };
02420
02424 class MaskSharpProcessor:public CircularMaskProcessor
02425 {
02426 public:
02427 MaskSharpProcessor():value(0)
02428 {
02429 }
02430
02431 string get_name() const
02432 {
02433 return NAME;
02434 }
02435 static Processor *NEW()
02436 {
02437 return new MaskSharpProcessor();
02438 }
02439
02440 void set_params(const Dict & new_params)
02441 {
02442 CircularMaskProcessor::set_params(new_params);
02443 value = params.set_default("value",0.0f);
02444 }
02445
02446 TypeDict get_param_types() const
02447 {
02448 TypeDict d = CircularMaskProcessor::get_param_types();
02449 d.put("value", EMObject::FLOAT, "step cutoff to this value. Default is 0.");
02450 return d;
02451 }
02452
02453 string get_desc() const
02454 {
02455 return "step cutoff to a user-given value in both inner and outer circles.";
02456 }
02457
02458 static const string NAME;
02459
02460 protected:
02461 void process_dist_pixel(float *pixel, float dist) const
02462 {
02463 if (dist >= outer_radius_square || dist < inner_radius_square)
02464 {
02465 *pixel = value;
02466 }
02467 }
02468
02469 float value;
02470 };
02471
02472
02476 class MaskEdgeMeanProcessor:public CircularMaskProcessor
02477 {
02478 public:
02479 string get_name() const
02480 {
02481 return NAME;
02482 }
02483 static Processor *NEW()
02484 {
02485 return new MaskEdgeMeanProcessor();
02486 }
02487
02488 void set_params(const Dict & new_params)
02489 {
02490 CircularMaskProcessor::set_params(new_params);
02491 ring_width = params["ring_width"];
02492 if (ring_width == 0) {
02493 ring_width = 1;
02494 }
02495 }
02496
02497 TypeDict get_param_types() const
02498 {
02499 TypeDict d = CircularMaskProcessor::get_param_types();
02500 d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02501 return d;
02502 }
02503
02504 string get_desc() const
02505 {
02506 return "A step cutoff to the the mean value in a ring centered on the outer radius";
02507 }
02508
02509 static const string NAME;
02510
02511 protected:
02512 void calc_locals(EMData * image);
02513
02514
02515 void process_dist_pixel(float *pixel, float dist) const
02516 {
02517 if (dist >= outer_radius_square || dist < inner_radius_square){
02518 *pixel = ring_avg;
02519 }
02520 }
02521
02522 private:
02523 int ring_width;
02524 float ring_avg;
02525 };
02526
02529 class MaskNoiseProcessor:public CircularMaskProcessor
02530 {
02531 public:
02532 string get_name() const
02533 {
02534 return NAME;
02535 }
02536 static Processor *NEW()
02537 {
02538 return new MaskNoiseProcessor();
02539 }
02540
02541 string get_desc() const
02542 {
02543 return "fills masked region";
02544 }
02545
02546 static const string NAME;
02547
02548 protected:
02549 void process_dist_pixel(float *pixel, float dist) const
02550 {
02551 if (dist >= outer_radius_square || dist < inner_radius_square)
02552 {
02553 *pixel = Util::get_gauss_rand(mean, sigma);
02554 }
02555 }
02556 };
02557
02560 class MaskGaussProcessor:public CircularMaskProcessor
02561 {
02562 public:
02563 string get_name() const
02564 {
02565 return NAME;
02566 }
02567 static Processor *NEW()
02568 {
02569 return new MaskGaussProcessor();
02570 }
02571
02572 void set_params(const Dict & new_params)
02573 {
02574 CircularMaskProcessor::set_params(new_params);
02575 exponent = params["exponent"];
02576 if (exponent <= 0.0) {
02577 exponent = 2.0;
02578 }
02579 }
02580
02581 TypeDict get_param_types() const
02582 {
02583 TypeDict d = CircularMaskProcessor::get_param_types();
02584 d.put("exponent", EMObject::FLOAT, "The exponent, f in e^-Bs^f. default 2.0, producing a Gaussian");
02585 return d;
02586 }
02587
02588 string get_desc() const
02589 {
02590 return "a gaussian falloff to zero, radius is the 1/e of the width. If inner_radius>0, then \
02591 outer radius specifies width of Gaussian starting at inner_radius rather than total radius.";
02592 }
02593
02594 static const string NAME;
02595
02596 protected:
02597 float exponent;
02598 void process_dist_pixel(float *pixel, float dist) const
02599 {
02600 if (inner_radius_square>0) {
02601 if (dist>inner_radius_square) {
02602 if (exponent==2.0f) (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,2.0f) / outer_radius_square);
02603 else (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,exponent) / pow((float)outer_radius_square,exponent/2.0f));
02604 }
02605 }
02606 else {
02607 if (exponent==2.0f) (*pixel) *= exp(-dist / outer_radius_square);
02608 else (*pixel) *= exp(-pow(dist,exponent/2.0f) / pow((float)outer_radius_square,exponent/2.0f));
02609 }
02610 }
02611 };
02612
02619 class MaskGaussNonuniformProcessor:public CoordinateProcessor
02620 {
02621 public:
02622 MaskGaussNonuniformProcessor():radius_x(0), radius_y(0), radius_z(0), gauss_width(0)
02623 {
02624 }
02625
02626 void set_params(const Dict & new_params)
02627 {
02628 params = new_params;
02629
02630 if (params.has_key("radius_x")) radius_x=params["radius_x"];
02631 else radius_x=5.0;
02632
02633 if (params.has_key("radius_y")) radius_y=params["radius_y"];
02634 else radius_y=5.0;
02635
02636 if (params.has_key("radius_z")) radius_z=params["radius_z"];
02637 else radius_z=5.0;
02638
02639 if (params.has_key("gauss_width")) gauss_width=params["gauss_width"];
02640 else gauss_width=0.05f;
02641 }
02642
02643 TypeDict get_param_types() const
02644 {
02645 TypeDict d;
02646
02647 d.put("radius_x", EMObject::INT, "x-axis radius");
02648 d.put("radius_y", EMObject::INT, "y-axis radius");
02649 d.put("radius_z", EMObject::INT, "z-axis radius");
02650 d.put("gauss_width", EMObject::FLOAT, "Gaussian falloff width, relative to each radius, default 0.05");
02651
02652 return d;
02653 }
02654
02655 string get_name() const
02656 {
02657 return NAME;
02658 }
02659 static Processor *NEW()
02660 {
02661 return new MaskGaussNonuniformProcessor();
02662 }
02663
02664 string get_desc() const
02665 {
02666 return "A Gaussian falloff to zero. Nonisotropic, specify inner radius for x,y,z and Gaussian falloff width. Falloff \
02667 width is also nonisotropic and relative to the radii, with 1 being equal to the radius on that axis.";
02668 }
02669
02670 static const string NAME;
02671
02672 protected:
02673 void process_pixel(float *pixel, int xi, int yi, int zi) const
02674 {
02675 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);
02676 if (dist>1.0) (*pixel)*=exp(-pow((sqrt(dist)-1.0f)/gauss_width,2.0f));
02677 }
02678
02679 float radius_x,radius_y,radius_z,gauss_width;
02680 };
02681
02686 class MaskGaussInvProcessor:public CircularMaskProcessor
02687 {
02688 public:
02689 TypeDict get_param_types() const
02690 {
02691 TypeDict d = CircularMaskProcessor::get_param_types();
02692 d.put("gauss_width", EMObject::FLOAT, "Used to calculate the constant factor - gauss_width / (ny*ny)" );
02693 d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02694 return d;
02695 }
02696
02697 string get_name() const
02698 {
02699 return NAME;
02700 }
02701
02702 static Processor *NEW()
02703 {
02704 return new MaskGaussInvProcessor();
02705 }
02706
02707 string get_desc() const
02708 {
02709 return "f(x) = f(x) / exp(-radius*radius * gauss_width / (ny*ny))";
02710 }
02711
02712 static const string NAME;
02713
02714 protected:
02715 void calc_locals(EMData *)
02716 {
02717 float gauss_width = params["gauss_width"];
02718 slice_value = gauss_width / (ny * ny);
02719 }
02720
02721 void process_dist_pixel(float *pixel, float dist) const
02722 {
02723 (*pixel) /= exp(-dist * slice_value);
02724 }
02725 private:
02726 float slice_value;
02727 };
02728
02729
02734 class LinearPyramidProcessor:public Processor
02735 {
02736 public:
02737 string get_name() const
02738 {
02739 return NAME;
02740 }
02741
02742 void process_inplace(EMData *image);
02743
02744 static Processor *NEW()
02745 {
02746 return new LinearPyramidProcessor();
02747 }
02748
02749 string get_desc() const
02750 {
02751 return "Multiplies image by a 'linear pyramid', 1-(|x-xsize/2|*|y-ysize/2|*4/(xsize*ysize))";
02752 }
02753
02754 static const string NAME;
02755 };
02756
02757
02760 class MakeRadiusSquaredProcessor:public CircularMaskProcessor
02761 {
02762 public:
02763 string get_name() const
02764 {
02765 return NAME;
02766 }
02767 static Processor *NEW()
02768 {
02769 return new MakeRadiusSquaredProcessor();
02770 }
02771
02772 string get_desc() const
02773 {
02774 return "overwrites input, f(x) = radius * radius";
02775 }
02776
02777 static const string NAME;
02778
02779 protected:
02780 void process_dist_pixel(float *pixel, float dist) const
02781 {
02782 *pixel = dist;
02783 }
02784 };
02785
02788 class MakeRadiusProcessor:public CircularMaskProcessor
02789 {
02790 public:
02791 string get_name() const
02792 {
02793 return NAME;
02794 }
02795 static Processor *NEW()
02796 {
02797 return new MakeRadiusProcessor();
02798 }
02799
02800 string get_desc() const
02801 {
02802 return "overwrites input, f(x) = radius;";
02803 }
02804
02805 static const string NAME;
02806
02807 protected:
02808 void process_dist_pixel(float *pixel, float dist) const
02809 {
02810 *pixel = sqrt(dist);
02811 }
02812 };
02813
02816 class ComplexPixelProcessor:public Processor
02817 {
02818 public:
02819 void process_inplace(EMData * image);
02820
02821 static string get_group_desc()
02822 {
02823 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.";
02824 }
02825
02826 protected:
02827 virtual void process_pixel(float *x) const = 0;
02828 };
02829
02832 class ComplexNormPixel:public ComplexPixelProcessor
02833 {
02834 public:
02835 string get_name() const
02836 {
02837 return NAME;
02838 }
02839 static Processor *NEW()
02840 {
02841 return new ComplexNormPixel();
02842 }
02843
02844 string get_desc() const
02845 {
02846 return "Each Fourier pixel will be normalized. ie - amp=1, phase=unmodified. Useful for performing phase-residual-like computations with dot products.";
02847 }
02848
02849 static const string NAME;
02850
02851 protected:
02852 void process_pixel(float *x) const
02853 {
02854 *x=1.0;
02855 }
02856 };
02857
02861 class AreaProcessor:public Processor
02862 {
02863 public:
02864 AreaProcessor():areasize(0), kernel(0), nx(0), ny(0), nz(0)
02865 {
02866 }
02867
02868 void process_inplace(EMData * image);
02869
02870 void set_params(const Dict & new_params)
02871 {
02872 params = new_params;
02873 areasize = params["areasize"];
02874 }
02875
02876 TypeDict get_param_types() const
02877 {
02878 TypeDict d;
02879 d.put("areasize", EMObject::INT, "The width of the area to process (not radius)");
02880 return d;
02881 }
02882
02883 string get_desc() const
02884 {
02885 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().";
02886 }
02887
02888 protected:
02889 virtual void process_pixel(float *pixel, float, float, float, float *area_matrix) const
02890 {
02891 for (int i = 0; i < matrix_size; i++)
02892 {
02893 *pixel += area_matrix[i] * kernel[i];
02894 }
02895 }
02896
02897 virtual void create_kernel() const = 0;
02898
02899 int areasize;
02900 int matrix_size;
02901 float *kernel;
02902 int nx;
02903 int ny;
02904 int nz;
02905 };
02906
02909 class LaplacianProcessor:public AreaProcessor
02910 {
02911 public:
02912 string get_name() const
02913 {
02914 return NAME;
02915 }
02916 static Processor *NEW()
02917 {
02918 return new LaplacianProcessor();
02919 }
02920
02921 string get_desc() const
02922 {
02923 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).";
02924 }
02925
02926 static const string NAME;
02927
02928 protected:
02929 void create_kernel() const;
02930
02931 };
02932
02935 class ZeroConstantProcessor:public AreaProcessor
02936 {
02937 public:
02938 string get_name() const
02939 {
02940 return NAME;
02941 }
02942 static Processor *NEW()
02943 {
02944 return new ZeroConstantProcessor();
02945 }
02946
02947 string get_desc() const
02948 {
02949 return "Contraction of data, if any nearest neighbor is 0, value -> 0, generally used iteratively";
02950 }
02951
02952 static const string NAME;
02953
02954 protected:
02955 void process_pixel(float *pixel, float, float, float, float *matrix) const
02956 {
02957 if (*pixel != 0)
02958 {
02959 if (*pixel == matrix[1] || *pixel == matrix[3] || *pixel == matrix[5] ||
02960 *pixel == matrix[7] || matrix[1] == 0 || matrix[3] == 0 ||
02961 matrix[5] == 0 || matrix[7] == 0) {
02962 *pixel = 0;
02963 }
02964 }
02965 }
02966
02967 void create_kernel() const
02968 {
02969 }
02970 };
02971
02980 class BoxStatProcessor:public Processor
02981 {
02982 public:
02983 void process_inplace(EMData * image);
02984
02985 static string get_group_desc()
02986 {
02987 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).";
02988 }
02989
02990 TypeDict get_param_types() const
02991 {
02992 TypeDict d;
02993 d.put("radius", EMObject::INT, "The radius of the search box, default is 1 which results in a 3x3 box (3 = 2xradius + 1)");
02994 return d;
02995 }
02996
02997 protected:
02998 virtual void process_pixel(float *pixel, const float *array, int n) const = 0;
02999 };
03000
03001
03004 class BoxMedianProcessor:public BoxStatProcessor
03005 {
03006 public:
03007 string get_name() const
03008 {
03009 return NAME;
03010 }
03011 static Processor *NEW()
03012 {
03013 return new BoxMedianProcessor();
03014 }
03015
03016 string get_desc() const
03017 {
03018 return "A processor for noise reduction. pixel = median of values surrounding pixel.";
03019 }
03020
03021 static const string NAME;
03022
03023 protected:
03024 void process_pixel(float *pixel, const float *array, int n) const
03025 {
03026 float *data = new float[n];
03027 memcpy(data, array, sizeof(float) * n);
03028
03029 for (int i = 0; i <= n / 2; i++)
03030 {
03031 for (int j = i + 1; j < n; j++)
03032 {
03033 if (data[i] < data[j]) {
03034 float t = data[i];
03035 data[i] = data[j];
03036 data[j] = t;
03037 }
03038 }
03039 }
03040
03041 if (n % 2 != 0)
03042 {
03043 *pixel = data[n / 2];
03044 }
03045 else {
03046 *pixel = (data[n / 2] + data[n / 2 - 1]) / 2;
03047 }
03048 if( data )
03049 {
03050 delete[]data;
03051 data = 0;
03052 }
03053 }
03054 };
03055
03058 class BoxSigmaProcessor:public BoxStatProcessor
03059 {
03060 public:
03061 string get_name() const
03062 {
03063 return NAME;
03064 }
03065 static Processor *NEW()
03066 {
03067 return new BoxSigmaProcessor();
03068 }
03069
03070 string get_desc() const
03071 {
03072 return "pixel = standard deviation of values surrounding pixel.";
03073 }
03074
03075 static const string NAME;
03076
03077 protected:
03078 void process_pixel(float *pixel, const float *data, int n) const
03079 {
03080 float sum = 0;
03081 float square_sum = 0;
03082 for (int i = 0; i < n; i++)
03083 {
03084 sum += data[i];
03085 square_sum += data[i] * data[i];
03086 }
03087
03088 float mean = sum / n;
03089 *pixel = sqrt(square_sum / n - mean * mean);
03090 }
03091 };
03092
03095 class BoxMaxProcessor:public BoxStatProcessor
03096 {
03097 public:
03098 string get_name() const
03099 {
03100 return NAME;
03101 }
03102 static Processor *NEW()
03103 {
03104 return new BoxMaxProcessor();
03105 }
03106
03107 string get_desc() const
03108 {
03109 return "peak processor: pixel = max of values surrounding pixel.";
03110 }
03111
03112 static const string NAME;
03113
03114 protected:
03115 void process_pixel(float *pixel, const float *data, int n) const
03116 {
03117 float maxval = -FLT_MAX;
03118 for (int i = 0; i < n; i++)
03119 {
03120 if (data[i] > maxval) {
03121 maxval = data[i];
03122 }
03123 }
03124 *pixel = maxval;
03125 }
03126 };
03127
03130 class MinusPeakProcessor:public BoxStatProcessor
03131 {
03132 public:
03133 string get_name() const
03134 {
03135 return NAME;
03136 }
03137 static Processor *NEW()
03138 {
03139 return new MinusPeakProcessor();
03140 }
03141
03142 string get_desc() const
03143 {
03144 return "peak processor: pixel = pixel - max of values surrounding pixel. This is a sort of positive peak-finding algorithm.";
03145 }
03146
03147 static const string NAME;
03148
03149 protected:
03150 void process_pixel(float *pixel, const float *data, int n) const
03151 {
03152 float maxval = -FLT_MAX;
03153 for (int i = 0; i < n; i++)
03154 {
03155 if (data[i] > maxval) {
03156 maxval = data[i];
03157 }
03158 }
03159 *pixel -= maxval;
03160 }
03161 };
03162
03166 class PeakOnlyProcessor:public BoxStatProcessor
03167 {
03168 public:
03169 string get_name() const
03170 {
03171 return NAME;
03172 }
03173 static Processor *NEW()
03174 {
03175 return new PeakOnlyProcessor();
03176 }
03177 void set_params(const Dict & new_params)
03178 {
03179 params = new_params;
03180 npeaks = params["npeaks"];
03181 if (npeaks == 0) {
03182 npeaks = 1;
03183 }
03184 }
03185
03186 TypeDict get_param_types() const
03187 {
03188 TypeDict d;
03189 d.put("npeaks", EMObject::INT, "the number of surrounding peaks allow to >= pixel values");
03190 return d;
03191 }
03192
03193 string get_desc() const
03194 {
03195 return "peak processor -> if npeaks or more surrounding values >= value, value->0";
03196 }
03197
03198 static const string NAME;
03199
03200 protected:
03201 void process_pixel(float *pixel, const float *data, int n) const
03202 {
03203 int r = 0;
03204
03205 for (int i = 0; i < n; i++)
03206 {
03207 if (data[i] >= *pixel) {
03208 r++;
03209 }
03210 }
03211
03212 if (r > npeaks)
03213 {
03214 *pixel = 0;
03215 }
03216 }
03217 private:
03218 int npeaks;
03219 };
03220
03225 class DiffBlockProcessor:public Processor
03226 {
03227 public:
03228 void process_inplace(EMData * image);
03229
03230 string get_name() const
03231 {
03232 return NAME;
03233 }
03234 static Processor *NEW()
03235 {
03236 return new DiffBlockProcessor();
03237 }
03238
03239 string get_desc() const
03240 {
03241 return "averages over cal_half_width, then sets the value in a local block";
03242 }
03243
03244 TypeDict get_param_types() const
03245 {
03246 TypeDict d;
03247 d.put("cal_half_width", EMObject::FLOAT, "cal_half_width is dx/dy for calculating an average");
03248 d.put("fill_half_width", EMObject::FLOAT, "fill_half_width is dx/dy for fill/step");
03249 return d;
03250 }
03251
03252 static const string NAME;
03253 };
03254
03259 class CutoffBlockProcessor:public Processor
03260 {
03261 public:
03262 void process_inplace(EMData * image);
03263
03264 string get_name() const
03265 {
03266 return NAME;
03267 }
03268 static Processor *NEW()
03269 {
03270 return new CutoffBlockProcessor();
03271 }
03272
03273 TypeDict get_param_types() const
03274 {
03275 TypeDict d;
03276 d.put("value1", EMObject::FLOAT, "val1 is dx/dy");
03277 d.put("value2", EMObject::FLOAT, "val2 is lowpass freq cutoff in pixels");
03278 return d;
03279 }
03280
03281 string get_desc() const
03282 {
03283 return "Block processor, val1 is dx/dy, val2 is lp freq cutoff in pixels. Mystery processor.";
03284 }
03285
03286 static const string NAME;
03287 };
03288
03294 class BooleanShrinkProcessor
03295 {
03296 protected:
03304 template<class LogicOp>
03305 EMData* process(const EMData *const image, Dict& params);
03306
03313 template<class LogicOp>
03314 void process_inplace(EMData * image, Dict& params);
03315
03316 };
03317
03326 class MaxShrinkProcessor:public BooleanShrinkProcessor, public Processor
03327 {
03328 public:
03335 virtual EMData* process(const EMData *const image)
03336 {
03337 return BooleanShrinkProcessor::process<GreaterThan>(image, params);
03338 }
03339
03340
03341 virtual void process_inplace(EMData * image)
03342 {
03343 BooleanShrinkProcessor::process_inplace<GreaterThan>(image, params);
03344 }
03345
03346 string get_desc() const
03347 {
03348 return "Shrink an image by a given amount (default 2), using the maximum value found in the pixel neighborhood.";
03349 }
03350
03351 string get_name() const
03352 {
03353 return NAME;
03354 }
03355 static Processor *NEW()
03356 {
03357 return new MaxShrinkProcessor();
03358 }
03359
03360 TypeDict get_param_types() const
03361 {
03362 TypeDict d;
03363 d.put("n", EMObject::INT, "The shrink factor");
03364 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03365 return d;
03366 }
03367
03368 static const string NAME;
03369
03370 private:
03371 struct GreaterThan
03372 {
03373 inline bool operator()(float left,float right) const { return left > right; }
03374 inline float get_start_val() { return -10000000; }
03375 };
03376 };
03377
03386 class MinShrinkProcessor:public BooleanShrinkProcessor, public Processor
03387 {
03388 public:
03395 virtual EMData* process(const EMData *const image)
03396 {
03397 return BooleanShrinkProcessor::process<LessThan>(image, params);
03398 }
03399
03400
03401 virtual void process_inplace(EMData * image)
03402 {
03403 BooleanShrinkProcessor::process_inplace<LessThan>(image, params);
03404 }
03405 string get_desc() const
03406 {
03407 return "Shrink an image by a given amount (default 2), using the minimum value found in the pixel neighborhood.";
03408 }
03409
03410 string get_name() const
03411 {
03412 return NAME;
03413 }
03414 static Processor *NEW()
03415 {
03416 return new MinShrinkProcessor();
03417 }
03418
03419 TypeDict get_param_types() const
03420 {
03421 TypeDict d;
03422 d.put("n", EMObject::INT, "The shrink factor");
03423 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03424 return d;
03425 }
03426
03427 static const string NAME;
03428
03429 private:
03430 struct LessThan
03431 {
03432 inline bool operator()(float left,float right) const { return left < right; }
03433 inline float get_start_val() { return 9999999999.0f; }
03434 };
03435 };
03436
03443 class MeanShrinkProcessor : public Processor
03444 {
03445 public:
03456 virtual EMData* process(const EMData *const image);
03457
03464 virtual void process_inplace(EMData * image);
03465
03466 string get_desc() const
03467 {
03468 return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
03469 }
03470
03471 virtual string get_name() const
03472 {
03473 return NAME;
03474 }
03475 static Processor *NEW()
03476 {
03477 return new MeanShrinkProcessor();
03478 }
03479
03480 virtual TypeDict get_param_types() const
03481 {
03482 TypeDict d;
03483 d.put("n", EMObject::FLOAT, "The shrink factor");
03484 return d;
03485 }
03486
03487 static const string NAME;
03488
03489 private:
03497 void accrue_mean(EMData* to, const EMData *const from, const int shrinkfactor);
03498
03505 void accrue_mean_one_p_five(EMData* to, const EMData * const from);
03506 };
03507
03508
03515 class MedianShrinkProcessor : public Processor
03516 {
03517 public:
03528 virtual EMData* process(const EMData *const image);
03529
03536 virtual void process_inplace(EMData * image);
03537
03538 string get_desc() const
03539 {
03540 return "Shrink an image by a given amount , using the median value found in the pixel neighborhood.";
03541 }
03542
03543 virtual string get_name() const
03544 {
03545 return NAME;
03546 }
03547 static Processor *NEW()
03548 {
03549 return new MedianShrinkProcessor();
03550 }
03551
03552 virtual TypeDict get_param_types() const
03553 {
03554 TypeDict d;
03555 d.put("n", EMObject::INT, "The shrink factor");
03556 return d;
03557 }
03558
03559 static const string NAME;
03560
03561 private:
03569 void accrue_median(EMData* to, const EMData* const from,const int shrink_factor);
03570 };
03571
03572
03581 class FFTResampleProcessor : public Processor
03582 {
03583 public:
03584 virtual EMData* process(const EMData *const image);
03585
03586 virtual void process_inplace(EMData * image);
03587
03588 string get_desc() const
03589 {
03590 return "Robust resampling of an image by clipping its Fourier transform.";
03591 }
03592
03593 string get_name() const
03594 {
03595 return NAME;
03596 }
03597 static Processor *NEW()
03598 {
03599 return new FFTResampleProcessor();
03600 }
03601
03602 TypeDict get_param_types() const
03603 {
03604 TypeDict d;
03605 d.put("n", EMObject::FLOAT, "The sample rate. Less than one enlarges the image, greater than one shrinks it.");
03606 return d;
03607 }
03608
03609 static const string NAME;
03610
03611 private:
03618 void fft_resample(EMData* to, const EMData *const from, const float& sample_rate);
03619
03620 };
03621
03624 class GradientRemoverProcessor:public Processor
03625 {
03626 public:
03627 void process_inplace(EMData * image);
03628
03629 string get_name() const
03630 {
03631 return NAME;
03632 }
03633 static Processor *NEW()
03634 {
03635 return new GradientRemoverProcessor();
03636 }
03637
03638 string get_desc() const
03639 {
03640 return "Gradient remover, does a rough plane fit to find linear gradients.";
03641 }
03642
03643 static const string NAME;
03644 };
03645
03654 class GradientPlaneRemoverProcessor:public Processor
03655 {
03656 public:
03657 void process_inplace(EMData * image);
03658
03659 string get_name() const
03660 {
03661 return NAME;
03662 }
03663 static Processor *NEW()
03664 {
03665 return new GradientPlaneRemoverProcessor();
03666 }
03667
03668 string get_desc() const
03669 {
03670 return "Remove gradient by least square plane fit";
03671 }
03672
03673 TypeDict get_param_types() const
03674 {
03675 TypeDict d;
03676 d.put("mask", EMObject::EMDATA, "mask object: nonzero pixel positions will be used to fit plane. default = 0");
03677 d.put("changeZero", EMObject::INT, "if zero pixels are modified when removing gradient. default = 0");
03678 d.put("planeParam", EMObject::FLOATARRAY, "fitted plane parameters output");
03679 return d;
03680 }
03681
03682 static const string NAME;
03683 };
03684
03685
03692 class FlattenBackgroundProcessor:public Processor
03693 {
03694 public:
03695 void process_inplace(EMData * image);
03696
03697 string get_name() const
03698 {
03699 return NAME;
03700 }
03701
03702 static Processor *NEW()
03703 {
03704 return new FlattenBackgroundProcessor();
03705 }
03706
03707 string get_desc() const
03708 {
03709 return "Flattens the background by subtracting the local mean";
03710 }
03711
03712 TypeDict get_param_types() const
03713 {
03714 TypeDict d;
03715 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");
03716 d.put("radius", EMObject::INT, "The radius of circle/sphere that defines the local neighborhood. Exclusive of the mask argument");
03717 return d;
03718 }
03719
03720 static const string NAME;
03721 };
03722
03723
03726 class RampProcessor:public Processor
03727 {
03728 public:
03729 void process_inplace(EMData * image);
03730
03731 string get_name() const
03732 {
03733 return NAME;
03734 }
03735 static Processor *NEW()
03736 {
03737 return new RampProcessor();
03738 }
03739
03740 string get_desc() const
03741 {
03742 return "Ramp processor -- Fits a least-squares plane "
03743 "to the picture, and subtracts the plane from "
03744 "the picture. A wedge-shaped overall density "
03745 "profile can thus be removed from the picture.";
03746 }
03747
03748 static const string NAME;
03749 };
03750
03753 class VerticalStripeProcessor:public Processor
03754 {
03755 public:
03756 void process_inplace(EMData * image);
03757
03758 string get_name() const
03759 {
03760 return NAME;
03761 }
03762
03763 static Processor *NEW()
03764 {
03765 return new VerticalStripeProcessor();
03766 }
03767
03768 string get_desc() const
03769 {
03770 return "Tries to fix images scanned on the zeiss for poor ccd normalization.";
03771 }
03772
03773 static const string NAME;
03774 };
03775
03778 class RealToFFTProcessor:public Processor
03779 {
03780 public:
03781 void process_inplace(EMData *image);
03782
03783 string get_name() const
03784 {
03785 return NAME;
03786 }
03787
03788 static Processor *NEW()
03789 {
03790 return new RealToFFTProcessor();
03791 }
03792
03793 string get_desc() const
03794 {
03795 return "This will replace the image with a full-circle 2D fft amplitude rendering. Note that this renders amplitude, when intensity is more common.";
03796 }
03797
03798 static const string NAME;
03799 };
03800
03801
03804 class SigmaZeroEdgeProcessor:public Processor
03805 {
03806 public:
03807 void process_inplace(EMData * image);
03808
03809 string get_name() const
03810 {
03811 return NAME;
03812 }
03813 static Processor *NEW()
03814 {
03815 return new SigmaZeroEdgeProcessor();
03816 }
03817
03818 string get_desc() const
03819 {
03820 return "Fill zeroes at edges with nearest horizontal/vertical value.";
03821 }
03822
03823 static const string NAME;
03824 };
03825
03831 class BeamstopProcessor:public Processor
03832 {
03833 public:
03834 void process_inplace(EMData * image);
03835
03836 string get_name() const
03837 {
03838 return NAME;
03839 }
03840
03841 static Processor *NEW()
03842 {
03843 return new BeamstopProcessor();
03844 }
03845
03846 string get_desc() const
03847 {
03848 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.";
03849 }
03850
03851 TypeDict get_param_types() const
03852 {
03853 TypeDict d;
03854 d.put("value1", EMObject::FLOAT, "sig multiplier");
03855 d.put("value2", EMObject::FLOAT, "x of center");
03856 d.put("value3", EMObject::FLOAT, "y of center");
03857 return d;
03858 }
03859
03860 static const string NAME;
03861 };
03862
03865 class MeanZeroEdgeProcessor:public Processor
03866 {
03867 public:
03868 void process_inplace(EMData * image);
03869
03870 string get_name() const
03871 {
03872 return NAME;
03873 }
03874
03875 static Processor *NEW()
03876 {
03877 return new MeanZeroEdgeProcessor();
03878 }
03879
03880 string get_desc() const
03881 {
03882 return "Fill zeroes at edges with nearest horizontal/vertical value damped towards Mean2.";
03883 }
03884
03885 static const string NAME;
03886 };
03887
03888
03891 class AverageXProcessor:public Processor
03892 {
03893 public:
03894 void process_inplace(EMData * image);
03895
03896 string get_name() const
03897 {
03898 return NAME;
03899 }
03900
03901 static Processor *NEW()
03902 {
03903 return new AverageXProcessor();
03904 }
03905
03906 string get_desc() const
03907 {
03908 return "Average along Y and replace with average";
03909 }
03910
03911 static const string NAME;
03912 };
03913
03917 class DecayEdgeProcessor:public Processor
03918 {
03919 public:
03920 void process_inplace(EMData * image);
03921 string get_name() const
03922 {
03923 return NAME;
03924 }
03925
03926 static Processor *NEW()
03927 {
03928 return new DecayEdgeProcessor();
03929 }
03930
03931 string get_desc() const
03932 {
03933 return "Decay edges of image to zero";
03934 }
03935
03936 TypeDict get_param_types() const
03937 {
03938 TypeDict d;
03939 d.put("width", EMObject::INT, "Width of the decay region around the edge of the image in pixels");
03940 return d;
03941 }
03942
03943 static const string NAME;
03944 };
03945
03952 class ZeroEdgeRowProcessor:public Processor
03953 {
03954 public:
03955 void process_inplace(EMData * image);
03956 string get_name() const
03957 {
03958 return NAME;
03959 }
03960
03961 static Processor *NEW()
03962 {
03963 return new ZeroEdgeRowProcessor();
03964 }
03965
03966 string get_desc() const
03967 {
03968 return "zero edges of image on top and bottom, and on left and right.";
03969 }
03970
03971 TypeDict get_param_types() const
03972 {
03973 TypeDict d;
03974 d.put("x0", EMObject::INT, "The number of columns to zero from left");
03975 d.put("x1", EMObject::INT, "The number of columns to zero from right");
03976 d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
03977 d.put("y1", EMObject::INT, "The number of rows to zero from the top");
03978 return d;
03979 }
03980
03981 static const string NAME;
03982 };
03983
03992 class ZeroEdgePlaneProcessor:public Processor
03993 {
03994 public:
03995 void process_inplace(EMData * image);
03996 string get_name() const
03997 {
03998 return NAME;
03999 }
04000
04001 static Processor *NEW()
04002 {
04003 return new ZeroEdgePlaneProcessor();
04004 }
04005
04006 string get_desc() const
04007 {
04008 return "zero edges of volume on all sides";
04009 }
04010
04011 TypeDict get_param_types() const
04012 {
04013 TypeDict d;
04014 d.put("x0", EMObject::INT, "The number of columns to zero from left");
04015 d.put("x1", EMObject::INT, "The number of columns to zero from right");
04016 d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
04017 d.put("y1", EMObject::INT, "The number of rows to zero from the top");
04018 d.put("z0", EMObject::INT, "The number of slices to zero from the bottom");
04019 d.put("z1", EMObject::INT, "The number of slices to zero from the top");
04020 return d;
04021 }
04022
04023 static const string NAME;
04024 };
04025
04026
04033 class BilateralProcessor:public Processor
04034 {
04035 public:
04036 void process_inplace(EMData * image);
04037 string get_name() const
04038 {
04039 return NAME;
04040 }
04041
04042 string get_desc() const
04043 {
04044 return "Bilateral processing on 2D or 3D volume data. Bilateral processing does non-linear weighted averaging processing within a certain window. ";
04045 }
04046
04047 static Processor *NEW()
04048 {
04049 return new BilateralProcessor();
04050 }
04051
04052 TypeDict get_param_types() const
04053 {
04054 TypeDict d;
04055 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.");
04056 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.");
04057 d.put("niter", EMObject::INT, "how many times to apply this processing on your data.");
04058 d.put("half_width", EMObject::INT, "processing window size = (2 * half_widthh + 1) ^ 3.");
04059 return d;
04060 }
04061
04062 static const string NAME;
04063 };
04064
04067 class NormalizeProcessor:public Processor
04068 {
04069 public:
04070 void process_inplace(EMData * image);
04071
04072 static string get_group_desc()
04073 {
04074 return "Base class for normalization processors. Each specific normalization processor needs to define how to calculate mean and how to calculate sigma.";
04075 }
04076
04077 protected:
04078 virtual float calc_sigma(EMData * image) const;
04079 virtual float calc_mean(EMData * image) const = 0;
04080 };
04081
04084 class NormalizeUnitProcessor:public NormalizeProcessor
04085 {
04086 public:
04087 string get_name() const
04088 {
04089 return NAME;
04090 }
04091
04092 static Processor *NEW()
04093 {
04094 return new NormalizeUnitProcessor();
04095 }
04096
04097 string get_desc() const
04098 {
04099 return "Normalize an image so its vector length is 1.0.";
04100 }
04101
04102 static const string NAME;
04103
04104 protected:
04105 float calc_sigma(EMData * image) const;
04106 float calc_mean(EMData * image) const;
04107 };
04108
04109 inline float NormalizeUnitProcessor::calc_mean(EMData *) const { return 0; }
04110
04113 class NormalizeUnitSumProcessor:public NormalizeProcessor
04114 {
04115 public:
04116 string get_name() const
04117 {
04118 return NAME;
04119 }
04120
04121 static Processor *NEW()
04122 {
04123 return new NormalizeUnitSumProcessor();
04124 }
04125
04126 string get_desc() const
04127 {
04128 return "Normalize an image so its elements sum to 1.0 (fails if mean=0)";
04129 }
04130
04131 static const string NAME;
04132
04133 protected:
04134 float calc_sigma(EMData * image) const;
04135 float calc_mean(EMData * image) const;
04136 };
04137
04138 inline float NormalizeUnitSumProcessor::calc_mean(EMData *) const { return 0; }
04139
04140
04143 class NormalizeStdProcessor:public NormalizeProcessor
04144 {
04145 public:
04146 string get_name() const
04147 {
04148 return NAME;
04149 }
04150
04151 static Processor *NEW()
04152 {
04153 return new NormalizeStdProcessor();
04154 }
04155
04156 string get_desc() const
04157 {
04158 return "do a standard normalization on an image.";
04159 }
04160
04161 static const string NAME;
04162
04163 protected:
04164 float calc_mean(EMData * image) const;
04165 };
04166
04171 class NormalizeMaskProcessor:public NormalizeProcessor
04172 {
04173 public:
04174 string get_name() const
04175 {
04176 return NAME;
04177 }
04178
04179 string get_desc() const
04180 {
04181 return "Uses a 1/0 mask defining a region to use for the zero-normalization.if no_sigma is 1, standard deviation not modified.";
04182 }
04183
04184 static Processor *NEW()
04185 {
04186 return new NormalizeMaskProcessor();
04187 }
04188
04189 TypeDict get_param_types() const
04190 {
04191 TypeDict d;
04192 d.put("mask", EMObject::EMDATA, "the 1/0 mask defining a region to use for the zero-normalization");
04193 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");
04194 return d;
04195 }
04196
04197 static const string NAME;
04198
04199 protected:
04200 float calc_sigma(EMData * image) const;
04201 float calc_mean(EMData * image) const;
04202 };
04203
04209 class NormalizeRampNormVar: public Processor
04210 {
04211 public:
04212 string get_name() const
04213 {
04214 return NAME;
04215 }
04216
04217 static Processor *NEW()
04218 {
04219 return new NormalizeRampNormVar();
04220 }
04221
04222 string get_desc() const
04223 {
04224 return "First call filter.ramp on the image, then make the mean 0 and norm 1";
04225 }
04226
04227 void process_inplace(EMData * image);
04228
04229 static const string NAME;
04230 };
04231
04240 class NormalizeByMassProcessor: public Processor
04241 {
04242 public:
04243 string get_name() const
04244 {
04245 return NAME;
04246 }
04247
04248 static Processor *NEW()
04249 {
04250 return new NormalizeByMassProcessor();
04251 }
04252
04253 string get_desc() const
04254 {
04255 return "Normalize the mass of the image assuming a density of 1.35 g/ml (0.81 Da/A^3) (3D only)";
04256 }
04257
04258 TypeDict get_param_types() const
04259 {
04260 TypeDict d;
04261 d.put("apix", EMObject::FLOAT,"Angstrom per pixel of the image. If not set will use the apix_x attribute of the image");
04262 d.put("mass", EMObject::FLOAT,"The approximate mass of protein/structure in kilodaltons");
04263 d.put("thr", EMObject::FLOAT,"The isosurface threshold which encapsulates the structure");
04264 return d;
04265 }
04266
04267 void process_inplace(EMData * image);
04268
04269 static const string NAME;
04270 };
04271
04272
04275 class NormalizeEdgeMeanProcessor:public NormalizeProcessor
04276 {
04277 public:
04278 string get_name() const
04279 {
04280 return NAME;
04281 }
04282
04283 static Processor *NEW()
04284 {
04285 return new NormalizeEdgeMeanProcessor();
04286 }
04287
04288 string get_desc() const
04289 {
04290 return "normalizes an image, mean value equals to edge mean.";
04291 }
04292
04293 static const string NAME;
04294
04295 protected:
04296 float calc_mean(EMData * image) const;
04297 };
04298
04301 class NormalizeCircleMeanProcessor:public NormalizeProcessor
04302 {
04303 public:
04304 string get_name() const
04305 {
04306 return NAME;
04307 }
04308
04309 static Processor *NEW()
04310 {
04311 return new NormalizeCircleMeanProcessor();
04312 }
04313
04314 string get_desc() const
04315 {
04316 return "normalizes an image, mean value equals to mean of 2 pixel circular border.";
04317 }
04318
04319 static const string NAME;
04320
04321 protected:
04322 float calc_mean(EMData * image) const;
04323 };
04324
04327 class NormalizeLREdgeMeanProcessor:public NormalizeProcessor
04328 {
04329 public:
04330 string get_name() const
04331 {
04332 return NAME;
04333 }
04334
04335 static Processor *NEW()
04336 {
04337 return new NormalizeLREdgeMeanProcessor();
04338 }
04339
04340 string get_desc() const
04341 {
04342 return "normalizes an image, uses 2 pixels on left and right edge";
04343 }
04344
04345 static const string NAME;
04346
04347 protected:
04348 float calc_mean(EMData * image) const;
04349 };
04350
04353 class NormalizeMaxMinProcessor:public NormalizeProcessor
04354 {
04355 public:
04356 string get_name() const
04357 {
04358 return NAME;
04359 }
04360
04361 static Processor *NEW()
04362 {
04363 return new NormalizeMaxMinProcessor();
04364 }
04365
04366 string get_desc() const
04367 {
04368 return "normalizes an image. mean -> (maxval-minval)/2; std dev = (maxval+minval)/2;";
04369 }
04370
04371 static const string NAME;
04372
04373 protected:
04374 float calc_sigma(EMData * image) const;
04375 float calc_mean(EMData * image) const;
04376 };
04377
04380 class NormalizeRowProcessor:public Processor
04381 {
04382 public:
04383 string get_name() const
04384 {
04385 return NAME;
04386 }
04387
04388 static Processor *NEW()
04389 {
04390 return new NormalizeRowProcessor();
04391 }
04392
04393 string get_desc() const
04394 {
04395 return "normalizes each row in the image individually";
04396 }
04397
04398 static const string NAME;
04399
04400 void process_inplace(EMData * image);
04401 };
04402
04408 class NormalizeToLeastSquareProcessor:public Processor
04409 {
04410 public:
04411 void process_inplace(EMData * image);
04412
04413 string get_name() const
04414 {
04415 return NAME;
04416 }
04417
04418 static Processor *NEW()
04419 {
04420 return new NormalizeToLeastSquareProcessor();
04421 }
04422
04423 TypeDict get_param_types() const
04424 {
04425 TypeDict d;
04426 d.put("to", EMObject::EMDATA, "reference image normalize to");
04427 d.put("ignore_zero", EMObject::BOOL, "If set, ignores any pixels which are exactly zero in either image. Defaut = True.");
04428 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)");
04429 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)");
04430 return d;
04431 }
04432
04433 string get_desc() const
04434 {
04435 return "use least square method to normalize";
04436 }
04437
04438 static const string NAME;
04439 };
04440
04443 class RotationalAverageProcessor:public Processor
04444 {
04445 public:
04446 void process_inplace(EMData * image);
04447
04448 string get_name() const
04449 {
04450 return NAME;
04451 }
04452
04453 static Processor *NEW()
04454 {
04455 return new RotationalAverageProcessor();
04456 }
04457
04458 string get_desc() const
04459 {
04460 return "Makes image circularly/spherically symmetric.";
04461 }
04462
04463 static const string NAME;
04464 };
04465
04468 class RotationalSubstractProcessor:public Processor
04469 {
04470 public:
04471 virtual void process_inplace(EMData * image);
04472
04473 virtual string get_name() const
04474 {
04475 return NAME;
04476 }
04477
04478 static Processor *NEW()
04479 {
04480 return new RotationalSubstractProcessor();
04481 }
04482
04483 virtual string get_desc() const
04484 {
04485 return "subtracts circularly/spherically symmetric part of an image.";
04486 }
04487
04488 static const string NAME;
04489 };
04490
04496 class TransposeProcessor:public Processor
04497 {
04498 public:
04499
04504 virtual void process_inplace(EMData * image);
04505
04510 virtual EMData* process(const EMData * const image);
04511
04512 virtual string get_name() const
04513 {
04514 return NAME;
04515 }
04516
04517 static Processor *NEW()
04518 {
04519 return new TransposeProcessor();
04520 }
04521
04522 virtual TypeDict get_param_types() const
04523 {
04524 TypeDict d;
04525 return d;
04526 }
04527
04528 virtual string get_desc() const
04529 {
04530 return "Get the transpose of an image. Works for 2D only";
04531 }
04532
04533 static const string NAME;
04534 };
04535
04536
04540 class FlipProcessor:public Processor
04541 {
04542 public:
04543 virtual void process_inplace(EMData * image);
04544
04545 virtual string get_name() const
04546 {
04547 return NAME;
04548 }
04549
04550 static Processor *NEW()
04551 {
04552 return new FlipProcessor();
04553 }
04554
04555 virtual TypeDict get_param_types() const
04556 {
04557 TypeDict d;
04558 d.put("axis", EMObject::STRING, "'x', 'y', or 'z' axis. 'x' means horizonal flip; 'y' means vertical flip;");
04559 return d;
04560 }
04561
04562 virtual string get_desc() const
04563 {
04564 return "flip an image around an axis.";
04565 }
04566
04567 static const string NAME;
04568 };
04569
04570
04571
04572
04573
04574
04575
04576
04577
04578
04579
04580
04581
04582
04583
04584
04585
04586
04587
04588
04589
04590
04591
04592
04593
04594
04595
04596
04597
04598
04603 class AddNoiseProcessor:public Processor
04604 {
04605 public:
04606 virtual void process_inplace(EMData * image);
04607
04608 virtual string get_name() const
04609 {
04610 return NAME;
04611 }
04612
04613 static Processor *NEW()
04614 {
04615 return new AddNoiseProcessor();
04616 }
04617
04618 virtual TypeDict get_param_types() const
04619 {
04620 TypeDict d;
04621 d.put("noise", EMObject::FLOAT, "noise factor used to generate Gaussian distribution random noise");
04622 d.put("seed", EMObject::INT, "seed for random number generator");
04623 return d;
04624 }
04625
04626 virtual string get_desc() const
04627 {
04628 return "add noise to an image, image multiply by noise then add a random value";
04629 }
04630
04631 static const string NAME;
04632
04633 protected:
04634 virtual float get_sigma(EMData *)
04635 {
04636 return 1.0;
04637 }
04638 };
04639
04642 class AddSigmaNoiseProcessor:public AddNoiseProcessor
04643 {
04644 public:
04645 virtual string get_name() const
04646 {
04647 return NAME;
04648 }
04649
04650 static Processor *NEW()
04651 {
04652 return new AddSigmaNoiseProcessor();
04653 }
04654
04655 virtual string get_desc() const
04656 {
04657 return "add sigma noise.";
04658 }
04659
04660 static const string NAME;
04661
04662 protected:
04663 float get_sigma(EMData * image);
04664 };
04665
04674 class AddRandomNoiseProcessor:public Processor
04675 {
04676 public:
04677 virtual void process_inplace(EMData * image);
04678
04679 virtual string get_name() const
04680 {
04681 return NAME;
04682 }
04683
04684 static Processor *NEW()
04685 {
04686 return new AddRandomNoiseProcessor();
04687 }
04688
04689 virtual TypeDict get_param_types() const
04690 {
04691 TypeDict d;
04692 d.put("n", EMObject::INT);
04693 d.put("x0", EMObject::FLOAT);
04694 d.put("dx", EMObject::FLOAT);
04695 d.put("y", EMObject::FLOATARRAY);
04696 d.put("interpolation", EMObject::INT);
04697 d.put("seed", EMObject::INT, "seed for random number generator");
04698 return d;
04699 }
04700
04701 virtual string get_desc() const
04702 {
04703 return "add spectral noise to a complex image.";
04704 }
04705
04706 static const string NAME;
04707 };
04708
04714 class FourierToCornerProcessor:public Processor
04715 {
04716 public:
04722 virtual void process_inplace(EMData * image);
04723
04724 virtual string get_name() const
04725 {
04726 return NAME;
04727 }
04728
04729 static Processor *NEW()
04730 {
04731 return new FourierToCornerProcessor();
04732 }
04733
04734 virtual string get_desc() const
04735 {
04736 return "Undoes the xform.fourierorigin.tocenter processor";
04737 }
04738
04739 static const string NAME;
04740 };
04741
04742
04754 class FourierToCenterProcessor:public Processor
04755 {
04756 public:
04762 virtual void process_inplace(EMData * image);
04763
04764 virtual string get_name() const
04765 {
04766 return NAME;
04767 }
04768
04769 static Processor *NEW()
04770 {
04771 return new FourierToCenterProcessor();
04772 }
04773
04774 virtual string get_desc() const
04775 {
04776 return "Translates the origin in Fourier space from the corner to the center in y and z - works in 2D and 3D";
04777 }
04778
04779 static const string NAME;
04780 };
04781
04791 class Phase180Processor:public Processor
04792 {
04793 protected:
04806 void swap_corners_180(EMData * image);
04807
04819 void swap_central_slices_180(EMData * image);
04820
04827 void fourier_phaseshift180(EMData * image);
04828
04829 };
04830
04840 class PhaseToCenterProcessor:public Phase180Processor
04841 {
04842 public:
04843 virtual void process_inplace(EMData * image);
04844
04845 virtual string get_name() const
04846 {
04847 return NAME;
04848 }
04849
04850 static Processor *NEW()
04851 {
04852 return new PhaseToCenterProcessor();
04853 }
04854
04855 virtual string get_desc() const
04856 {
04857 return "Undoes the effect of the xform.phaseorigin.tocorner processor";
04858 }
04859
04860 static const string NAME;
04861 };
04862
04870 class PhaseToCornerProcessor:public Phase180Processor
04871 {
04872 public:
04873 virtual void process_inplace(EMData * image);
04874
04875 virtual string get_name() const
04876 {
04877 return NAME;
04878 }
04879
04880 static Processor *NEW()
04881 {
04882 return new PhaseToCornerProcessor();
04883 }
04884
04885 virtual string get_desc() const
04886 {
04887 return "Translates a centered image to the corner in a forward fashion";
04888 }
04889
04890 static const string NAME;
04891 };
04892
04897 class AutoMask2DProcessor:public Processor
04898 {
04899 public:
04900 virtual void process_inplace(EMData * image);
04901
04902 virtual string get_name() const
04903 {
04904 return NAME;
04905 }
04906
04907 static Processor *NEW()
04908 {
04909 return new AutoMask2DProcessor();
04910 }
04911
04912 virtual TypeDict get_param_types() const
04913 {
04914 TypeDict d;
04915 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
04916 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
04917 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
04918 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
04919 d.put("nshells", EMObject::INT, "The number of dilation operations");
04920 d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
04921 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
04922 d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
04923 return d;
04924 }
04925
04926 virtual string get_desc() const
04927 {
04928 return "2D version of mask.auto3d";
04929 }
04930
04931 static const string NAME;
04932 };
04933
04934
04941 class AutoMaskAsymUnit:public Processor
04942 {
04943 public:
04944 virtual void process_inplace(EMData * image);
04945
04946 virtual string get_name() const
04947 {
04948 return NAME;
04949 }
04950
04951 static Processor *NEW()
04952 {
04953 return new AutoMaskAsymUnit();
04954 }
04955
04956 virtual TypeDict get_param_types() const
04957 {
04958 TypeDict d;
04959 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.");
04960 d.put("sym", EMObject::STRING, "The symmetry, for example, d7");
04961 return d;
04962 }
04963
04964 virtual string get_desc() const
04965 {
04966 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.";
04967 }
04968
04969 static const string NAME;
04970 };
04971
04976 class AutoMask3DProcessor:public Processor
04977 {
04978 public:
04979 virtual void process_inplace(EMData * image);
04980
04981 virtual string get_name() const
04982 {
04983 return NAME;
04984 }
04985
04986 static Processor *NEW()
04987 {
04988 return new AutoMask3DProcessor();
04989 }
04990
04991 virtual TypeDict get_param_types() const
04992 {
04993 TypeDict d;
04994 d.put("threshold1", EMObject::FLOAT);
04995 d.put("threshold2", EMObject::FLOAT);
04996 return d;
04997 }
04998
04999 virtual string get_desc() const
05000 {
05001 return "Tries to mask out only interesting density";
05002 }
05003
05004 static void search_nearby(float *dat, float *dat2, int nx, int ny, int nz, float thr);
05005 static void fill_nearby(float *dat2, int nx, int ny, int nz);
05006
05007 static const string NAME;
05008 };
05009
05017 class AutoMask3D2Processor:public Processor
05018 {
05019 public:
05020 virtual void process_inplace(EMData * image);
05021
05022 virtual string get_name() const
05023 {
05024 return NAME;
05025 }
05026
05027 static Processor *NEW()
05028 {
05029 return new AutoMask3D2Processor();
05030 }
05031
05032 virtual string get_desc() const
05033 {
05034 return "Tries to mask out only interesting density using something akin to a flood file approach.";
05035 }
05036
05037 virtual TypeDict get_param_types() const
05038 {
05039 TypeDict d;
05040 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
05041 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
05042 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
05043 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
05044 d.put("nshells", EMObject::INT, "The number of dilation operations");
05045 d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
05046 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
05047 d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
05048 return d;
05049 }
05050
05051 static const string NAME;
05052 };
05053
05057 class AddMaskShellProcessor:public Processor
05058 {
05059 public:
05060 virtual void process_inplace(EMData * image);
05061
05062 virtual string get_name() const
05063 {
05064 return NAME;
05065 }
05066
05067 virtual string get_desc() const
05068 {
05069 return "Add additional shells/rings to an existing 1/0 mask image";
05070 }
05071
05072 static Processor *NEW()
05073 {
05074 return new AddMaskShellProcessor();
05075 }
05076
05077 virtual TypeDict get_param_types() const
05078 {
05079 TypeDict d;
05080 d.put("nshells", EMObject::INT, "number of shells to add");
05081 return d;
05082 }
05083
05084 static const string NAME;
05085 };
05086
05091 class PhaseToMassCenterProcessor:public Processor
05092 {
05093 public:
05094 virtual void process_inplace(EMData * image);
05095
05096 virtual string get_name() const
05097 {
05098 return NAME;
05099 }
05100
05101 static Processor *NEW()
05102 {
05103 return new PhaseToMassCenterProcessor();
05104 }
05105
05106 virtual string get_desc() const
05107 {
05108 return "centers the image the center of mass, which is calculated using Fourier phases, ignores old dx, dy.";
05109 }
05110
05111 virtual TypeDict get_param_types() const
05112 {
05113 TypeDict d;
05114 d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05115 return d;
05116 }
05117
05118 static const string NAME;
05119 };
05120
05125 class ToMassCenterProcessor: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 ToMassCenterProcessor();
05138 }
05139
05140 virtual string get_desc() const
05141 {
05142 return "ToMassCenterProcessor centers image at center of mass. Note: includes only values > mean+0.75*sigma";
05143 }
05144
05145 virtual TypeDict get_param_types() const
05146 {
05147 TypeDict d;
05148 d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05149
05150 return d;
05151 }
05152
05153 static const string NAME;
05154 };
05155
05159 class ACFCenterProcessor: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 ACFCenterProcessor();
05172 }
05173
05174 virtual string get_desc() const
05175 {
05176 return "Center image using self-convolution.";
05177 }
05178
05179 virtual TypeDict get_param_types() const
05180 {
05181 TypeDict d;
05182 return d;
05183 }
05184
05185 static const string NAME;
05186 };
05187
05192 class SNRProcessor:public Processor
05193 {
05194 public:
05195 virtual void process_inplace(EMData * image);
05196
05197 virtual string get_name() const
05198 {
05199 return NAME;
05200 }
05201
05202 static Processor *NEW()
05203 {
05204 return new SNRProcessor();
05205 }
05206
05207 virtual string get_desc() const
05208 {
05209 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.";
05210 }
05211
05212 virtual TypeDict get_param_types() const
05213 {
05214 TypeDict d;
05215 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");
05216 d.put("snrfile", EMObject::STRING, "structure factor file name");
05217 return d;
05218 }
05219
05220 static const string NAME;
05221 };
05222
05226 class FileFourierProcessor:public Processor
05227 {
05228 public:
05229 virtual void process_inplace(EMData * image);
05230
05231 virtual string get_name() const
05232 {
05233 return NAME;
05234 }
05235
05236 virtual string get_desc() const
05237 {
05238 return "A fourier processor specified in a 2 column text file.";
05239 }
05240
05241 static Processor *NEW()
05242 {
05243 return new FileFourierProcessor();
05244 }
05245
05246 virtual TypeDict get_param_types() const
05247 {
05248 TypeDict d;
05249 d.put("filename", EMObject::STRING, "file name for a 2 column text file which specified a radial function data array.");
05250 return d;
05251 }
05252
05253 static const string NAME;
05254 };
05255
05266 class SymSearchProcessor:public Processor
05267 {
05268 public:
05269 virtual void process_inplace(EMData * image);
05270
05271 virtual string get_name() const
05272 {
05273 return NAME;
05274 }
05275
05276 virtual string get_desc() const
05277 {
05278 return "Identifiy the best symmetry in the given symmetry list for each pixel and then apply the best symmetry to each pixel.";
05279 }
05280
05281 static Processor *NEW()
05282 {
05283 return new SymSearchProcessor();
05284 }
05285
05286 virtual TypeDict get_param_types() const
05287 {
05288 TypeDict d;
05289 d.put("sym", EMObject::STRINGARRAY, "the list of symmetries to search");
05290 d.put("thresh", EMObject::FLOAT, "the minimal level of symmetry to be accepted (0-1)");
05291 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");
05292 d.put("symlabel_map", EMObject::EMDATA, "the optional return map when output_symlabel=1");
05293 return d;
05294 }
05295
05296 static const string NAME;
05297 };
05298
05304 class LocalNormProcessor:public Processor
05305 {
05306 public:
05307 void process_inplace(EMData * image);
05308
05309 virtual string get_name() const
05310 {
05311 return NAME;
05312 }
05313
05314 static Processor *NEW()
05315 {
05316 return new LocalNormProcessor();
05317 }
05318
05319 virtual string get_desc() const
05320 {
05321 return "This processor attempts to perform a 'local normalization' so low density and high density features will be on a more even playing field in an isosurface display. threshold is an isosurface threshold at which all desired features are visible, radius is a normalization size similar to an lp= value.";
05322 }
05323
05324 virtual TypeDict get_param_types() const
05325 {
05326 TypeDict d;
05327 d.put("threshold", EMObject::FLOAT, "an isosurface threshold at which all desired features are visible");
05328 d.put("radius", EMObject::FLOAT, "a normalization size similar to an lp= value");
05329 d.put("apix", EMObject::FLOAT, "Angstrom per pixel ratio");
05330 return d;
05331 }
05332
05333 static const string NAME;
05334 };
05335
05340 class IndexMaskFileProcessor:public Processor
05341 {
05342 public:
05343 virtual void process_inplace(EMData * image);
05344
05345 virtual string get_name() const
05346 {
05347 return NAME;
05348 }
05349
05350 static Processor *NEW()
05351 {
05352 return new IndexMaskFileProcessor();
05353 }
05354
05355 virtual TypeDict get_param_types() const
05356 {
05357 TypeDict d;
05358 d.put("filename", EMObject::STRING, "mask image file name");
05359 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");
05360 return d;
05361 }
05362
05363 virtual string get_desc() const
05364 {
05365 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.";
05366 }
05367
05368 static const string NAME;
05369 };
05370
05374 class CoordinateMaskFileProcessor:public Processor
05375 {
05376 public:
05377 virtual void process_inplace(EMData * image);
05378
05379 virtual string get_name() const
05380 {
05381 return NAME;
05382 }
05383
05384 static Processor *NEW()
05385 {
05386 return new CoordinateMaskFileProcessor();
05387 }
05388
05389 virtual string get_desc() const
05390 {
05391 return "Multiplies the image by the specified file using pixel coordinates instead of pixel indices. The images can be different size.";
05392 }
05393
05394 virtual TypeDict get_param_types() const
05395 {
05396 TypeDict d;
05397 d.put("filename", EMObject::STRING, "mask image file name");
05398 return d;
05399 }
05400
05401 static const string NAME;
05402 };
05403
05414 class PaintProcessor:public Processor
05415 {
05416 public:
05417 PaintProcessor():x(0), y(0), z(0),r1(0), v1(0.0), r2(0), v2(0.0)
05418 {
05419 }
05420
05421 virtual string get_name() const
05422 {
05423 return NAME;
05424 }
05425
05426 static Processor *NEW()
05427 {
05428 return new PaintProcessor();
05429 }
05430
05431 virtual string get_desc() const
05432 {
05433 return "Paints a circle with a decaying edge into the image. r<r1 -> v1, r1<r<r2 -> (v1,v2), r>r2 unchanged";
05434 }
05435
05436 virtual TypeDict get_param_types() const
05437 {
05438 TypeDict d;
05439 d.put("x", EMObject::INT, "x coordinate for Center of circle");
05440 d.put("y", EMObject::INT, "y coordinate for Center of circle");
05441 d.put("z", EMObject::INT, "z coordinate for Center of circle");
05442 d.put("r1", EMObject::INT, "Inner radius");
05443 d.put("v1", EMObject::FLOAT, "Inner value");
05444 d.put("r2", EMObject::INT, "Outter radius");
05445 d.put("v2", EMObject::FLOAT, "Outer Value");
05446 return d;
05447 }
05448
05449 virtual void set_params(const Dict & new_params)
05450 {
05451 params = new_params;
05452
05453 if (params.has_key("x")) x = params["x"];
05454 if (params.has_key("y")) y = params["y"];
05455 if (params.has_key("z")) z = params["z"];
05456 if (params.has_key("r1")) r1 = params["r1"];
05457 if (params.has_key("r2")) r2 = params["r2"];
05458 if (params.has_key("v1")) v1 = params["v1"];
05459 if (params.has_key("v2")) v2 = params["v2"];
05460 }
05461
05462 static const string NAME;
05463
05464 protected:
05465 virtual void process_inplace(EMData *image);
05466
05467 int x,y,z,r1;
05468 float v1;
05469 int r2;
05470 float v2;
05471
05472 };
05473
05474
05479 class DirectionalSumProcessor : public Processor
05480 {
05481 public:
05482 virtual string get_name() const
05483 {
05484 return NAME;
05485 }
05486
05487 static Processor *NEW()
05488 {
05489 return new DirectionalSumProcessor();
05490 }
05491
05495 virtual EMData* process(const EMData* const image);
05496
05500 virtual void process_inplace(EMData* image ) {
05501 throw InvalidCallException("The directional sum processor does not work inplace");
05502 }
05503
05504 virtual TypeDict get_param_types() const
05505 {
05506 TypeDict d;
05507 d.put("direction", EMObject::STRING,"The direction of the sum, either x,y or z");
05508 return d;
05509 }
05510
05511 string get_desc() const
05512 {
05513 return "Calculates the projection of the image along one of the axial directions, either x, y or z";
05514 }
05515
05516 static const string NAME;
05517 };
05518
05526 class WatershedProcessor:public Processor
05527 {
05528 public:
05529 virtual void process_inplace(EMData * image);
05530
05531 virtual string get_name() const
05532 {
05533 return NAME;
05534 }
05535
05536 static Processor *NEW()
05537 {
05538 return new WatershedProcessor();
05539 }
05540
05541 virtual string get_desc() const
05542 {
05543 return "Does a watershed";
05544 }
05545
05546 virtual TypeDict get_param_types() const
05547 {
05548 TypeDict d;
05549 d.put("xpoints", EMObject::FLOATARRAY,"x coordinates");
05550 d.put("ypoints", EMObject::FLOATARRAY,"y coordinates");
05551 d.put("zpoints", EMObject::FLOATARRAY,"z coordinates");
05552 d.put("minval", EMObject::FLOAT,"min value");
05553 return d;
05554 }
05555
05556 static const string NAME;
05557
05558 private:
05559 vector<Vec3i > watershed(EMData* mask, EMData* image, const float& threshold, const Vec3i& cordinate, const int mask_value);
05560 vector<Vec3i > find_region(EMData* mask,const vector<Vec3i >& coords, const int mask_value, vector<Vec3i >& region);
05561
05562 };
05563
05573 template<class Type>
05574 class BinaryOperateProcessor : public Processor{
05575 public:
05580 virtual void process_inplace(EMData * image) {
05581 if ( ! params.has_key("with") ) throw InvalidParameterException("You must supply the \"with\" parameter");
05582 EMData* with = params["with"];
05583
05584 if ( with->get_xsize() != image->get_xsize() || with->get_ysize() != image->get_ysize() || with->get_zsize() != image->get_zsize() )
05585 throw ImageDimensionException("The images you are operating on do not have the same dimensions");
05586
05587 float* image_data = image->get_data();
05588 float* with_data = with->get_data();
05589
05590 std::transform(image_data,image_data+image->get_size(),with_data,image_data,Type::binary_operate);
05591 image->update();
05592 }
05593
05594 virtual string get_name() const
05595 {
05596 return op.get_name();
05597 }
05598
05599 virtual string get_desc() const
05600 {
05601 return op.get_desc();
05602 }
05603
05604 static Processor *NEW()
05605 {
05606 return new BinaryOperateProcessor<Type>();
05607 }
05608
05609 virtual TypeDict get_param_types() const
05610 {
05611 TypeDict d;
05612 d.put("with", EMObject::EMDATA,"The second image");
05613 return d;
05614 }
05615
05616 static const string NAME;
05617 private:
05618 Type op;
05619 };
05620
05621 class MaxPixelOperator {
05622 public:
05623 string get_name() const
05624 {
05625 return NAME;
05626 }
05627
05628 string get_desc() const
05629 {
05630 return "Compares pixels in two images, returning an image with the maximum pixel value in each pixel location";
05631 }
05632
05633 static float binary_operate(const float& left, const float& right) {
05634 if (left > right) return left;
05635 return right;
05636 }
05637
05638 static const string NAME;
05639 };
05640
05641 class MinPixelOperator {
05642 public:
05643 string get_name() const
05644 {
05645 return NAME;
05646 }
05647
05648 string get_desc() const
05649 {
05650 return "Compares pixels in two images, returning an image with the minimum pixel value in each pixel location";
05651 }
05652
05653 static float binary_operate(const float& left, const float& right) {
05654 if (left < right) return left;
05655 return right;
05656 }
05657
05658 static const string NAME;
05659 };
05660
05664 class MatchSFProcessor:public FourierAnlProcessor
05665 {
05666 public:
05667
05668 virtual string get_name() const
05669 {
05670 return NAME;
05671 }
05672
05673 virtual string get_desc() const
05674 {
05675 return "Filters the image so its 1-D power spectrum matches a second image";
05676 }
05677
05678 static Processor *NEW()
05679 {
05680 return new MatchSFProcessor();
05681 }
05682
05683 virtual TypeDict get_param_types() const
05684 {
05685 TypeDict d;
05686 d.put("to", EMObject::EMDATA, "The image to match with. Make sure apix values are correct.");
05687 return d;
05688 }
05689
05690 static const string NAME;
05691
05692 protected:
05693 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05694 };
05695
05696
05701 class SetSFProcessor:public FourierAnlProcessor
05702 {
05703 public:
05704
05705 virtual string get_name() const
05706 {
05707 return NAME;
05708 }
05709
05710 virtual string get_desc() const
05711 {
05712 return "Filters the image so its 1-D power spectrum matches a supplied X-Y curve";
05713 }
05714
05715 static Processor *NEW()
05716 {
05717 return new SetSFProcessor();
05718 }
05719
05720 virtual TypeDict get_param_types() const
05721 {
05722 TypeDict d;
05723 d.put("strucfac", EMObject::XYDATA, "An XYData object contaning the curve to be imposed as a function of S");
05724 d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
05725 return d;
05726 }
05727
05728 static const string NAME;
05729
05730 protected:
05731 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05732 };
05733
05737 class SmartMaskProcessor:public Processor
05738 {
05739 public:
05740 virtual void process_inplace(EMData * image);
05741
05742 virtual string get_name() const
05743 {
05744 return NAME;
05745 }
05746
05747 static Processor *NEW()
05748 {
05749 return new SmartMaskProcessor();
05750 }
05751
05752 virtual string get_desc() const
05753 {
05754 return "Smart mask processor.";
05755 }
05756
05757 virtual TypeDict get_param_types() const
05758 {
05759 TypeDict d;
05760 d.put("mask", EMObject::FLOAT, "mask value");
05761 return d;
05762 }
05763
05764 static const string NAME;
05765 };
05766
05771 class IterBinMaskProcessor:public Processor
05772 {
05773 public:
05774 virtual void process_inplace(EMData * image);
05775
05776 virtual string get_name() const
05777 {
05778 return NAME;
05779 }
05780
05781 virtual string get_desc() const
05782 {
05783 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.";
05784 }
05785
05786 static Processor *NEW()
05787 {
05788 return new IterBinMaskProcessor();
05789 }
05790
05791 virtual TypeDict get_param_types() const
05792 {
05793 TypeDict d;
05794 d.put("val1", EMObject::FLOAT, "number of pixels to expand");
05795 d.put("val2", EMObject::FLOAT, "number of Gaussian pixels to expand, following the first expansion");
05796 return d;
05797 }
05798
05799 static const string NAME;
05800 };
05801
05804 class TestImageProcessor : public Processor
05805 {
05806 public:
05807 static string get_group_desc()
05808 {
05809 return "Base class for a group of 'processors' used to create test image.";
05810 }
05811
05812 protected:
05813 void preprocess(EMData * image);
05814 int nx, ny, nz;
05815 };
05816
05825 class TestImagePureGaussian : public TestImageProcessor
05826 {
05827 public:
05828 virtual void process_inplace(EMData * image);
05829
05830 virtual string get_name() const
05831 {
05832 return NAME;
05833 }
05834
05835 virtual string get_desc() const
05836 {
05837 return "Replace a source image as a strict Gaussian ";
05838 }
05839
05840 static Processor * NEW()
05841 {
05842 return new TestImagePureGaussian();
05843 }
05844
05845 virtual TypeDict get_param_types() const
05846 {
05847 TypeDict d;
05848 d.put("x_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on x direction");
05849 d.put("y_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on y direction");
05850 d.put("z_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on z direction");
05851 d.put("x_center", EMObject::FLOAT, "center for this Gaussian blob on x direction" );
05852 d.put("y_center", EMObject::FLOAT, "center for this Gaussian blob on y direction" );
05853 d.put("z_center", EMObject::FLOAT, "center for this Gaussian blob on z direction" );
05854 return d;
05855 }
05856
05857 static const string NAME;
05858 };
05859
05863 class TestImageFourierNoiseGaussian : public TestImageProcessor
05864 {
05865 public:
05866 virtual void process_inplace(EMData * image);
05867
05868 virtual string get_name() const
05869 {
05870 return NAME;
05871 }
05872
05873 virtual string get_desc() const
05874 {
05875 return "Replace a source image with pink Fourier noise, based on a Gaussian. Random phase.";
05876 }
05877
05878 static Processor * NEW()
05879 {
05880 return new TestImageFourierNoiseGaussian();
05881 }
05882
05883 virtual TypeDict get_param_types() const
05884 {
05885 TypeDict d;
05886 d.put("sigma", EMObject::FLOAT, "sigma value");
05887 return d;
05888 }
05889
05890 static const string NAME;
05891 };
05892
05897 class TestImageFourierNoiseProfile : public TestImageProcessor
05898 {
05899 public:
05900 virtual void process_inplace(EMData * image);
05901
05902 virtual string get_name() const
05903 {
05904 return NAME;
05905 }
05906
05907 virtual string get_desc() const
05908 {
05909 return "Replace a source image with Fourier noise using amplitude information that is stored in a profile.";
05910 }
05911
05912 static Processor * NEW()
05913 {
05914 return new TestImageFourierNoiseProfile();
05915 }
05916
05917 virtual TypeDict get_param_types() const
05918 {
05919 TypeDict d;
05920 d.put("profile", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
05921 return d;
05922 }
05923
05924 static const string NAME;
05925 };
05926
05927
05932 class CTFSNRWeightProcessor : public TestImageProcessor
05933 {
05934 public:
05935 virtual void process_inplace(EMData * image);
05936
05937 virtual string get_name() const
05938 {
05939 return NAME;
05940 }
05941
05942 virtual string get_desc() const
05943 {
05944 return "Weight the amplitudes of an image based on radial noise and snr curves ";
05945 }
05946
05947 static Processor * NEW()
05948 {
05949 return new CTFSNRWeightProcessor();
05950 }
05951
05952 virtual TypeDict get_param_types() const
05953 {
05954 TypeDict d;
05955 d.put("noise", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
05956 d.put("snr", EMObject::FLOATARRAY, "Squared amplitude divided by squared noise amplitude. As in, what is the EMAN2CTF.snr attribute");
05957 d.put("boost", EMObject::FLOAT, "Multiplicative signal boost");
05958 return d;
05959 }
05960
05961 static const string NAME;
05962 };
05963
05964
05965
05970 class TestImageLineWave : public TestImageProcessor
05971 {
05972 public:
05973 virtual void process_inplace(EMData * image);
05974
05975 virtual string get_name() const
05976 {
05977 return NAME;
05978 }
05979
05980 virtual string get_desc() const
05981 {
05982 return "Insert an oscillating sine wave into the pixel data";
05983 }
05984
05985 static Processor * NEW()
05986 {
05987 return new TestImageLineWave();
05988 }
05989
05990 virtual TypeDict get_param_types() const
05991 {
05992 TypeDict d;
05993 d.put("period", EMObject::FLOAT, "The period of the oscillating sine wave. Default 10.");
05994 return d;
05995 }
05996
05997 static const string NAME;
05998 };
05999
06000
06008 class TestTomoImage : public TestImageProcessor
06009 {
06010 public:
06014 virtual void process_inplace(EMData * image);
06015
06016 virtual string get_name() const
06017 {
06018 return NAME;
06019 }
06020
06021 virtual string get_desc() const
06022 {
06023 return "Make an image consisting various objects, useful for tomographic testing";
06024 }
06025
06026 static Processor * NEW()
06027 {
06028 return new TestTomoImage();
06029 }
06030
06031 static const string NAME;
06032
06033 private:
06034 void insert_solid_ellipse( EMData* image, const Region& region, const float& value, const Transform& t3d = Transform() );
06035 void insert_hollow_ellipse( EMData* image, const Region& region, const float& value, const int& radius, const Transform& t3d = Transform() );
06036 void insert_rectangle( EMData* image, const Region& region, const float& value, const Transform& t3d = Transform() );
06037 };
06038
06046 class TestImageGradient : public TestImageProcessor
06047 {
06048 public:
06049 virtual void process_inplace(EMData * image);
06050
06051 virtual string get_name() const
06052 {
06053 return NAME;
06054 }
06055
06056 virtual string get_desc() const
06057 {
06058 return "Make a gradient image of the form y=mx+b, where x is any of the image axes.";
06059 }
06060
06061 static Processor * NEW()
06062 {
06063 return new TestImageGradient();
06064 }
06065
06066 virtual TypeDict get_param_types() const
06067 {
06068 TypeDict d;
06069 d.put("axis", EMObject::STRING, "The axis the will be used to determine pixel values. Must be x,y or z");
06070 d.put("m", EMObject::FLOAT, "m in the equation m*axis+b. Default is 1.0");
06071 d.put("b", EMObject::FLOAT, "b in the equation m*axis+b. Default is 0.0");
06072 return d;
06073 }
06074
06075 static const string NAME;
06076 };
06077
06085 class TestImageAxes : public TestImageProcessor
06086 {
06087 public:
06092 virtual void process_inplace(EMData * image);
06093
06094 virtual string get_name() const
06095 {
06096 return NAME;
06097 }
06098
06099 virtual string get_desc() const
06100 {
06101 return "Make an image consisting of a single cross";
06102 }
06103
06104 static Processor * NEW()
06105 {
06106 return new TestImageAxes();
06107 }
06108
06109 virtual TypeDict get_param_types() const
06110 {
06111 TypeDict d;
06112 d.put("int", EMObject::FLOAT, "radius of the lines emanating from the origin");
06113 d.put("fill", EMObject::FLOAT, "value to make non-zero pixels");
06114 return d;
06115 }
06116
06117 static const string NAME;
06118 };
06119
06125 class TestImageGaussian : public TestImageProcessor
06126 {
06127 public:
06128 virtual void process_inplace(EMData * image);
06129
06130 virtual string get_name() const
06131 {
06132 return NAME;
06133 }
06134
06135 virtual string get_desc() const
06136 {
06137 return "Replace a source image as a Gaussian Blob";
06138 }
06139
06140 static Processor * NEW()
06141 {
06142 return new TestImageGaussian();
06143 }
06144
06145 virtual TypeDict get_param_types() const
06146 {
06147 TypeDict d;
06148 d.put("sigma", EMObject::FLOAT, "sigma value for this Gaussian blob");
06149 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06150 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06151 return d;
06152 }
06153
06154 static const string NAME;
06155 };
06156
06159 class TestImageScurve : public TestImageProcessor
06160 {
06161 public:
06162 virtual void process_inplace(EMData * image);
06163
06164 virtual string get_name() const
06165 {
06166 return NAME;
06167 }
06168
06169 virtual string get_desc() const
06170 {
06171 return "Replace a source image with a lumpy S-curve used for alignment testing";
06172 }
06173
06174 static Processor * NEW()
06175 {
06176 return new TestImageScurve();
06177 }
06178
06179 virtual TypeDict get_param_types() const
06180 {
06181 TypeDict d;
06182 return d;
06183 }
06184
06185 static const string NAME;
06186 };
06187
06195 class TestImageSphericalWave : public TestImageProcessor
06196 {
06197 public:
06198 virtual void process_inplace(EMData * image);
06199
06200 virtual string get_name() const
06201 {
06202 return NAME;
06203 }
06204
06205 virtual string get_desc() const
06206 {
06207 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)";
06208 }
06209
06210 static Processor * NEW()
06211 {
06212 return new TestImageSphericalWave();
06213 }
06214
06215 virtual TypeDict get_param_types() const
06216 {
06217 TypeDict d;
06218 d.put("wavelength", EMObject::FLOAT, "cos(2*pi*r/wavelength+phase)");
06219 d.put("phase", EMObject::FLOAT, "in radians");
06220 d.put("x", EMObject::FLOAT, "center of the spherical wave");
06221 d.put("y", EMObject::FLOAT, "center of the spherical wave");
06222 d.put("z", EMObject::FLOAT, "center of the spherical wave");
06223 return d;
06224 }
06225
06226 static const string NAME;
06227 };
06228
06229
06238 class TestImageSinewave : public TestImageProcessor
06239 {
06240 public:
06241 virtual void process_inplace(EMData * image);
06242
06243 virtual string get_name() const
06244 {
06245 return NAME;
06246 }
06247
06248 virtual string get_desc() const
06249 {
06250 return "Replace a source image as a sine wave in specified wave length";
06251 }
06252
06253 static Processor * NEW()
06254 {
06255 return new TestImageSinewave();
06256 }
06257
06258 virtual TypeDict get_param_types() const
06259 {
06260 TypeDict d;
06261 d.put("wavelength", EMObject::FLOAT, "wavelength in equation sin(x*2*PI/wavelength - phase*180/PI)");
06262 d.put("axis", EMObject::STRING, "(optional) specify a major axis for asymmetric features, default x axis");
06263 d.put("phase", EMObject::FLOAT, "(optional) the phase in equation sin(x*2*PI/wavelength - phase*180/PI)");
06264 d.put("az", EMObject::FLOAT, "(optional) angle in degree. for 2D image, this is the rotated angle of the image, \
06265 in 3D image, it's az for euler angle. default is zero");
06266 d.put("alt", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, alt for euler angle, default is zero");
06267 d.put("phi", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, phi for euler angle, default is zero");
06268 return d;
06269 }
06270
06271 static const string NAME;
06272 };
06273
06280 class TestImageSinewaveCircular : public TestImageProcessor
06281 {
06282 public:
06283 virtual void process_inplace(EMData * image);
06284
06285 virtual string get_name() const
06286 {
06287 return NAME;
06288 }
06289
06290 virtual string get_desc() const
06291 {
06292 return "Replace a source image as a circular sine wave in specified wave length";
06293 }
06294
06295 static Processor * NEW()
06296 {
06297 return new TestImageSinewaveCircular();
06298 }
06299
06300 virtual TypeDict get_param_types() const
06301 {
06302 TypeDict d;
06303 d.put("wavelength", EMObject::FLOAT, "(required)this value is the d in function |sin(x/d)|, unit: pixel");
06304 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06305 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06306 d.put("phase", EMObject::FLOAT, "(optional)phase for sine wave, default is 0");
06307 return d;
06308 }
06309
06310 static const string NAME;
06311 };
06312
06319 class TestImageSquarecube : public TestImageProcessor
06320 {
06321 public:
06322 virtual void process_inplace(EMData * image);
06323
06324 virtual string get_name() const
06325 {
06326 return NAME;
06327 }
06328
06329 virtual string get_desc() const
06330 {
06331 return "Replace a source image as a square or cube depends on 2D or 3D of the source image";
06332 }
06333
06334 static Processor * NEW()
06335 {
06336 return new TestImageSquarecube();
06337 }
06338
06339 virtual TypeDict get_param_types() const
06340 {
06341 TypeDict d;
06342 d.put("edge_length", EMObject::FLOAT, "edge length of the square or cube, unit: pixel");
06343 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06344 d.put("odd_edge", EMObject::FLOAT, "edge length for the asymmetric axis");
06345 d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank");
06346 return d;
06347 }
06348
06349 static const string NAME;
06350 };
06351
06359 class TestImageEllipse : public TestImageProcessor
06360 {
06361 public:
06362 virtual void process_inplace(EMData * image);
06363
06364 virtual string get_name() const
06365 {
06366 return NAME;
06367 }
06368
06369 virtual string get_desc() const
06370 {
06371 return "Insert an ellipse into the image.";
06372 }
06373
06374 static Processor * NEW()
06375 {
06376 return new TestImageEllipse();
06377 }
06378
06379 virtual TypeDict get_param_types() const
06380 {
06381 TypeDict d;
06382 d.put("a", EMObject::FLOAT, "equatorial radii along x axes");
06383 d.put("b", EMObject::FLOAT, "equatorial radii along y axes");
06384 d.put("c", EMObject::FLOAT, "polar radius");
06385 d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06386 d.put("fill", EMObject::FLOAT, "value you want to fill in ellipse, default to 1.0");
06387 return d;
06388 }
06389
06390 static const string NAME;
06391 };
06392
06404 class TestImageHollowEllipse : public TestImageProcessor
06405 {
06406 public:
06407 virtual void process_inplace(EMData * image);
06408
06409 virtual string get_name() const
06410 {
06411 return NAME;
06412 }
06413
06414 virtual string get_desc() const
06415 {
06416 return "Insert a hollow ellipse into the image.";
06417 }
06418
06419 static Processor * NEW()
06420 {
06421 return new TestImageHollowEllipse();
06422 }
06423
06424 virtual TypeDict get_param_types() const
06425 {
06426 TypeDict d;
06427 d.put("xwidth", EMObject::FLOAT, "inner equatorial radii along x axes");
06428 d.put("ywidth", EMObject::FLOAT, "inner equatorial radii along y axes");
06429 d.put("zwidth", EMObject::FLOAT, "inner polar radius");
06430 d.put("a", EMObject::FLOAT, "outter equatorial radii along x axes");
06431 d.put("b", EMObject::FLOAT, "outter equatorial radii along y axes");
06432 d.put("c", EMObject::FLOAT, "outter polar radius");
06433 d.put("width",EMObject::FLOAT, "width - specify the width or specify each width explicitly - xwidth, ywidth, zwidth");
06434 d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06435 d.put("fill", EMObject::FLOAT, "value you want to fill in hollow ellipse, default to 1.0");
06436 return d;
06437 }
06438
06439 static const string NAME;
06440 };
06441
06448 class TestImageCirclesphere : public TestImageProcessor
06449 {
06450 public:
06451 virtual void process_inplace(EMData * image);
06452
06453 virtual string get_name() const
06454 {
06455 return NAME;
06456 }
06457
06458 virtual string get_desc() const
06459 {
06460 return "Replace a source image as a circle or sphere depends on 2D or 3D of the source image";
06461 }
06462
06463 static Processor * NEW()
06464 {
06465 return new TestImageCirclesphere();
06466 }
06467
06468 virtual TypeDict get_param_types() const
06469 {
06470 TypeDict d;
06471 d.put("radius", EMObject::FLOAT, "radius of circle or sphere, unit: pixel");
06472 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06473 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06474 d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank.");
06475 return d;
06476 }
06477
06478 static const string NAME;
06479 };
06480
06485 class TestImageNoiseUniformRand : public TestImageProcessor
06486 {
06487 public:
06488 virtual void process_inplace(EMData * image);
06489
06490 virtual string get_name() const
06491 {
06492 return NAME;
06493 }
06494
06495 virtual string get_desc() const
06496 {
06497 return "Replace a source image as a uniform random noise, random number generated from gsl_rng_mt19937, the pixel value is [0, 1)";
06498 }
06499
06500 static Processor * NEW()
06501 {
06502 return new TestImageNoiseUniformRand();
06503 }
06504
06505 virtual TypeDict get_param_types() const
06506 {
06507 TypeDict d;
06508 d.put("seed", EMObject::INT, "seed for random number generator");
06509 return d;
06510 }
06511
06512 static const string NAME;
06513 };
06514
06525 class TestImageNoiseGauss : public TestImageProcessor
06526 {
06527 public:
06528 virtual void process_inplace(EMData * image);
06529
06530 virtual string get_name() const
06531 {
06532 return NAME;
06533 }
06534
06535 virtual string get_desc() const
06536 {
06537 return "Replace a source image as a random noise, the random value is gaussian distributed";
06538 }
06539
06540 static Processor * NEW()
06541 {
06542 return new TestImageNoiseGauss();
06543 }
06544
06545 virtual TypeDict get_param_types() const
06546 {
06547 TypeDict d;
06548 d.put("sigma", EMObject::FLOAT, "sigma value of gausian distributed noise, default is 0.5");
06549 d.put("mean", EMObject::FLOAT, "mean value of gausian distributed noise, default is zero.");
06550 d.put("seed", EMObject::INT, "the seed for random number generator, default is not to reseed.");
06551
06552 return d;
06553 }
06554
06555 static const string NAME;
06556 };
06557
06562 class TestImageCylinder : public TestImageProcessor
06563 {
06564 public:
06565 virtual void process_inplace(EMData * image);
06566
06567 virtual string get_name() const
06568 {
06569 return NAME;
06570 }
06571
06572 virtual string get_desc() const
06573 {
06574 return "Replace a source image as a cylinder";
06575 }
06576
06577 static Processor * NEW()
06578 {
06579 return new TestImageCylinder();
06580 }
06581
06582 virtual TypeDict get_param_types() const
06583 {
06584 TypeDict d;
06585 d.put("radius", EMObject::FLOAT, "radius for the cylinder");
06586 d.put("height", EMObject::FLOAT, "height for the cylinder, by default it's the nz");
06587
06588 return d;
06589 }
06590
06591 static const string NAME;
06592 };
06593
06599 class CCDNormProcessor:public Processor
06600 {
06601 public:
06602 virtual void process_inplace(EMData * image);
06603
06604 virtual string get_name() const
06605 {
06606 return NAME;
06607 }
06608
06609 static Processor *NEW()
06610 {
06611 return new CCDNormProcessor();
06612 }
06613
06614 virtual string get_desc() const
06615 {
06616 return "normalize the 4 quadrants of a CCD image";
06617 }
06618
06619 virtual TypeDict get_param_types() const
06620 {
06621 TypeDict d;
06622 d.put("width", EMObject::INT, "number of pixels on either side of the seam to sample");
06623 return d;
06624 }
06625
06626 static const string NAME;
06627 };
06628
06636 class WaveletProcessor:public Processor
06637 {
06638 public:
06639 virtual void process_inplace(EMData * image);
06640
06641 virtual string get_name() const
06642 {
06643 return NAME;
06644 }
06645
06646 static Processor *NEW()
06647 {
06648 return new WaveletProcessor();
06649 }
06650
06651 virtual TypeDict get_param_types() const
06652 {
06653 TypeDict d;
06654 d.put("type", EMObject::STRING, "'daub', 'harr' or 'bspl'");
06655 d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06656 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)");
06657 return d;
06658 }
06659
06660 virtual string get_desc() const
06661 {
06662 return "Computes the DWT (discrete wavelet transform) of an image in one of 3 possible bases";
06663 }
06664
06665 static const string NAME;
06666 };
06667
06683 class TomoTiltEdgeMaskProcessor : public Processor
06684 {
06685 public:
06686 virtual void process_inplace(EMData* image);
06687
06688 virtual string get_name() const
06689 {
06690 return NAME;
06691 }
06692
06693 static Processor *NEW()
06694 {
06695 return new TomoTiltEdgeMaskProcessor();
06696 }
06697
06698 virtual TypeDict get_param_types() const
06699 {
06700 TypeDict d;
06701 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");
06702 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.");
06703 d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06704 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.");
06705 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)");
06706 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");
06707 return d;
06708 }
06709
06710 virtual string get_desc() const
06711 {
06712 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.";
06713 }
06714
06715 static const string NAME;
06716
06717 private:
06718 class GaussianFunctoid
06719 {
06720 public:
06721 GaussianFunctoid(const float sigma, const float mean = 0.0) : m_mean(mean), m_sigma_squared(sigma*sigma) {}
06722 ~GaussianFunctoid() {}
06723
06724 float operator()(const float distance )
06725 {
06726 return exp( -(distance-m_mean)*(distance-m_mean)/ (m_sigma_squared ));
06727 }
06728 private:
06729 float m_mean, m_sigma_squared;
06730 };
06731
06732 };
06733
06748 class TomoTiltAngleWeightProcessor : public Processor
06749 {
06750 public:
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 TomoTiltAngleWeightProcessor();
06761 }
06762
06763 virtual TypeDict get_param_types() const
06764 {
06765 TypeDict d;
06766 d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06767 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");
06768 return d;
06769 }
06770
06771 virtual string get_desc() const
06772 {
06773 return "Weights the image by 1/cos(angle)";
06774 }
06775
06776 static const string NAME;
06777
06778 };
06779
06783 class FFTProcessor : public Processor
06784 {
06785 public:
06786 void process_inplace(EMData * image);
06787
06788 string get_name() const
06789 {
06790 return NAME;
06791 }
06792
06793 static Processor *NEW()
06794 {
06795 return new FFTProcessor();
06796 }
06797
06798 TypeDict get_param_types() const
06799 {
06800 TypeDict d;
06801 d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06802 return d;
06803 }
06804
06805 string get_desc() const
06806 {
06807 return "Computes the DFFT (Discrete Fast Fourier Transform) of an image";
06808 }
06809
06810 static const string NAME;
06811 };
06812
06817 class RadialProcessor : public Processor
06818 {
06819 public:
06820 void process_inplace(EMData * image);
06821
06822 string get_name() const
06823 {
06824 return NAME;
06825 }
06826
06827 static Processor *NEW()
06828 {
06829 return new RadialProcessor();
06830 }
06831
06832 TypeDict get_param_types() const
06833 {
06834 TypeDict d;
06835 d.put("table", EMObject::FLOATARRAY, "Radial array of floats, 1 float/pixel");
06836 return d;
06837 }
06838
06839 string get_desc() const
06840 {
06841 return "Multiply a real-space image by a radial function. 1 value / pixel, extending to corner. Missing values -> 0.";
06842 }
06843
06844 static const string NAME;
06845 };
06846
06853 class HistogramBin : public Processor
06854 {
06855 public:
06856 HistogramBin() : default_bins(1024) {}
06857
06858 void process_inplace(EMData * image);
06859
06860 string get_name() const
06861 {
06862 return NAME;
06863 }
06864
06865 static Processor *NEW()
06866 {
06867 return new HistogramBin();
06868 }
06869
06870 TypeDict get_param_types() const
06871 {
06872 TypeDict d;
06873 d.put("nbins", EMObject::INT, "The number of bins the pixel values will be compressed into");
06874 d.put("debug", EMObject::BOOL, "Outputs debugging information (number of pixels per bin)");
06875 return d;
06876 }
06877
06878 string get_desc() const
06879 {
06880 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";
06881 }
06882
06883 static const string NAME;
06884
06885 protected:
06886 int default_bins;
06887 };
06888
06889 class ModelHelixProcessor : public Processor
06890 {
06891 protected:
06892 float radprofile(float r, int type);
06893 };
06894
06895 class ModelEMCylinderProcessor : public ModelHelixProcessor
06896 {
06897 public:
06898 void process_inplace(EMData * in);
06899
06900 string get_name() const
06901 {
06902 return NAME;
06903 }
06904
06905 static Processor *NEW()
06906 {
06907 return new ModelEMCylinderProcessor();
06908 }
06909
06910 string get_desc() const
06911 {
06912 return "Adds a cylinder with a radial density profile similar to that of an alpha helix.";
06913 }
06914
06915 virtual TypeDict get_param_types() const
06916 {
06917 TypeDict d;
06918 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");
06919 d.put("length", EMObject::FLOAT, "cylinder length in angstroms, defaults to 3 turns (16.2 Angstroms)");
06920 d.put("x0", EMObject::INT, "x coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06921 d.put("y0", EMObject::INT, "y coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06922 d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06923
06924 return d;
06925 }
06926
06927 static const string NAME;
06928 };
06929
06930 class ApplyPolynomialProfileToHelix : public ModelHelixProcessor
06931 {
06932 public:
06933 void process_inplace(EMData * in);
06934
06935 string get_name() const
06936 {
06937 return NAME;
06938 }
06939
06940 static Processor *NEW()
06941 {
06942 return new ApplyPolynomialProfileToHelix();
06943 }
06944
06945 string get_desc() const
06946 {
06947 return "Finds the CM of each z-axis slice and applies a polynomial radial profile about it.";
06948 }
06949 virtual TypeDict get_param_types() const
06950 {
06951 TypeDict d;
06952 d.put("length", EMObject::FLOAT, "Helix length in angstroms.");
06953 d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06954 return d;
06955 }
06956
06957 static const string NAME;
06958 };
06959
06960 class BinarySkeletonizerProcessor : public Processor
06961 {
06962 public:
06963 virtual EMData* process(EMData * image);
06964 virtual void process_inplace(EMData * image);
06965
06966 virtual string get_name() const
06967 {
06968 return NAME;
06969
06970 }
06971 static Processor *NEW()
06972 {
06973 return new BinarySkeletonizerProcessor();
06974 }
06975 string get_desc() const
06976 {
06977 return "Creates a skeleton of the 3D image by considering whether density is above or below a threshold value.";
06978 }
06979 virtual TypeDict get_param_types() const
06980 {
06981 TypeDict d;
06982 d.put("threshold", EMObject::FLOAT, "Threshold value.");
06983 d.put("min_curve_width", EMObject::INT, "Minimum curve width.");
06984 d.put("min_surface_width", EMObject::INT, "Minimum surface width.");
06985 d.put("mark_surfaces", EMObject::BOOL, "Mark surfaces with a value of 2.0f, whereas curves are 1.0f.");
06986 return d;
06987 }
06988 static const string NAME;
06989 };
06990
06991 #ifdef EMAN2_USING_CUDA
06992
06997 class CudaMultProcessor: public Processor
06998 {
06999 public:
07000
07001 virtual void process_inplace(EMData * image);
07002
07003 virtual string get_name() const
07004 {
07005 return NAME;
07006 }
07007
07008 static Processor *NEW()
07009 {
07010 return new CudaMultProcessor();
07011 }
07012
07013 virtual TypeDict get_param_types() const
07014 {
07015 TypeDict d;
07016 d.put("scale", EMObject::FLOAT, "The amount to multiply each pixel by");
07017 return d;
07018 }
07019
07020 virtual string get_desc() const
07021 {
07022 return "Multiplies each pixel by a constant value";
07023 }
07024
07025 static const string NAME;
07026
07027 protected:
07028 };
07029
07035 class CudaCorrelationProcessor: public Processor
07036 {
07037 public:
07038
07039 virtual void process_inplace(EMData * image);
07040
07041 string get_name() const
07042 {
07043 return NAME;
07044 }
07045
07046 static Processor *NEW()
07047 {
07048 return new CudaCorrelationProcessor();
07049 }
07050
07051 virtual TypeDict get_param_types() const
07052 {
07053 TypeDict d;
07054 d.put("with", EMObject::EMDATA, "That which to perform the cross correlation with.");
07055 return d;
07056 }
07057
07058 virtual string get_desc() const
07059 {
07060 return "Performs Fourier based cross correlation on the GPU";
07061 }
07062
07063 static const string NAME;
07064
07065 protected:
07066 };
07067
07068
07069
07070
07071
07072
07073 class MPICUDA_kmeans {
07074 public:
07075 MPICUDA_kmeans();
07076 ~MPICUDA_kmeans();
07077 int setup(int extm, int extN, int extn, int extK, int extn_start);
07078 void append_flat_image(EMData* im, int pos);
07079 int init_mem(int numdev);
07080 void compute_im2();
07081 int random_ASG(long int rnd);
07082 vector<int> get_ASG();
07083 vector<int> get_asg();
07084 void compute_NC();
07085 vector<int> get_NC();
07086 void set_ASG(const vector <int>& ASG);
07087 void set_NC(const vector <int>& NC);
07088 int get_ct_im_mv();
07089 void set_T(float extT);
07090 float get_T();
07091 void compute_AVE();
07092 void set_AVE(EMData* im, int pos);
07093 vector<EMData*> get_AVE();
07094 int one_iter();
07095 int one_iter_SA();
07096 vector<float> compute_ji();
07097 vector<float> compute_criterion(const vector <float>& Ji);
07098 int shutdown();
07099 private:
07100
07101 int m;
07102 int N;
07103 int n;
07104 int K;
07105 int nb_part;
07106 int n_start;
07107 int size_im;
07108 int size_IM;
07109 int size_AVE;
07110 int size_dist;
07111 int BLOCK_SIZE;
07112 int NB;
07113 int ins_BLOCK;
07114 int ite;
07115 float T;
07116
07117 int ct_im_mv;
07118
07119 float* h_IM;
07120 float* h_im;
07121 float* h_AVE;
07122 float* h_dist;
07123 float* h_AVE2;
07124 float* h_im2;
07125 unsigned short int* h_ASG;
07126 unsigned short int* h_asg;
07127 unsigned int* h_NC;
07128 int* params;
07129
07130 float* d_im;
07131 float* d_AVE;
07132 float* d_dist;
07133 };
07134
07135 #endif //EMAN2_USING_CUDA
07136
07137 #if 0
07138
07139 class XYZProcessor:public Processor
07140 {
07141 public:
07142 void process_inplace(EMData * image);
07143
07144 string get_name() const
07145 {
07146 return NAME;
07147 }
07148
07149 static Processor *NEW()
07150 {
07151 return new XYZProcessor();
07152 }
07153
07154 string get_desc() const
07155 {
07156 return "N/A";
07157 }
07158
07159 TypeDict get_param_types() const
07160 {
07161 TypeDict d;
07162 return d;
07163 }
07164
07165 static const string NAME;
07166 };
07167
07168
07169 #endif
07170
07171
07172 int multi_processors(EMData * image, vector < string > processornames);
07173 void dump_processors();
07174 map<string, vector<string> > dump_processors_list();
07175 map<string, vector<string> > group_processors();
07176
07177 template <> Factory < Processor >::Factory();
07178 }
07179
07180 #endif //eman_filter_h__
07181
07182
07183