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 *) {}
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 *) {}
00390 virtual void create_radial_func(vector < float >&radial_mask,EMData *image) const = 0;
00391 };
00392
00395 class SNREvalProcessor:public Processor
00396 {
00397 public:
00398 string get_name() const
00399 {
00400 return NAME;
00401 }
00402
00403 void process_inplace(EMData * image);
00404
00405 void set_params(const Dict & new_params)
00406 {
00407 params = new_params;
00408
00409
00410
00411 }
00412
00413 TypeDict get_param_types() const
00414 {
00415 TypeDict d;
00416
00417
00418 return d;
00419 }
00420
00421 static Processor *NEW()
00422 {
00423 return new SNREvalProcessor();
00424 }
00425
00426 string get_desc() const
00427 {
00428 return "Evaluates the SNR of the particle using a masking method similar to that used in the CTF analysis process. The image is not changed. The resulting value is placed in the particle dictionary as eval_maskedsnr";
00429 }
00430
00431 static const string NAME;
00432
00433 protected:
00434 EMData *sum;
00435 int dosqrt;
00436 };
00437
00438
00443 class AmpweightFourierProcessor:public Processor
00444 {
00445 public:
00446 string get_name() const
00447 {
00448 return NAME;
00449 }
00450
00451 void process_inplace(EMData * image);
00452
00453 void set_params(const Dict & new_params)
00454 {
00455 params = new_params;
00456 sum = params["sum"];
00457 dosqrt = params["sqrt"];
00458
00459 }
00460
00461 TypeDict get_param_types() const
00462 {
00463 TypeDict d;
00464 d.put("sum", EMObject::EMDATA, "Adds the weights to sum for normalization");
00465 d.put("sqrt", EMObject::INT, "Weights using sqrt of the amplitude if set");
00466 return d;
00467 }
00468
00469 static Processor *NEW()
00470 {
00471 return new AmpweightFourierProcessor();
00472 }
00473
00474 string get_desc() const
00475 {
00476 return "Multiplies each Fourier pixel by its amplitude";
00477 }
00478
00479 static const string NAME;
00480
00481 protected:
00482 EMData *sum;
00483 int dosqrt;
00484 };
00491 class ConvolutionProcessor : public Processor
00492 {
00493 public:
00494 ConvolutionProcessor() {}
00495
00496 string get_name() const
00497 {
00498 return NAME;
00499 }
00500
00501 void process_inplace(EMData *image);
00502
00503 static Processor *NEW()
00504 {
00505 return new ConvolutionProcessor();
00506 }
00507
00508 string get_desc() const
00509 {
00510 return "Performs Fourier space convolution. Maintains the space that the image is in - i.e. if image is real, the result is real and vice versa.";
00511 }
00512
00513 TypeDict get_param_types() const
00514 {
00515 TypeDict d;
00516 d.put("with", EMObject::EMDATA, "The image that will convolute the other image");
00517 return d;
00518 }
00519
00520 static const string NAME;
00521 };
00522
00529 class XGradientProcessor : public Processor
00530 {
00531 public:
00532 XGradientProcessor() {}
00533
00534 string get_name() const
00535 {
00536 return NAME;
00537 }
00538
00539 void process_inplace(EMData *image);
00540
00541 static Processor *NEW()
00542 {
00543 return new XGradientProcessor();
00544 }
00545
00546 string get_desc() const
00547 {
00548 return "Determines the image gradient in the x direction";
00549 }
00550
00551 TypeDict get_param_types() const
00552 {
00553 TypeDict d;
00554 return d;
00555 }
00556
00557 static const string NAME;
00558 };
00559
00560 class YGradientProcessor : public Processor
00561 {
00562 public:
00563 YGradientProcessor() {}
00564
00565 string get_name() const
00566 {
00567 return NAME;
00568 }
00569
00570 void process_inplace(EMData *image);
00571
00572 static Processor *NEW()
00573 {
00574 return new YGradientProcessor();
00575 }
00576
00577 string get_desc() const
00578 {
00579 return "Determines the image gradient in the y direction";
00580 }
00581
00582
00583 TypeDict get_param_types() const
00584 {
00585 TypeDict d;
00586 return d;
00587 }
00588
00589 static const string NAME;
00590 };
00591
00592 class ZGradientProcessor : public Processor
00593 {
00594 public:
00595 ZGradientProcessor() {}
00596
00597 string get_name() const
00598 {
00599 return NAME;
00600 }
00601
00602 void process_inplace(EMData *image);
00603
00604 static Processor *NEW()
00605 {
00606 return new ZGradientProcessor();
00607 }
00608
00609 string get_desc() const
00610 {
00611 return "Determines the image gradient in the z direction";
00612 }
00613
00614 TypeDict get_param_types() const
00615 {
00616 TypeDict d;
00617 return d;
00618 }
00619
00620 static const string NAME;
00621 };
00622
00631 class Wiener2DAutoAreaProcessor:public Processor
00632 {
00633 public:
00634 string get_name() const
00635 {
00636 return NAME;
00637 }
00638
00639 virtual EMData* process(const EMData * const image);
00640
00641 void process_inplace(EMData *image);
00642
00643 void set_params(const Dict & new_params)
00644 {
00645 params = new_params;
00646 bgsize = params["size"];
00647
00648 }
00649
00650 TypeDict get_param_types() const
00651 {
00652 TypeDict d;
00653 d.put("size", EMObject::INT, "Size in pixels of the boxes to chop the image into");
00654 return d;
00655 }
00656
00657 static Processor *NEW()
00658 {
00659 return new Wiener2DAutoAreaProcessor();
00660 }
00661
00662 string get_desc() const
00663 {
00664 return "Automatically detrmines the background for the image then uses this to perform Wiener filters on overlapping subregions of the image, which are then combined using linear interpolation";
00665 }
00666
00667 static const string NAME;
00668
00669 protected:
00670 int bgsize;
00671 };
00672
00679 class DistanceSegmentProcessor:public Processor
00680 {
00681 public:
00682 string get_name() const
00683 {
00684 return NAME;
00685 }
00686
00687 virtual EMData* process(const EMData * const image);
00688 void process_inplace( EMData * image);
00689
00690 TypeDict get_param_types() const
00691 {
00692 TypeDict d ;
00693 d.put("thr",EMObject::FLOAT,"Optional : Isosurface threshold value. Pixels below this will not be segment centers (default = 0.9)");
00694 d.put("minsegsep",EMObject::FLOAT,"Required: Minimum segment separation in pixels. Segments too close will trigger a reseed");
00695 d.put("maxsegsep",EMObject::FLOAT,"Required: Maximum segment separation in pixels. Segments too close will trigger a reseed");
00696 d.put("verbose",EMObject::INT,"Be verbose while running");
00697 return d;
00698 }
00699
00700 static Processor *NEW()
00701 {
00702 return new DistanceSegmentProcessor();
00703 }
00704
00705 string get_desc() const
00706 {
00707 return "Segments a volume into pieces separated by distances in the specified range.";
00708 }
00709
00710 static const string NAME;
00711
00712 };
00713
00720 class KmeansSegmentProcessor:public Processor
00721 {
00722 public:
00723 string get_name() const
00724 {
00725 return NAME;
00726 }
00727
00728 virtual EMData* process(const EMData * const image);
00729 void process_inplace( EMData * image);
00730
00731 TypeDict get_param_types() const
00732 {
00733 TypeDict d ;
00734 d.put("nseg", EMObject::INT, "Number of segments to divide the image into. default=12" );
00735 d.put("thr",EMObject::FLOAT,"Isosurface threshold value. Pixels below this will not be segmented");
00736 d.put("ampweight",EMObject::INT,"If set, will weight centers by voxel amplitude. default = 1");
00737 d.put("maxsegsize",EMObject::FLOAT,"Maximum radial distance from segment center to member voxel. Default=10000");
00738 d.put("minsegsep",EMObject::FLOAT,"Minimum segment separation. Segments too close will trigger a reseed");
00739 d.put("maxiter",EMObject::FLOAT,"Maximum number of iterations to run before stopping. Default=100");
00740 d.put("maxvoxmove",EMObject::FLOAT,"Maximum number of voxels that can move before quitting. Default=25");
00741 d.put("verbose",EMObject::INT,"Be verbose while running");
00742 return d;
00743 }
00744
00745 static Processor *NEW()
00746 {
00747 return new KmeansSegmentProcessor();
00748 }
00749
00750 string get_desc() const
00751 {
00752 return "Performs K-means segmentation on a volume. Note that this method uses random seeds, and thus will return different results each time it is run. Returned map contains number of segment for each voxel (or 0 for unsegmented voxels). Segmentation centers are stored in 'segmentcenters' attribute, consisting of a list of 3n floats in x,y,z triples.";
00753 }
00754
00755 static const string NAME;
00756
00757 };
00758
00759
00766 class Wiener2DFourierProcessor:public Processor
00767 {
00768 public:
00769 string get_name() const
00770 {
00771 return NAME;
00772 }
00773
00774 virtual EMData* process(const EMData * const image);
00775
00776 void process_inplace(EMData *image);
00777
00778 void set_params(const Dict & new_params)
00779 {
00780 params = new_params;
00781 ctf = params["ctf"];
00782
00783 }
00784
00785 TypeDict get_param_types() const
00786 {
00787 TypeDict d;
00788 d.put("ctf", EMObject::EMDATA, "Ctf object to use for Wiener filter parameters");
00789 return d;
00790 }
00791
00792 static Processor *NEW()
00793 {
00794 return new Wiener2DFourierProcessor();
00795 }
00796
00797 string get_desc() const
00798 {
00799 return "Applies a 2-D Wiener filter to an image based on its Ctf parameters";
00800 }
00801
00802 static const string NAME;
00803
00804 protected:
00805 Ctf *ctf;
00806 };
00807
00808 class LinearRampFourierProcessor:public FourierProcessor
00809 {
00810 public:
00811 virtual string get_name() const
00812 {
00813 return NAME;
00814 }
00815
00816 virtual string get_desc() const
00817 {
00818 return "";
00819 }
00820
00821 static Processor *NEW()
00822 {
00823 return new LinearRampFourierProcessor();
00824 }
00825
00826 static const string NAME;
00827
00828 protected:
00829 virtual void create_radial_func(vector < float >&radial_mask) const ;
00830 };
00831
00834 class LowpassAutoBProcessor:public FourierAnlProcessor
00835 {
00836 public:
00837 string get_name() const
00838 {
00839 return NAME;
00840 }
00841
00842 static Processor *NEW()
00843 {
00844 return new LowpassAutoBProcessor();
00845 }
00846
00847 string get_desc() const
00848 {
00849 return "This processor sharpens a map based on the concept that the power spectrum should be roughly flat over the ~15 A-Nyquist resolution range, then combines this inverse B-factor with the specified low-pass Gaussian filter parameters to produce a single aggregate Gaussian filter.";
00850 }
00851
00852 static const string NAME;
00853
00854 virtual TypeDict get_param_types() const
00855 {
00856 TypeDict d = FourierAnlProcessor::get_param_types();
00857 d.put("bfactor", EMObject::FLOAT, "B-factor in terms of e^-(B s^2/4)");
00858 d.put("noisecutoff", EMObject::FLOAT, "Spatial frequency past which inverse-B will not be applied");
00859
00860 d.put("verbose", EMObject::INT, "Print information about the determined B-factor");
00861 return d;
00862 }
00863
00864 protected:
00865 virtual void preprocess(EMData * image) {
00866 if(params.has_key("apix")) {
00867 image->set_attr("apix_x", (float)params["apix"]);
00868 image->set_attr("apix_y", (float)params["apix"]);
00869 image->set_attr("apix_z", (float)params["apix"]);
00870 }
00871 float apix=(float)image->get_attr("apix_x");
00872
00873 const Dict dict = image->get_attr_dict();
00874 if (params.has_key("cutoff_abs")) {
00875 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00876 }
00877 else if( params.has_key("cutoff_freq") ) {
00878 float val = (float)params["cutoff_freq"] * apix;
00879 params["cutoff_abs"] = val;
00880 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00881 }
00882 else if( params.has_key("cutoff_pixels") ) {
00883 float val = 0.5f*(float)params["cutoff_pixels"] / (float)dict["nx"];
00884 params["cutoff_abs"] = val;
00885 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00886 }
00887 }
00888
00889 void create_radial_func(vector < float >&radial_mask,EMData *image) const;
00890 };
00891
00894 class HighpassAutoPeakProcessor:public FourierAnlProcessor
00895 {
00896 public:
00897 string get_name() const
00898 {
00899 return NAME;
00900 }
00901 static Processor *NEW()
00902 {
00903 return new HighpassAutoPeakProcessor();
00904 }
00905
00906 string get_desc() const
00907 {
00908 return "Attempts to automatically remove the low resolution peak present in virtually all cryoEM data.";
00909 }
00910
00911 static const string NAME;
00912
00913 protected:
00914 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
00915 virtual void preprocess(EMData * image);
00916 float highpass;
00917 };
00918
00923 class LinearRampProcessor:public FourierProcessor
00924 {
00925 public:
00926 LinearRampProcessor():intercept(0), slope(0)
00927 {
00928 }
00929
00930 string get_name() const
00931 {
00932 return NAME;
00933 }
00934 static Processor *NEW()
00935 {
00936 return new LinearRampProcessor();
00937 }
00938
00939 string get_desc() const
00940 {
00941 return "processor radial function: f(x) = slope * x + intercept;";
00942 }
00943
00944 void set_params(const Dict & new_params)
00945 {
00946 params = new_params;
00947 intercept = params["intercept"];
00948 slope = params["slope"];
00949 }
00950
00951 TypeDict get_param_types() const
00952 {
00953 TypeDict d;
00954 d.put("intercept", EMObject::FLOAT, "intercept in 'f(x) = slope * x + intercept'");
00955 d.put("slope", EMObject::FLOAT, "slope in 'f(x) = slope * x + intercept'");
00956 return d;
00957 }
00958
00959 static const string NAME;
00960
00961 protected:
00962 void create_radial_func(vector < float >&radial_mask) const;
00963
00964 private:
00965 float intercept;
00966 float slope;
00967 };
00968
00972 class LoGFourierProcessor:public FourierProcessor
00973 {
00974 public:
00975 LoGFourierProcessor():sigma(0)
00976 {
00977 }
00978
00979 string get_name() const
00980 {
00981 return NAME;
00982 }
00983 static Processor *NEW()
00984 {
00985 return new LoGFourierProcessor();
00986 }
00987
00988 string get_desc() const
00989 {
00990 return "processor radial function: f(x) = ((x^2 - s^2)/s^4)e^-(x^2/2s^2)";
00991 }
00992
00993 void set_params(const Dict & new_params)
00994 {
00995 params = new_params;
00996 sigma = params["sigma"];
00997 }
00998
00999 TypeDict get_param_types() const
01000 {
01001 TypeDict d;
01002 d.put("sigma", EMObject::FLOAT, "LoG sigma");
01003 return d;
01004 }
01005
01006 static const string NAME;
01007
01008 protected:
01009 void create_radial_func(vector < float >&radial_mask) const;
01010
01011 private:
01012 float sigma;
01013 };
01014
01019 class DoGFourierProcessor:public FourierProcessor
01020 {
01021 public:
01022 DoGFourierProcessor():sigma1(0), sigma2(0)
01023 {
01024 }
01025
01026 string get_name() const
01027 {
01028 return NAME;
01029 }
01030 static Processor *NEW()
01031 {
01032 return new DoGFourierProcessor();
01033 }
01034
01035 string get_desc() const
01036 {
01037 return "processor radial function: f(x) = 1/sqrt(2*pi)*[1/sigma1*exp-(x^2/2*sigma1^2) - 1/sigma2*exp-(x^2/2*sigma2^2)]";
01038 }
01039
01040 void set_params(const Dict & new_params)
01041 {
01042 params = new_params;
01043 sigma1 = params["sigma1"];
01044 sigma2 = params["sigma2"];
01045 }
01046
01047 TypeDict get_param_types() const
01048 {
01049 TypeDict d;
01050 d.put("sigma1", EMObject::FLOAT, "DoG sigma1");
01051 d.put("sigma2", EMObject::FLOAT, "DoG sigma2");
01052 return d;
01053 }
01054
01055 static const string NAME;
01056
01057 protected:
01058 void create_radial_func(vector < float >&radial_mask) const;
01059
01060 private:
01061 float sigma1;
01062 float sigma2;
01063 };
01064
01067 class RealPixelProcessor:public Processor
01068 {
01069 public:
01070 RealPixelProcessor():value(0), maxval(1), mean(0), sigma(0)
01071 {
01072 }
01073 void process_inplace(EMData * image);
01074
01075 virtual void set_params(const Dict & new_params)
01076 {
01077 params = new_params;
01078 if (params.size() == 1) {
01079 vector < EMObject > dict_values = params.values();
01080 value = dict_values[0];
01081 }
01082 }
01083
01084 static string get_group_desc()
01085 {
01086 return "The base class for real space processor working on individual pixels. The processor won't consider the pixel's coordinates and neighbors.";
01087 }
01088
01089 protected:
01090 virtual void process_pixel(float *x) const = 0;
01091 virtual void calc_locals(EMData *)
01092 {
01093 }
01094 virtual void normalize(EMData *) const
01095 {
01096 }
01097
01098 float value;
01099 float maxval;
01100 float mean;
01101 float sigma;
01102 };
01103
01106 class AbsoluateValueProcessor:public RealPixelProcessor
01107 {
01108 public:
01109 string get_name() const
01110 {
01111 return NAME;
01112 }
01113 static Processor *NEW()
01114 {
01115 return new AbsoluateValueProcessor();
01116 }
01117
01118 static const string NAME;
01119
01120 protected:
01121 void process_pixel(float *x) const
01122 {
01123 *x = fabs(*x);
01124 }
01125
01126 string get_desc() const
01127 {
01128 return "f(x) = |x|";
01129 }
01130 };
01131
01134 class FloorValueProcessor:public RealPixelProcessor
01135 {
01136 public:
01137 string get_name() const
01138 {
01139 return NAME;
01140 }
01141 static Processor *NEW()
01142 {
01143 return new FloorValueProcessor();
01144 }
01145
01146 static const string NAME;
01147
01148 protected:
01149 void process_pixel(float *x) const
01150 {
01151 *x = floor(*x);
01152 }
01153
01154 string get_desc() const
01155 {
01156 return "f(x) = floor(x)";
01157 }
01158 };
01159
01160
01163 class BooleanProcessor:public RealPixelProcessor
01164 {
01165 public:
01166 string get_name() const
01167 {
01168 return NAME;
01169 }
01170 static Processor *NEW()
01171 {
01172 return new BooleanProcessor();
01173 }
01174
01175 string get_desc() const
01176 {
01177 return "f(x) = 0 if x = 0; f(x) = 1 if x != 0;";
01178 }
01179
01180 static const string NAME;
01181
01182 protected:
01183 void process_pixel(float *x) const
01184 {
01185 if (*x != 0)
01186 {
01187 *x = 1.0;
01188 }
01189 }
01190 };
01191
01195 class InvertCarefullyProcessor:public RealPixelProcessor
01196 {
01197 public:
01198 string get_name() const
01199 {
01200 return NAME;
01201 }
01202 static Processor *NEW()
01203 {
01204 return new InvertCarefullyProcessor();
01205 }
01206
01207 void set_params(const Dict & new_params)
01208 {
01209 params = new_params;
01210 zero_to = params.set_default("zero_to",0.0f);
01211 }
01212
01213 TypeDict get_param_types() const
01214 {
01215 TypeDict d;
01216 d.put("zero_to", EMObject::FLOAT, "Inverted zero values are set to this value, default is 0.");
01217 return d;
01218 }
01219
01220 string get_desc() const
01221 {
01222 return "if f(x) != 0: f(x) = 1/f(x) else: f(x) = zero_to";
01223 }
01224
01225 static const string NAME;
01226
01227 protected:
01228 void process_pixel(float *x) const
01229 {
01230 if (*x == 0) *x = zero_to;
01231 else *x = 1/(*x);
01232 }
01233 private:
01234 float zero_to;
01235 };
01236
01240 class ValuePowProcessor:public RealPixelProcessor
01241 {
01242 public:
01243 string get_name() const
01244 {
01245 return NAME;
01246 }
01247 static Processor *NEW()
01248 {
01249 return new ValuePowProcessor();
01250 }
01251
01252 void set_params(const Dict & new_params)
01253 {
01254 params = new_params;
01255 pwr = params["pow"];
01256 }
01257
01258 TypeDict get_param_types() const
01259 {
01260 TypeDict d;
01261 d.put("pow", EMObject::FLOAT, "Each pixel is raised to this power");
01262 return d;
01263 }
01264
01265 string get_desc() const
01266 {
01267 return "f(x) = x ^ pow;";
01268 }
01269
01270 static const string NAME;
01271
01272 protected:
01273 void process_pixel(float *x) const
01274 {
01275 if (*x<0 && pwr!=(int)pwr) *x=0;
01276 else (*x) = pow(*x,pwr);
01277 }
01278 private:
01279 float pwr;
01280 };
01281
01284 class ValueSquaredProcessor:public RealPixelProcessor
01285 {
01286 public:
01287 string get_name() const
01288 {
01289 return NAME;
01290 }
01291 static Processor *NEW()
01292 {
01293 return new ValueSquaredProcessor();
01294 }
01295
01296
01297 string get_desc() const
01298 {
01299 return "f(x) = x * x;";
01300 }
01301
01302 static const string NAME;
01303
01304 protected:
01305 void process_pixel(float *x) const
01306 {
01307 (*x) *= (*x);
01308 }
01309 };
01310
01313 class ValueSqrtProcessor:public RealPixelProcessor
01314 {
01315 public:
01316 string get_name() const
01317 {
01318 return NAME;
01319 }
01320 static Processor *NEW()
01321 {
01322 return new ValueSqrtProcessor();
01323 }
01324
01325 string get_desc() const
01326 {
01327 return "f(x) = sqrt(x)";
01328 }
01329
01330 static const string NAME;
01331
01332 protected:
01333 void process_pixel(float *x) const
01334 {
01335 *x = sqrt(*x);
01336 }
01337 };
01338
01342 class ToZeroProcessor:public RealPixelProcessor
01343 {
01344 public:
01345 string get_name() const
01346 {
01347 return NAME;
01348 }
01349 static Processor *NEW()
01350 {
01351 return new ToZeroProcessor();
01352 }
01353 TypeDict get_param_types() const
01354 {
01355 TypeDict d;
01356 d.put("minval", EMObject::FLOAT, "Everything below this value is set to zero");
01357 return d;
01358 }
01359
01360 string get_desc() const
01361 {
01362 return "f(x) = x if x >= minval; f(x) = 0 if x < minval.";
01363 }
01364
01365 static const string NAME;
01366
01367 protected:
01368 inline void process_pixel(float *x) const
01369 {
01370 if (*x < value) {
01371 *x = 0;
01372 }
01373 }
01374 };
01375
01381 class Rotate180Processor:public Processor
01382 {
01383 public:
01384 string get_name() const
01385 {
01386 return NAME;
01387 }
01388 static Processor *NEW()
01389 {
01390 return new Rotate180Processor();
01391 }
01392
01396 void process_inplace(EMData* image);
01397
01398 string get_desc() const
01399 {
01400 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.";
01401 }
01402
01403 static const string NAME;
01404 };
01405
01412 class TransformProcessor:public Processor
01413 {
01414 public:
01415 virtual string get_name() const
01416 {
01417 return NAME;
01418 }
01419 static Processor *NEW()
01420 {
01421 return new TransformProcessor();
01422 }
01423
01428 virtual void process_inplace(EMData* image);
01429
01434 virtual EMData* process(const EMData* const image);
01435
01436 virtual TypeDict get_param_types() const
01437 {
01438 TypeDict d;
01439 d.put("transform", EMObject::TRANSFORM, "The Transform object that will be applied to the image" );
01440 return d;
01441 }
01442
01443 virtual string get_desc() const
01444 {
01445 return "The image is transformed using Transform parameter.";
01446 }
01447
01448 static const string NAME;
01449
01450 private:
01451 float* transform(const EMData* const image, const Transform& t) const;
01452
01453
01454
01455
01456 void assert_valid_aspect(const EMData* const image) const;
01457 };
01458
01466 class IntTranslateProcessor:public Processor
01467 {
01468 public:
01469 virtual string get_name() const
01470 {
01471 return NAME;
01472 }
01473
01474 static Processor *NEW()
01475 {
01476 return new IntTranslateProcessor();
01477 }
01478
01483 virtual void process_inplace(EMData* image);
01484
01489 virtual EMData* process(const EMData* const image);
01490
01491 virtual TypeDict get_param_types() const
01492 {
01493 TypeDict d;
01494 d.put("trans", EMObject::INTARRAY, "The displacement array, can be length 1-3" );
01495 return d;
01496 }
01497
01498 virtual string get_desc() const
01499 {
01500 return "The image is translated an integer amount";
01501 }
01502
01503 static const string NAME;
01504
01505 private:
01509 void assert_valid_aspect(const vector<int>& translation, const EMData* const image) const;
01510
01516 Region get_clip_region(vector<int>& translation, const EMData* const image) const;
01517 };
01518
01525 class SymAlignProcessor:public Processor
01526 {
01527 public:
01528 virtual string get_name() const
01529 {
01530 return NAME;
01531 }
01532
01533 static Processor *NEW()
01534 {
01535 return new SymAlignProcessor();
01536 }
01537
01538 virtual void process_inplace(EMData* image);
01539
01540 virtual EMData* process(const EMData* const image);
01541
01542 virtual TypeDict get_param_types() const
01543 {
01544 TypeDict d;
01545 d.put("sym", EMObject::STRING, "The symmetry under which to do the alignment, Default=c1" );
01546 d.put("delta", EMObject::FLOAT,"Angle the separates points on the sphere. This is exclusive of the \'n\' paramater. Default is 10");
01547 d.put("dphi", EMObject::FLOAT,"The angle increment in the phi direction. Default is 10");
01548 d.put("lphi", EMObject::FLOAT,"Lower bound for phi. Default it 0");
01549 d.put("uphi", EMObject::FLOAT,"Upper bound for phi. Default it 359.9");
01550 d.put("avger", EMObject::STRING, "The sort of averager to use, Default=mean" );
01551 return d;
01552 }
01553
01554 virtual string get_desc() const
01555 {
01556 return "The image is centered and rotated to the standard orientation for the specified symmetry";
01557 }
01558
01559 static const string NAME;
01560
01561 private:
01565 void assert_valid_aspect(const vector<int>& translation, const EMData* const image) const;
01566
01572 Region get_clip_region(vector<int>& translation, const EMData* const image) const;
01573 };
01574
01575
01582 class ScaleTransformProcessor:public Processor
01583 {
01584 public:
01585 virtual string get_name() const
01586 {
01587 return NAME;
01588 }
01589 static Processor *NEW()
01590 {
01591 return new ScaleTransformProcessor();
01592 }
01593
01598 virtual void process_inplace(EMData* image);
01599
01604 virtual EMData* process(const EMData* const image);
01605
01606 virtual TypeDict get_param_types() const
01607 {
01608 TypeDict d;
01609 d.put("scale", EMObject::FLOAT, "The amount by which to scale" );
01610 d.put("clip", EMObject::INT, "The length of each output dimension. Non sophisticated, output dimensions can't be different" );
01613 return d;
01614 }
01615
01616 virtual string get_desc() const
01617 {
01618 return "The image is scaled with the clip variable in mind, being sure to preserve as much pixel information as possible.";
01619 }
01620
01621 static const string NAME;
01622 };
01623
01630 class ClampingProcessor :public Processor
01631 {
01632 public:
01633 ClampingProcessor() : default_max(1.0), default_min(0.0) {}
01634
01635 string get_name() const
01636 {
01637 return NAME;
01638 }
01639 static Processor *NEW()
01640 {
01641 return new ClampingProcessor();
01642 }
01643
01644 void process_inplace(EMData *image);
01645
01646 TypeDict get_param_types() const
01647 {
01648 TypeDict d;
01649 d.put("minval", EMObject::FLOAT, "The pixel values that bounds the smallest pixel value in the output image" );
01650 d.put("maxval", EMObject::FLOAT, "The pixel values that bounds the largest pixel value in the output image" );
01651 d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01652 return d;
01653 }
01654
01655 string get_desc() const
01656 {
01657 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.";
01658 }
01659
01660 static const string NAME;
01661
01662 protected:
01663 float default_max, default_min;
01664 };
01665
01671 class NSigmaClampingProcessor : public ClampingProcessor
01672 {
01673 public:
01674 NSigmaClampingProcessor() : default_sigma(2.0) {}
01675
01676 string get_name() const
01677 {
01678 return NAME;
01679 }
01680
01681 static Processor *NEW()
01682 {
01683 return new NSigmaClampingProcessor();
01684 }
01685
01686 TypeDict get_param_types() const
01687 {
01688 TypeDict d;
01689 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" );
01690 d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01691 return d;
01692 }
01693
01694 void process_inplace(EMData *image);
01695
01696 string get_desc() const
01697 {
01698 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.";
01699 }
01700
01701 static const string NAME;
01702
01703 protected:
01704 float default_sigma;
01705 };
01706
01710 class ToMinvalProcessor:public Processor
01711 {
01712 public:
01713 string get_name() const
01714 {
01715 return NAME;
01716 }
01717 static Processor *NEW()
01718 {
01719 return new ToMinvalProcessor();
01720 }
01721
01722 void process_inplace(EMData *image);
01723
01724 TypeDict get_param_types() const
01725 {
01726 TypeDict d;
01727 d.put("minval", EMObject::FLOAT, "Everything below this value is set to this value");
01728 d.put("newval", EMObject::FLOAT, "If set, values below minval will be set to newval instead of minval ");
01729 return d;
01730 }
01731
01732 string get_desc() const
01733 {
01734 return "f(x) = x if x >= minval; f(x) = minval|newval if x < minval.";
01735 }
01736
01737 static const string NAME;
01738
01739 protected:
01740
01741 };
01742
01743
01744
01748 class CutToZeroProcessor:public RealPixelProcessor
01749 {
01750 public:
01751 string get_name() const
01752 {
01753 return NAME;
01754 }
01755 static Processor *NEW()
01756 {
01757 return new CutToZeroProcessor();
01758 }
01759 TypeDict get_param_types() const
01760 {
01761 TypeDict d;
01762 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" );
01763 return d;
01764 }
01765
01766 string get_desc() const
01767 {
01768 return "f(x) = x-minval if x >= minval; f(x) = 0 if x < minval.";
01769 }
01770
01771 static const string NAME;
01772
01773 protected:
01774 void process_pixel(float *x) const
01775 {
01776 *x = *x - value;
01777 if (*x < 0) {
01778 *x = 0;
01779 }
01780 }
01781 };
01782
01786 class BinarizeProcessor:public RealPixelProcessor
01787 {
01788 public:
01789 string get_name() const
01790 {
01791 return NAME;
01792 }
01793 static Processor *NEW()
01794 {
01795 return new BinarizeProcessor();
01796 }
01797 TypeDict get_param_types() const
01798 {
01799 TypeDict d;
01800 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" );
01801 return d;
01802 }
01803
01804 string get_desc() const
01805 {
01806 return "f(x) = 0 if x < value; f(x) = 1 if x >= value.";
01807 }
01808
01809 static const string NAME;
01810
01811 protected:
01812 void process_pixel(float *x) const
01813 {
01814 if (*x < value)
01815 {
01816 *x = 0;
01817 }
01818 else
01819 {
01820 *x = 1;
01821 }
01822 }
01823 };
01824
01832 class BinarizeFourierProcessor:public Processor
01833 {
01834 public:
01835 virtual string get_name() const
01836 {
01837 return NAME;
01838 }
01839 static Processor *NEW()
01840 {
01841 return new BinarizeFourierProcessor();
01842 }
01843
01848 virtual void process_inplace(EMData* image);
01849
01850 virtual TypeDict get_param_types() const
01851 {
01852 TypeDict d;
01853 d.put("value", EMObject::FLOAT, "The Fourier amplitude threshold cutoff" );
01854 return d;
01855 }
01856
01857 virtual string get_desc() const
01858 {
01859 return "f(k) = 0 + 0i if ||f(k)|| < value; f(k) = a + bi if ||f(k)|| >= value.";
01860 }
01861
01862 static const string NAME;
01863 };
01864
01869 class CollapseProcessor:public RealPixelProcessor
01870 {
01871 public:
01872 string get_name() const
01873 {
01874 return NAME;
01875 }
01876 static Processor *NEW()
01877 {
01878 return new CollapseProcessor();
01879 }
01880
01881 void set_params(const Dict & new_params)
01882 {
01883 params = new_params;
01884 range = params["range"];
01885 value = params["value"];
01886 }
01887
01888 TypeDict get_param_types() const
01889 {
01890 TypeDict d;
01891 d.put("range", EMObject::FLOAT, "The range about 'value' which will be collapsed to 'value'");
01892 d.put("value", EMObject::FLOAT, "The pixel value where the focus of the collapse operation is");
01893 return d;
01894 }
01895
01896 string get_desc() const
01897 {
01898 return "f(x): if v-r<x<v+r -> v; if x>v+r -> x-r; if x<v-r -> x+r";
01899 }
01900
01901 static const string NAME;
01902
01903 protected:
01904 void process_pixel(float *x) const
01905 {
01906 if (*x>value+range) *x-=range;
01907 else if (*x<value-range) *x+=range;
01908 else *x=value;
01909 }
01910 float range;
01911 };
01912
01917 class LinearXformProcessor:public RealPixelProcessor
01918 {
01919 public:
01920 LinearXformProcessor():shift(0), scale(0)
01921 {
01922 }
01923
01924 string get_name() const
01925 {
01926 return NAME;
01927 }
01928 static Processor *NEW()
01929 {
01930 return new LinearXformProcessor();
01931 }
01932
01933 void set_params(const Dict & new_params)
01934 {
01935 params = new_params;
01936 shift = params.get("shift");
01937 scale = params.get("scale");
01938 }
01939
01940 TypeDict get_param_types() const
01941 {
01942 TypeDict d;
01943 d.put("shift", EMObject::FLOAT, "The amount to shift pixel values by before scaling");
01944 d.put("scale", EMObject::FLOAT, "The scaling factor to be applied to pixel values");
01945 return d;
01946 }
01947
01948 string get_desc() const
01949 {
01950 return "linear transform processor: f(x) = x * scale + shift. This is equivalent to a regular contrast stretching operation";
01951 }
01952
01953 static const string NAME;
01954
01955 protected:
01956 void process_pixel(float *x) const
01957 {
01958 *x = (*x) * scale + shift;
01959 }
01960
01961 private:
01962 float shift;
01963 float scale;
01964 };
01965
01970 class ExpProcessor:public RealPixelProcessor
01971 {
01972 public:
01973 ExpProcessor():low(0), high(0)
01974 {
01975 }
01976
01977 string get_name() const
01978 {
01979 return NAME;
01980 }
01981
01982 static Processor *NEW()
01983 {
01984 return new ExpProcessor();
01985 }
01986
01987 void set_params(const Dict & new_params)
01988 {
01989 params = new_params;
01990 low = params.get("low");
01991 high = params.get("high");
01992 }
01993
01994 TypeDict get_param_types() const
01995 {
01996 TypeDict d;
01997 d.put("low", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
01998 d.put("high", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
01999 return d;
02000 }
02001
02002 string get_desc() const
02003 {
02004 return "f(x) = exp( x / low - high)";
02005 }
02006
02007 static const string NAME;
02008
02009 protected:
02013 void process_pixel(float *x) const
02014 {
02015 float v = *x / low - high;
02016 if (v > 40) {
02017 v = 40;
02018 }
02019 *x = exp(v);
02020 }
02021
02022 private:
02023 float low;
02024 float high;
02025 };
02026
02030 class FiniteProcessor:public RealPixelProcessor
02031 {
02032 public:
02033 FiniteProcessor():to(0)
02034 {
02035 }
02036
02037 string get_name() const
02038 {
02039 return NAME;
02040 }
02041
02042 static Processor *NEW()
02043 {
02044 return new FiniteProcessor();
02045 }
02046
02047 void set_params(const Dict & new_params)
02048 {
02049 if (new_params.has_key("to") )
02050 to = params["to"];
02051 }
02052
02053 TypeDict get_param_types() const
02054 {
02055 TypeDict d;
02056 d.put("to", EMObject::FLOAT, "Pixels which are not finite will be set to this value");
02057 return d;
02058 }
02059
02060 string get_desc() const
02061 {
02062 return "f(x) = f(x) if f(x) is finite | to if f(x) is not finite";
02063 }
02064
02065 static const string NAME;
02066
02067 protected:
02071 void process_pixel(float *x) const;
02072 private:
02073 float to;
02074 };
02075
02080 class RangeThresholdProcessor:public RealPixelProcessor
02081 {
02082 public:
02083 RangeThresholdProcessor():low(0), high(0)
02084 {
02085 }
02086
02087 string get_name() const
02088 {
02089 return NAME;
02090 }
02091 static Processor *NEW()
02092 {
02093 return new RangeThresholdProcessor();
02094 }
02095
02096 void set_params(const Dict & new_params)
02097 {
02098 params = new_params;
02099 low = params.get("low");
02100 high = params.get("high");
02101 }
02102
02103 TypeDict get_param_types() const
02104 {
02105 TypeDict d;
02106 d.put("low", EMObject::FLOAT, "The lower limit of the range that will be set to 1");
02107 d.put("high", EMObject::FLOAT, "The upper limit of the range that will be set to 1");
02108 return d;
02109 }
02110
02111 string get_desc() const
02112 {
02113 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";
02114 }
02115
02116 static const string NAME;
02117
02118 protected:
02119 void process_pixel(float *x) const
02120 {
02121 if (*x >= low && *x <= high) {
02122 *x = 1;
02123 }
02124 else {
02125 *x = 0;
02126 }
02127 }
02128 private:
02129 float low;
02130 float high;
02131
02132 };
02133
02138 class SigmaProcessor:public RealPixelProcessor
02139 {
02140 public:
02141 string get_name() const
02142 {
02143 return NAME;
02144 }
02145 static Processor *NEW()
02146 {
02147 return new SigmaProcessor();
02148 }
02149
02150 void set_params(const Dict & new_params)
02151 {
02152 params = new_params;
02153 value1 = params.get("value1");
02154 value2 = params.get("value2");
02155 }
02156
02157 TypeDict get_param_types() const
02158 {
02159 TypeDict d;
02160 d.put("value1", EMObject::FLOAT, "A number reflecting total standard deviations in the right direction");
02161 d.put("value2", EMObject::FLOAT, "A number reflecting total standard deviations in the left direction");
02162 return d;
02163 }
02164
02165 string get_desc() const
02166 {
02167 return "f(x) = mean if x<(mean-v2*sigma) or x>(mean+v1*sigma); else f(x) = x;";
02168 }
02169
02170 static const string NAME;
02171
02172 protected:
02173 void process_pixel(float *x) const
02174 {
02175 if (*x < (mean - value2 * sigma) || *x > (mean + value1 * sigma))
02176 {
02177 *x = mean;
02178 }
02179 }
02180
02181 private:
02182 float value1;
02183 float value2;
02184 };
02185
02188 class LogProcessor:public RealPixelProcessor
02189 {
02190 public:
02191 string get_name() const
02192 {
02193 return NAME;
02194 }
02195 static Processor *NEW()
02196 {
02197 return new LogProcessor();
02198 }
02199
02200 string get_desc() const
02201 {
02202 return "f(x) = log10(x) if x > 0; else f(x) = 0;";
02203 }
02204
02205 static const string NAME;
02206
02207 protected:
02208 void process_pixel(float *x) const
02209 {
02210 if (*x > 0)
02211 {
02212 *x = log10(*x);
02213 }
02214 else
02215 {
02216 *x = 0;
02217 }
02218 }
02219 };
02220
02223 class CoordinateProcessor:public Processor
02224 {
02225 public:
02226 CoordinateProcessor():nx(0), ny(0), nz(0), mean(0), sigma(0), maxval(0), is_complex(false)
02227 {
02228 }
02229 void process_inplace(EMData * image);
02230
02231 static string get_group_desc()
02232 {
02233 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().";
02234 }
02235
02236 protected:
02237 virtual void process_pixel(float *pixel, int xi, int yi, int zi) const = 0;
02238 virtual void calc_locals(EMData *)
02239 {
02240 }
02241 virtual bool is_valid() const
02242 {
02243 return true;
02244 }
02245
02246 int nx;
02247 int ny;
02248 int nz;
02249 float mean;
02250 float sigma;
02251 float maxval;
02252
02253 bool is_complex;
02254 };
02255
02263 class CircularMaskProcessor:public CoordinateProcessor
02264 {
02265 public:
02266 CircularMaskProcessor():inner_radius(0), outer_radius(0), inner_radius_square(0),
02267 outer_radius_square(0), dx(0), dy(0), dz(0), xc(0), yc(0), zc(0)
02268 {
02269 }
02270
02271 void set_params(const Dict & new_params)
02272 {
02273 params = new_params;
02274
02275 if (params.has_key("inner_radius")) {
02276 inner_radius = params["inner_radius"];
02277 inner_radius_square = inner_radius * inner_radius;
02278 }
02279 else {
02280 inner_radius = -1;
02281 inner_radius_square = -1;
02282 }
02283
02284 if (params.has_key("outer_radius")) {
02285 outer_radius = params["outer_radius"];
02286 outer_radius_square = outer_radius * outer_radius;
02287 }
02288 else {
02289 outer_radius = INT_MAX;
02290 outer_radius_square = INT_MAX;
02291 }
02292
02293 if (params.has_key("xc")) xc = params["xc"];
02294 if (params.has_key("yc")) yc = params["yc"];
02295 if (params.has_key("zc")) zc = params["zc"];
02296 if (params.has_key("dx")) dx = params["dx"];
02297 if (params.has_key("dy")) dy = params["dy"];
02298 if (params.has_key("dz")) dz = params["dz"];
02299 }
02300
02301 string get_desc() const
02302 {
02303 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().";
02304 }
02305
02306 TypeDict get_param_types() const
02307 {
02308 TypeDict d;
02309
02310 d.put("inner_radius", EMObject::INT, "inner mask radius. optional");
02311 d.put("outer_radius", EMObject::INT, "outer mask radius. Negative value -> box radius + outer_radius +1");
02312
02313 d.put("dx", EMObject::FLOAT,
02314 "Modify mask center by dx relative to the default center nx/2");
02315 d.put("dy", EMObject::FLOAT,
02316 "Modify mask center by dy relative to the default center ny/2");
02317 d.put("dz", EMObject::FLOAT,
02318 "Modify mask center by dz relative to the default center nz/2");
02319
02320 return d;
02321 }
02322 protected:
02323 void calc_locals(EMData * image);
02324
02325 bool is_valid() const
02326 {
02327 return (!is_complex);
02328 }
02329
02330 void process_pixel(float *pixel, int xi, int yi, int zi) const
02331 {
02332 float dist = (xi - xc) * (xi - xc) + (yi - yc) * (yi - yc) + (zi - zc) * (zi - zc);
02333 process_dist_pixel(pixel, dist);
02334 }
02335
02336 virtual void process_dist_pixel(float *pixel, float dist) const = 0;
02337
02338 int inner_radius;
02339 int outer_radius;
02340 int inner_radius_square;
02341 int outer_radius_square;
02342 float dx, dy, dz;
02343 float xc, yc, zc;
02344 };
02345
02349 class MaskSharpProcessor:public CircularMaskProcessor
02350 {
02351 public:
02352 MaskSharpProcessor():value(0)
02353 {
02354 }
02355
02356 string get_name() const
02357 {
02358 return NAME;
02359 }
02360 static Processor *NEW()
02361 {
02362 return new MaskSharpProcessor();
02363 }
02364
02365 void set_params(const Dict & new_params)
02366 {
02367 CircularMaskProcessor::set_params(new_params);
02368 value = params.set_default("value",0.0f);
02369 }
02370
02371 TypeDict get_param_types() const
02372 {
02373 TypeDict d = CircularMaskProcessor::get_param_types();
02374 d.put("value", EMObject::FLOAT, "step cutoff to this value. Default is 0.");
02375 return d;
02376 }
02377
02378 string get_desc() const
02379 {
02380 return "step cutoff to a user-given value in both inner and outer circles.";
02381 }
02382
02383 static const string NAME;
02384
02385 protected:
02386 void process_dist_pixel(float *pixel, float dist) const
02387 {
02388 if (dist >= outer_radius_square || dist < inner_radius_square)
02389 {
02390 *pixel = value;
02391 }
02392 }
02393
02394 float value;
02395 };
02396
02397
02401 class MaskEdgeMeanProcessor:public CircularMaskProcessor
02402 {
02403 public:
02404 string get_name() const
02405 {
02406 return NAME;
02407 }
02408 static Processor *NEW()
02409 {
02410 return new MaskEdgeMeanProcessor();
02411 }
02412
02413 void set_params(const Dict & new_params)
02414 {
02415 CircularMaskProcessor::set_params(new_params);
02416 ring_width = params["ring_width"];
02417 if (ring_width == 0) {
02418 ring_width = 1;
02419 }
02420 }
02421
02422 TypeDict get_param_types() const
02423 {
02424 TypeDict d = CircularMaskProcessor::get_param_types();
02425 d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02426 return d;
02427 }
02428
02429 string get_desc() const
02430 {
02431 return "A step cutoff to the the mean value in a ring centered on the outer radius";
02432 }
02433
02434 static const string NAME;
02435
02436 protected:
02437 void calc_locals(EMData * image);
02438
02439
02440 void process_dist_pixel(float *pixel, float dist) const
02441 {
02442 if (dist >= outer_radius_square || dist < inner_radius_square){
02443 *pixel = ring_avg;
02444 }
02445 }
02446
02447 private:
02448 int ring_width;
02449 float ring_avg;
02450 };
02451
02454 class MaskNoiseProcessor:public CircularMaskProcessor
02455 {
02456 public:
02457 string get_name() const
02458 {
02459 return NAME;
02460 }
02461 static Processor *NEW()
02462 {
02463 return new MaskNoiseProcessor();
02464 }
02465
02466 string get_desc() const
02467 {
02468 return "fills masked region";
02469 }
02470
02471 static const string NAME;
02472
02473 protected:
02474 void process_dist_pixel(float *pixel, float dist) const
02475 {
02476 if (dist >= outer_radius_square || dist < inner_radius_square)
02477 {
02478 *pixel = Util::get_gauss_rand(mean, sigma);
02479 }
02480 }
02481 };
02482
02485 class MaskGaussProcessor:public CircularMaskProcessor
02486 {
02487 public:
02488 string get_name() const
02489 {
02490 return NAME;
02491 }
02492 static Processor *NEW()
02493 {
02494 return new MaskGaussProcessor();
02495 }
02496
02497 void set_params(const Dict & new_params)
02498 {
02499 CircularMaskProcessor::set_params(new_params);
02500 exponent = params["exponent"];
02501 if (exponent <= 0.0) {
02502 exponent = 2.0;
02503 }
02504 }
02505
02506 TypeDict get_param_types() const
02507 {
02508 TypeDict d = CircularMaskProcessor::get_param_types();
02509 d.put("exponent", EMObject::FLOAT, "The exponent, f in e^-Bs^f. default 2.0, producing a Gaussian");
02510 return d;
02511 }
02512
02513 string get_desc() const
02514 {
02515 return "a gaussian falloff to zero, radius is the 1/e of the width. If inner_radius>0, then \
02516 outer radius specifies width of Gaussian starting at inner_radius rather than total radius.";
02517 }
02518
02519 static const string NAME;
02520
02521 protected:
02522 float exponent;
02523 void process_dist_pixel(float *pixel, float dist) const
02524 {
02525 if (inner_radius_square>0) {
02526 if (dist>inner_radius_square) {
02527 if (exponent==2.0f) (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,2.0f) / outer_radius_square);
02528 else (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,exponent) / pow((float)outer_radius_square,exponent/2.0f));
02529 }
02530 }
02531 else {
02532 if (exponent==2.0f) (*pixel) *= exp(-dist / outer_radius_square);
02533 else (*pixel) *= exp(-pow(dist,exponent/2.0f) / pow((float)outer_radius_square,exponent/2.0f));
02534 }
02535 }
02536 };
02537
02544 class MaskGaussNonuniformProcessor:public CoordinateProcessor
02545 {
02546 public:
02547 MaskGaussNonuniformProcessor():radius_x(0), radius_y(0), radius_z(0), gauss_width(0)
02548 {
02549 }
02550
02551 void set_params(const Dict & new_params)
02552 {
02553 params = new_params;
02554
02555 if (params.has_key("radius_x")) radius_x=params["radius_x"];
02556 else radius_x=5.0;
02557
02558 if (params.has_key("radius_y")) radius_y=params["radius_y"];
02559 else radius_y=5.0;
02560
02561 if (params.has_key("radius_z")) radius_z=params["radius_z"];
02562 else radius_z=5.0;
02563
02564 if (params.has_key("gauss_width")) gauss_width=params["gauss_width"];
02565 else gauss_width=0.05f;
02566 }
02567
02568 TypeDict get_param_types() const
02569 {
02570 TypeDict d;
02571
02572 d.put("radius_x", EMObject::INT, "x-axis radius");
02573 d.put("radius_y", EMObject::INT, "y-axis radius");
02574 d.put("radius_z", EMObject::INT, "z-axis radius");
02575 d.put("gauss_width", EMObject::FLOAT, "Gaussian falloff width, relative to each radius, default 0.05");
02576
02577 return d;
02578 }
02579
02580 string get_name() const
02581 {
02582 return NAME;
02583 }
02584 static Processor *NEW()
02585 {
02586 return new MaskGaussNonuniformProcessor();
02587 }
02588
02589 string get_desc() const
02590 {
02591 return "A Gaussian falloff to zero. Nonisotropic, specify inner radius for x,y,z and Gaussian falloff width. Falloff \
02592 width is also nonisotropic and relative to the radii, with 1 being equal to the radius on that axis.";
02593 }
02594
02595 static const string NAME;
02596
02597 protected:
02598 void process_pixel(float *pixel, int xi, int yi, int zi) const
02599 {
02600 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);
02601 if (dist>1.0) (*pixel)*=exp(-pow((sqrt(dist)-1.0f)/gauss_width,2.0f));
02602 }
02603
02604 float radius_x,radius_y,radius_z,gauss_width;
02605 };
02606
02611 class MaskGaussInvProcessor:public CircularMaskProcessor
02612 {
02613 public:
02614 TypeDict get_param_types() const
02615 {
02616 TypeDict d = CircularMaskProcessor::get_param_types();
02617 d.put("gauss_width", EMObject::FLOAT, "Used to calculate the constant factor - gauss_width / (ny*ny)" );
02618 d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02619 return d;
02620 }
02621
02622 string get_name() const
02623 {
02624 return NAME;
02625 }
02626
02627 static Processor *NEW()
02628 {
02629 return new MaskGaussInvProcessor();
02630 }
02631
02632 string get_desc() const
02633 {
02634 return "f(x) = f(x) / exp(-radius*radius * gauss_width / (ny*ny))";
02635 }
02636
02637 static const string NAME;
02638
02639 protected:
02640 void calc_locals(EMData *)
02641 {
02642 float gauss_width = params["gauss_width"];
02643 slice_value = gauss_width / (ny * ny);
02644 }
02645
02646 void process_dist_pixel(float *pixel, float dist) const
02647 {
02648 (*pixel) /= exp(-dist * slice_value);
02649 }
02650 private:
02651 float slice_value;
02652 };
02653
02654
02659 class LinearPyramidProcessor:public Processor
02660 {
02661 public:
02662 string get_name() const
02663 {
02664 return NAME;
02665 }
02666
02667 void process_inplace(EMData *image);
02668
02669 static Processor *NEW()
02670 {
02671 return new LinearPyramidProcessor();
02672 }
02673
02674 string get_desc() const
02675 {
02676 return "Multiplies image by a 'linear pyramid', 1-(|x-xsize/2|*|y-ysize/2|*4/(xsize*ysize))";
02677 }
02678
02679 static const string NAME;
02680 };
02681
02682
02685 class MakeRadiusSquaredProcessor:public CircularMaskProcessor
02686 {
02687 public:
02688 string get_name() const
02689 {
02690 return NAME;
02691 }
02692 static Processor *NEW()
02693 {
02694 return new MakeRadiusSquaredProcessor();
02695 }
02696
02697 string get_desc() const
02698 {
02699 return "overwrites input, f(x) = radius * radius";
02700 }
02701
02702 static const string NAME;
02703
02704 protected:
02705 void process_dist_pixel(float *pixel, float dist) const
02706 {
02707 *pixel = dist;
02708 }
02709 };
02710
02713 class MakeRadiusProcessor:public CircularMaskProcessor
02714 {
02715 public:
02716 string get_name() const
02717 {
02718 return NAME;
02719 }
02720 static Processor *NEW()
02721 {
02722 return new MakeRadiusProcessor();
02723 }
02724
02725 string get_desc() const
02726 {
02727 return "overwrites input, f(x) = radius;";
02728 }
02729
02730 static const string NAME;
02731
02732 protected:
02733 void process_dist_pixel(float *pixel, float dist) const
02734 {
02735 *pixel = sqrt(dist);
02736 }
02737 };
02738
02741 class ComplexPixelProcessor:public Processor
02742 {
02743 public:
02744 void process_inplace(EMData * image);
02745
02746 static string get_group_desc()
02747 {
02748 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.";
02749 }
02750
02751 protected:
02752 virtual void process_pixel(float *x) const = 0;
02753 };
02754
02757 class ComplexNormPixel:public ComplexPixelProcessor
02758 {
02759 public:
02760 string get_name() const
02761 {
02762 return NAME;
02763 }
02764 static Processor *NEW()
02765 {
02766 return new ComplexNormPixel();
02767 }
02768
02769 string get_desc() const
02770 {
02771 return "Each Fourier pixel will be normalized. ie - amp=1, phase=unmodified. Useful for performing phase-residual-like computations with dot products.";
02772 }
02773
02774 static const string NAME;
02775
02776 protected:
02777 void process_pixel(float *x) const
02778 {
02779 *x=1.0;
02780 }
02781 };
02782
02786 class AreaProcessor:public Processor
02787 {
02788 public:
02789 AreaProcessor():areasize(0), kernel(0), nx(0), ny(0), nz(0)
02790 {
02791 }
02792
02793 void process_inplace(EMData * image);
02794
02795 void set_params(const Dict & new_params)
02796 {
02797 params = new_params;
02798 areasize = params["areasize"];
02799 }
02800
02801 TypeDict get_param_types() const
02802 {
02803 TypeDict d;
02804 d.put("areasize", EMObject::INT, "The width of the area to process (not radius)");
02805 return d;
02806 }
02807
02808 string get_desc() const
02809 {
02810 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().";
02811 }
02812
02813 protected:
02814 virtual void process_pixel(float *pixel, float, float, float, float *area_matrix) const
02815 {
02816 for (int i = 0; i < matrix_size; i++)
02817 {
02818 *pixel += area_matrix[i] * kernel[i];
02819 }
02820 }
02821
02822 virtual void create_kernel() const = 0;
02823
02824 int areasize;
02825 int matrix_size;
02826 float *kernel;
02827 int nx;
02828 int ny;
02829 int nz;
02830 };
02831
02834 class LaplacianProcessor:public AreaProcessor
02835 {
02836 public:
02837 string get_name() const
02838 {
02839 return NAME;
02840 }
02841 static Processor *NEW()
02842 {
02843 return new LaplacianProcessor();
02844 }
02845
02846 string get_desc() const
02847 {
02848 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).";
02849 }
02850
02851 static const string NAME;
02852
02853 protected:
02854 void create_kernel() const;
02855
02856 };
02857
02860 class ZeroConstantProcessor:public AreaProcessor
02861 {
02862 public:
02863 string get_name() const
02864 {
02865 return NAME;
02866 }
02867 static Processor *NEW()
02868 {
02869 return new ZeroConstantProcessor();
02870 }
02871
02872 string get_desc() const
02873 {
02874 return "Contraction of data, if any nearest neighbor is 0, value -> 0, generally used iteratively";
02875 }
02876
02877 static const string NAME;
02878
02879 protected:
02880 void process_pixel(float *pixel, float, float, float, float *matrix) const
02881 {
02882 if (*pixel != 0)
02883 {
02884 if (*pixel == matrix[1] || *pixel == matrix[3] || *pixel == matrix[5] ||
02885 *pixel == matrix[7] || matrix[1] == 0 || matrix[3] == 0 ||
02886 matrix[5] == 0 || matrix[7] == 0) {
02887 *pixel = 0;
02888 }
02889 }
02890 }
02891
02892 void create_kernel() const
02893 {
02894 }
02895 };
02896
02905 class BoxStatProcessor:public Processor
02906 {
02907 public:
02908 void process_inplace(EMData * image);
02909
02910 static string get_group_desc()
02911 {
02912 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).";
02913 }
02914
02915 TypeDict get_param_types() const
02916 {
02917 TypeDict d;
02918 d.put("radius", EMObject::INT, "The radius of the search box, default is 1 which results in a 3x3 box (3 = 2xradius + 1)");
02919 return d;
02920 }
02921
02922 protected:
02923 virtual void process_pixel(float *pixel, const float *array, int n) const = 0;
02924 };
02925
02926
02929 class BoxMedianProcessor:public BoxStatProcessor
02930 {
02931 public:
02932 string get_name() const
02933 {
02934 return NAME;
02935 }
02936 static Processor *NEW()
02937 {
02938 return new BoxMedianProcessor();
02939 }
02940
02941 string get_desc() const
02942 {
02943 return "A processor for noise reduction. pixel = median of values surrounding pixel.";
02944 }
02945
02946 static const string NAME;
02947
02948 protected:
02949 void process_pixel(float *pixel, const float *array, int n) const
02950 {
02951 float *data = new float[n];
02952 memcpy(data, array, sizeof(float) * n);
02953
02954 for (int i = 0; i <= n / 2; i++)
02955 {
02956 for (int j = i + 1; j < n; j++)
02957 {
02958 if (data[i] < data[j]) {
02959 float t = data[i];
02960 data[i] = data[j];
02961 data[j] = t;
02962 }
02963 }
02964 }
02965
02966 if (n % 2 != 0)
02967 {
02968 *pixel = data[n / 2];
02969 }
02970 else {
02971 *pixel = (data[n / 2] + data[n / 2 - 1]) / 2;
02972 }
02973 if( data )
02974 {
02975 delete[]data;
02976 data = 0;
02977 }
02978 }
02979 };
02980
02983 class BoxSigmaProcessor:public BoxStatProcessor
02984 {
02985 public:
02986 string get_name() const
02987 {
02988 return NAME;
02989 }
02990 static Processor *NEW()
02991 {
02992 return new BoxSigmaProcessor();
02993 }
02994
02995 string get_desc() const
02996 {
02997 return "pixel = standard deviation of values surrounding pixel.";
02998 }
02999
03000 static const string NAME;
03001
03002 protected:
03003 void process_pixel(float *pixel, const float *data, int n) const
03004 {
03005 float sum = 0;
03006 float square_sum = 0;
03007 for (int i = 0; i < n; i++)
03008 {
03009 sum += data[i];
03010 square_sum += data[i] * data[i];
03011 }
03012
03013 float mean = sum / n;
03014 *pixel = sqrt(square_sum / n - mean * mean);
03015 }
03016 };
03017
03020 class BoxMaxProcessor:public BoxStatProcessor
03021 {
03022 public:
03023 string get_name() const
03024 {
03025 return NAME;
03026 }
03027 static Processor *NEW()
03028 {
03029 return new BoxMaxProcessor();
03030 }
03031
03032 string get_desc() const
03033 {
03034 return "peak processor: pixel = max of values surrounding pixel.";
03035 }
03036
03037 static const string NAME;
03038
03039 protected:
03040 void process_pixel(float *pixel, const float *data, int n) const
03041 {
03042 float maxval = -FLT_MAX;
03043 for (int i = 0; i < n; i++)
03044 {
03045 if (data[i] > maxval) {
03046 maxval = data[i];
03047 }
03048 }
03049 *pixel = maxval;
03050 }
03051 };
03052
03055 class MinusPeakProcessor:public BoxStatProcessor
03056 {
03057 public:
03058 string get_name() const
03059 {
03060 return NAME;
03061 }
03062 static Processor *NEW()
03063 {
03064 return new MinusPeakProcessor();
03065 }
03066
03067 string get_desc() const
03068 {
03069 return "peak processor: pixel = pixel - max of values surrounding pixel. This is a sort of positive peak-finding algorithm.";
03070 }
03071
03072 static const string NAME;
03073
03074 protected:
03075 void process_pixel(float *pixel, const float *data, int n) const
03076 {
03077 float maxval = -FLT_MAX;
03078 for (int i = 0; i < n; i++)
03079 {
03080 if (data[i] > maxval) {
03081 maxval = data[i];
03082 }
03083 }
03084 *pixel -= maxval;
03085 }
03086 };
03087
03091 class PeakOnlyProcessor:public BoxStatProcessor
03092 {
03093 public:
03094 string get_name() const
03095 {
03096 return NAME;
03097 }
03098 static Processor *NEW()
03099 {
03100 return new PeakOnlyProcessor();
03101 }
03102 void set_params(const Dict & new_params)
03103 {
03104 params = new_params;
03105 npeaks = params["npeaks"];
03106 if (npeaks == 0) {
03107 npeaks = 1;
03108 }
03109 }
03110
03111 TypeDict get_param_types() const
03112 {
03113 TypeDict d;
03114 d.put("npeaks", EMObject::INT, "the number of surrounding peaks allow to >= pixel values");
03115 return d;
03116 }
03117
03118 string get_desc() const
03119 {
03120 return "peak processor -> if npeaks or more surrounding values >= value, value->0";
03121 }
03122
03123 static const string NAME;
03124
03125 protected:
03126 void process_pixel(float *pixel, const float *data, int n) const
03127 {
03128 int r = 0;
03129
03130 for (int i = 0; i < n; i++)
03131 {
03132 if (data[i] >= *pixel) {
03133 r++;
03134 }
03135 }
03136
03137 if (r > npeaks)
03138 {
03139 *pixel = 0;
03140 }
03141 }
03142 private:
03143 int npeaks;
03144 };
03145
03150 class DiffBlockProcessor:public Processor
03151 {
03152 public:
03153 void process_inplace(EMData * image);
03154
03155 string get_name() const
03156 {
03157 return NAME;
03158 }
03159 static Processor *NEW()
03160 {
03161 return new DiffBlockProcessor();
03162 }
03163
03164 string get_desc() const
03165 {
03166 return "averages over cal_half_width, then sets the value in a local block";
03167 }
03168
03169 TypeDict get_param_types() const
03170 {
03171 TypeDict d;
03172 d.put("cal_half_width", EMObject::FLOAT, "cal_half_width is dx/dy for calculating an average");
03173 d.put("fill_half_width", EMObject::FLOAT, "fill_half_width is dx/dy for fill/step");
03174 return d;
03175 }
03176
03177 static const string NAME;
03178 };
03179
03184 class CutoffBlockProcessor:public Processor
03185 {
03186 public:
03187 void process_inplace(EMData * image);
03188
03189 string get_name() const
03190 {
03191 return NAME;
03192 }
03193 static Processor *NEW()
03194 {
03195 return new CutoffBlockProcessor();
03196 }
03197
03198 TypeDict get_param_types() const
03199 {
03200 TypeDict d;
03201 d.put("value1", EMObject::FLOAT, "val1 is dx/dy");
03202 d.put("value2", EMObject::FLOAT, "val2 is lowpass freq cutoff in pixels");
03203 return d;
03204 }
03205
03206 string get_desc() const
03207 {
03208 return "Block processor, val1 is dx/dy, val2 is lp freq cutoff in pixels. Mystery processor.";
03209 }
03210
03211 static const string NAME;
03212 };
03213
03219 class BooleanShrinkProcessor
03220 {
03221 protected:
03229 template<class LogicOp>
03230 EMData* process(const EMData *const image, Dict& params);
03231
03238 template<class LogicOp>
03239 void process_inplace(EMData * image, Dict& params);
03240
03241 };
03242
03251 class MaxShrinkProcessor:public BooleanShrinkProcessor, public Processor
03252 {
03253 public:
03260 virtual EMData* process(const EMData *const image)
03261 {
03262 return BooleanShrinkProcessor::process<GreaterThan>(image, params);
03263 }
03264
03265
03266 virtual void process_inplace(EMData * image)
03267 {
03268 BooleanShrinkProcessor::process_inplace<GreaterThan>(image, params);
03269 }
03270
03271 string get_desc() const
03272 {
03273 return "Shrink an image by a given amount (default 2), using the maximum value found in the pixel neighborhood.";
03274 }
03275
03276 string get_name() const
03277 {
03278 return NAME;
03279 }
03280 static Processor *NEW()
03281 {
03282 return new MaxShrinkProcessor();
03283 }
03284
03285 TypeDict get_param_types() const
03286 {
03287 TypeDict d;
03288 d.put("n", EMObject::INT, "The shrink factor");
03289 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03290 return d;
03291 }
03292
03293 static const string NAME;
03294
03295 private:
03296 struct GreaterThan
03297 {
03298 inline bool operator()(float left,float right) const { return left > right; }
03299 inline float get_start_val() { return -10000000; }
03300 };
03301 };
03302
03311 class MinShrinkProcessor:public BooleanShrinkProcessor, public Processor
03312 {
03313 public:
03320 virtual EMData* process(const EMData *const image)
03321 {
03322 return BooleanShrinkProcessor::process<LessThan>(image, params);
03323 }
03324
03325
03326 virtual void process_inplace(EMData * image)
03327 {
03328 BooleanShrinkProcessor::process_inplace<LessThan>(image, params);
03329 }
03330 string get_desc() const
03331 {
03332 return "Shrink an image by a given amount (default 2), using the minimum value found in the pixel neighborhood.";
03333 }
03334
03335 string get_name() const
03336 {
03337 return NAME;
03338 }
03339 static Processor *NEW()
03340 {
03341 return new MinShrinkProcessor();
03342 }
03343
03344 TypeDict get_param_types() const
03345 {
03346 TypeDict d;
03347 d.put("n", EMObject::INT, "The shrink factor");
03348 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03349 return d;
03350 }
03351
03352 static const string NAME;
03353
03354 private:
03355 struct LessThan
03356 {
03357 inline bool operator()(float left,float right) const { return left < right; }
03358 inline float get_start_val() { return 9999999999.0f; }
03359 };
03360 };
03361
03368 class MeanShrinkProcessor : public Processor
03369 {
03370 public:
03381 virtual EMData* process(const EMData *const image);
03382
03389 virtual void process_inplace(EMData * image);
03390
03391 string get_desc() const
03392 {
03393 return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
03394 }
03395
03396 virtual string get_name() const
03397 {
03398 return NAME;
03399 }
03400 static Processor *NEW()
03401 {
03402 return new MeanShrinkProcessor();
03403 }
03404
03405 virtual TypeDict get_param_types() const
03406 {
03407 TypeDict d;
03408 d.put("n", EMObject::FLOAT, "The shrink factor");
03409 return d;
03410 }
03411
03412 static const string NAME;
03413
03414 private:
03422 void accrue_mean(EMData* to, const EMData *const from, const int shrinkfactor);
03423
03430 void accrue_mean_one_p_five(EMData* to, const EMData * const from);
03431 };
03432
03433
03440 class MedianShrinkProcessor : public Processor
03441 {
03442 public:
03453 virtual EMData* process(const EMData *const image);
03454
03461 virtual void process_inplace(EMData * image);
03462
03463 string get_desc() const
03464 {
03465 return "Shrink an image by a given amount , using the median value found in the pixel neighborhood.";
03466 }
03467
03468 virtual string get_name() const
03469 {
03470 return NAME;
03471 }
03472 static Processor *NEW()
03473 {
03474 return new MedianShrinkProcessor();
03475 }
03476
03477 virtual TypeDict get_param_types() const
03478 {
03479 TypeDict d;
03480 d.put("n", EMObject::INT, "The shrink factor");
03481 return d;
03482 }
03483
03484 static const string NAME;
03485
03486 private:
03494 void accrue_median(EMData* to, const EMData* const from,const int shrink_factor);
03495 };
03496
03497
03506 class FFTResampleProcessor : public Processor
03507 {
03508 public:
03509 virtual EMData* process(const EMData *const image);
03510
03511 virtual void process_inplace(EMData * image);
03512
03513 string get_desc() const
03514 {
03515 return "Robust resampling of an image by clipping its Fourier transform.";
03516 }
03517
03518 string get_name() const
03519 {
03520 return NAME;
03521 }
03522 static Processor *NEW()
03523 {
03524 return new FFTResampleProcessor();
03525 }
03526
03527 TypeDict get_param_types() const
03528 {
03529 TypeDict d;
03530 d.put("n", EMObject::FLOAT, "The sample rate. Less than one enlarges the image, greater than one shrinks it.");
03531 return d;
03532 }
03533
03534 static const string NAME;
03535
03536 private:
03543 void fft_resample(EMData* to, const EMData *const from, const float& sample_rate);
03544
03545 };
03546
03549 class GradientRemoverProcessor:public Processor
03550 {
03551 public:
03552 void process_inplace(EMData * image);
03553
03554 string get_name() const
03555 {
03556 return NAME;
03557 }
03558 static Processor *NEW()
03559 {
03560 return new GradientRemoverProcessor();
03561 }
03562
03563 string get_desc() const
03564 {
03565 return "Gradient remover, does a rough plane fit to find linear gradients.";
03566 }
03567
03568 static const string NAME;
03569 };
03570
03579 class GradientPlaneRemoverProcessor:public Processor
03580 {
03581 public:
03582 void process_inplace(EMData * image);
03583
03584 string get_name() const
03585 {
03586 return NAME;
03587 }
03588 static Processor *NEW()
03589 {
03590 return new GradientPlaneRemoverProcessor();
03591 }
03592
03593 string get_desc() const
03594 {
03595 return "Remove gradient by least square plane fit";
03596 }
03597
03598 TypeDict get_param_types() const
03599 {
03600 TypeDict d;
03601 d.put("mask", EMObject::EMDATA, "mask object: nonzero pixel positions will be used to fit plane. default = 0");
03602 d.put("changeZero", EMObject::INT, "if zero pixels are modified when removing gradient. default = 0");
03603 d.put("planeParam", EMObject::FLOATARRAY, "fitted plane parameters output");
03604 return d;
03605 }
03606
03607 static const string NAME;
03608 };
03609
03610
03617 class FlattenBackgroundProcessor:public Processor
03618 {
03619 public:
03620 void process_inplace(EMData * image);
03621
03622 string get_name() const
03623 {
03624 return NAME;
03625 }
03626
03627 static Processor *NEW()
03628 {
03629 return new FlattenBackgroundProcessor();
03630 }
03631
03632 string get_desc() const
03633 {
03634 return "Flattens the background by subtracting the local mean";
03635 }
03636
03637 TypeDict get_param_types() const
03638 {
03639 TypeDict d;
03640 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");
03641 d.put("radius", EMObject::INT, "The radius of circle/sphere that defines the local neighborhood. Exclusive of the mask argument");
03642 return d;
03643 }
03644
03645 static const string NAME;
03646 };
03647
03648
03651 class RampProcessor:public Processor
03652 {
03653 public:
03654 void process_inplace(EMData * image);
03655
03656 string get_name() const
03657 {
03658 return NAME;
03659 }
03660 static Processor *NEW()
03661 {
03662 return new RampProcessor();
03663 }
03664
03665 string get_desc() const
03666 {
03667 return "Ramp processor -- Fits a least-squares plane "
03668 "to the picture, and subtracts the plane from "
03669 "the picture. A wedge-shaped overall density "
03670 "profile can thus be removed from the picture.";
03671 }
03672
03673 static const string NAME;
03674 };
03675
03678 class VerticalStripeProcessor:public Processor
03679 {
03680 public:
03681 void process_inplace(EMData * image);
03682
03683 string get_name() const
03684 {
03685 return NAME;
03686 }
03687
03688 static Processor *NEW()
03689 {
03690 return new VerticalStripeProcessor();
03691 }
03692
03693 string get_desc() const
03694 {
03695 return "Tries to fix images scanned on the zeiss for poor ccd normalization.";
03696 }
03697
03698 static const string NAME;
03699 };
03700
03703 class RealToFFTProcessor:public Processor
03704 {
03705 public:
03706 void process_inplace(EMData *image);
03707
03708 string get_name() const
03709 {
03710 return NAME;
03711 }
03712
03713 static Processor *NEW()
03714 {
03715 return new RealToFFTProcessor();
03716 }
03717
03718 string get_desc() const
03719 {
03720 return "This will replace the image with a full-circle 2D fft amplitude rendering. Note that this renders amplitude, when intensity is more common.";
03721 }
03722
03723 static const string NAME;
03724 };
03725
03726
03729 class SigmaZeroEdgeProcessor:public Processor
03730 {
03731 public:
03732 void process_inplace(EMData * image);
03733
03734 string get_name() const
03735 {
03736 return NAME;
03737 }
03738 static Processor *NEW()
03739 {
03740 return new SigmaZeroEdgeProcessor();
03741 }
03742
03743 string get_desc() const
03744 {
03745 return "Fill zeroes at edges with nearest horizontal/vertical value.";
03746 }
03747
03748 static const string NAME;
03749 };
03750
03756 class BeamstopProcessor:public Processor
03757 {
03758 public:
03759 void process_inplace(EMData * image);
03760
03761 string get_name() const
03762 {
03763 return NAME;
03764 }
03765
03766 static Processor *NEW()
03767 {
03768 return new BeamstopProcessor();
03769 }
03770
03771 string get_desc() const
03772 {
03773 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.";
03774 }
03775
03776 TypeDict get_param_types() const
03777 {
03778 TypeDict d;
03779 d.put("value1", EMObject::FLOAT, "sig multiplier");
03780 d.put("value2", EMObject::FLOAT, "x of center");
03781 d.put("value3", EMObject::FLOAT, "y of center");
03782 return d;
03783 }
03784
03785 static const string NAME;
03786 };
03787
03790 class MeanZeroEdgeProcessor:public Processor
03791 {
03792 public:
03793 void process_inplace(EMData * image);
03794
03795 string get_name() const
03796 {
03797 return NAME;
03798 }
03799
03800 static Processor *NEW()
03801 {
03802 return new MeanZeroEdgeProcessor();
03803 }
03804
03805 string get_desc() const
03806 {
03807 return "Fill zeroes at edges with nearest horizontal/vertical value damped towards Mean2.";
03808 }
03809
03810 static const string NAME;
03811 };
03812
03813
03816 class AverageXProcessor:public Processor
03817 {
03818 public:
03819 void process_inplace(EMData * image);
03820
03821 string get_name() const
03822 {
03823 return NAME;
03824 }
03825
03826 static Processor *NEW()
03827 {
03828 return new AverageXProcessor();
03829 }
03830
03831 string get_desc() const
03832 {
03833 return "Average along Y and replace with average";
03834 }
03835
03836 static const string NAME;
03837 };
03838
03842 class DecayEdgeProcessor:public Processor
03843 {
03844 public:
03845 void process_inplace(EMData * image);
03846 string get_name() const
03847 {
03848 return NAME;
03849 }
03850
03851 static Processor *NEW()
03852 {
03853 return new DecayEdgeProcessor();
03854 }
03855
03856 string get_desc() const
03857 {
03858 return "Decay edges of image to zero";
03859 }
03860
03861 TypeDict get_param_types() const
03862 {
03863 TypeDict d;
03864 d.put("width", EMObject::INT, "Width of the decay region around the edge of the image in pixels");
03865 return d;
03866 }
03867
03868 static const string NAME;
03869 };
03870
03877 class ZeroEdgeRowProcessor:public Processor
03878 {
03879 public:
03880 void process_inplace(EMData * image);
03881 string get_name() const
03882 {
03883 return NAME;
03884 }
03885
03886 static Processor *NEW()
03887 {
03888 return new ZeroEdgeRowProcessor();
03889 }
03890
03891 string get_desc() const
03892 {
03893 return "zero edges of image on top and bottom, and on left and right.";
03894 }
03895
03896 TypeDict get_param_types() const
03897 {
03898 TypeDict d;
03899 d.put("x0", EMObject::INT, "The number of columns to zero from left");
03900 d.put("x1", EMObject::INT, "The number of columns to zero from right");
03901 d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
03902 d.put("y1", EMObject::INT, "The number of rows to zero from the top");
03903 return d;
03904 }
03905
03906 static const string NAME;
03907 };
03908
03917 class ZeroEdgePlaneProcessor: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 ZeroEdgePlaneProcessor();
03929 }
03930
03931 string get_desc() const
03932 {
03933 return "zero edges of volume on all sides";
03934 }
03935
03936 TypeDict get_param_types() const
03937 {
03938 TypeDict d;
03939 d.put("x0", EMObject::INT, "The number of columns to zero from left");
03940 d.put("x1", EMObject::INT, "The number of columns to zero from right");
03941 d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
03942 d.put("y1", EMObject::INT, "The number of rows to zero from the top");
03943 d.put("z0", EMObject::INT, "The number of slices to zero from the bottom");
03944 d.put("z1", EMObject::INT, "The number of slices to zero from the top");
03945 return d;
03946 }
03947
03948 static const string NAME;
03949 };
03950
03951
03958 class BilateralProcessor:public Processor
03959 {
03960 public:
03961 void process_inplace(EMData * image);
03962 string get_name() const
03963 {
03964 return NAME;
03965 }
03966
03967 string get_desc() const
03968 {
03969 return "Bilateral processing on 2D or 3D volume data. Bilateral processing does non-linear weighted averaging processing within a certain window. ";
03970 }
03971
03972 static Processor *NEW()
03973 {
03974 return new BilateralProcessor();
03975 }
03976
03977 TypeDict get_param_types() const
03978 {
03979 TypeDict d;
03980 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.");
03981 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.");
03982 d.put("niter", EMObject::INT, "how many times to apply this processing on your data.");
03983 d.put("half_width", EMObject::INT, "processing window size = (2 * half_widthh + 1) ^ 3.");
03984 return d;
03985 }
03986
03987 static const string NAME;
03988 };
03989
03992 class NormalizeProcessor:public Processor
03993 {
03994 public:
03995 void process_inplace(EMData * image);
03996
03997 static string get_group_desc()
03998 {
03999 return "Base class for normalization processors. Each specific normalization processor needs to define how to calculate mean and how to calculate sigma.";
04000 }
04001
04002 protected:
04003 virtual float calc_sigma(EMData * image) const;
04004 virtual float calc_mean(EMData * image) const = 0;
04005 };
04006
04009 class NormalizeUnitProcessor:public NormalizeProcessor
04010 {
04011 public:
04012 string get_name() const
04013 {
04014 return NAME;
04015 }
04016
04017 static Processor *NEW()
04018 {
04019 return new NormalizeUnitProcessor();
04020 }
04021
04022 string get_desc() const
04023 {
04024 return "Normalize an image so its vector length is 1.0.";
04025 }
04026
04027 static const string NAME;
04028
04029 protected:
04030 float calc_sigma(EMData * image) const;
04031 float calc_mean(EMData * image) const;
04032 };
04033
04034 inline float NormalizeUnitProcessor::calc_mean(EMData *) const { return 0; }
04035
04038 class NormalizeUnitSumProcessor:public NormalizeProcessor
04039 {
04040 public:
04041 string get_name() const
04042 {
04043 return NAME;
04044 }
04045
04046 static Processor *NEW()
04047 {
04048 return new NormalizeUnitSumProcessor();
04049 }
04050
04051 string get_desc() const
04052 {
04053 return "Normalize an image so its elements sum to 1.0 (fails if mean=0)";
04054 }
04055
04056 static const string NAME;
04057
04058 protected:
04059 float calc_sigma(EMData * image) const;
04060 float calc_mean(EMData * image) const;
04061 };
04062
04063 inline float NormalizeUnitSumProcessor::calc_mean(EMData *) const { return 0; }
04064
04065
04068 class NormalizeStdProcessor:public NormalizeProcessor
04069 {
04070 public:
04071 string get_name() const
04072 {
04073 return NAME;
04074 }
04075
04076 static Processor *NEW()
04077 {
04078 return new NormalizeStdProcessor();
04079 }
04080
04081 string get_desc() const
04082 {
04083 return "do a standard normalization on an image.";
04084 }
04085
04086 static const string NAME;
04087
04088 protected:
04089 float calc_mean(EMData * image) const;
04090 };
04091
04096 class NormalizeMaskProcessor:public NormalizeProcessor
04097 {
04098 public:
04099 string get_name() const
04100 {
04101 return NAME;
04102 }
04103
04104 string get_desc() const
04105 {
04106 return "Uses a 1/0 mask defining a region to use for the zero-normalization.if no_sigma is 1, standard deviation not modified.";
04107 }
04108
04109 static Processor *NEW()
04110 {
04111 return new NormalizeMaskProcessor();
04112 }
04113
04114 TypeDict get_param_types() const
04115 {
04116 TypeDict d;
04117 d.put("mask", EMObject::EMDATA, "the 1/0 mask defining a region to use for the zero-normalization");
04118 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");
04119 return d;
04120 }
04121
04122 static const string NAME;
04123
04124 protected:
04125 float calc_sigma(EMData * image) const;
04126 float calc_mean(EMData * image) const;
04127 };
04128
04134 class NormalizeRampNormVar: public Processor
04135 {
04136 public:
04137 string get_name() const
04138 {
04139 return NAME;
04140 }
04141
04142 static Processor *NEW()
04143 {
04144 return new NormalizeRampNormVar();
04145 }
04146
04147 string get_desc() const
04148 {
04149 return "First call filter.ramp on the image, then make the mean 0 and norm 1";
04150 }
04151
04152 void process_inplace(EMData * image);
04153
04154 static const string NAME;
04155 };
04156
04165 class NormalizeByMassProcessor: public Processor
04166 {
04167 public:
04168 string get_name() const
04169 {
04170 return NAME;
04171 }
04172
04173 static Processor *NEW()
04174 {
04175 return new NormalizeByMassProcessor();
04176 }
04177
04178 string get_desc() const
04179 {
04180 return "Normalize the mass of the image assuming a density of 1.35 g/ml (0.81 Da/A^3) (3D only)";
04181 }
04182
04183 TypeDict get_param_types() const
04184 {
04185 TypeDict d;
04186 d.put("apix", EMObject::FLOAT,"Angstrom per pixel of the image. If not set will use the apix_x attribute of the image");
04187 d.put("mass", EMObject::FLOAT,"The approximate mass of protein/structure in kilodaltons");
04188 d.put("thr", EMObject::FLOAT,"The isosurface threshold which encapsulates the structure");
04189 return d;
04190 }
04191
04192 void process_inplace(EMData * image);
04193
04194 static const string NAME;
04195 };
04196
04197
04200 class NormalizeEdgeMeanProcessor:public NormalizeProcessor
04201 {
04202 public:
04203 string get_name() const
04204 {
04205 return NAME;
04206 }
04207
04208 static Processor *NEW()
04209 {
04210 return new NormalizeEdgeMeanProcessor();
04211 }
04212
04213 string get_desc() const
04214 {
04215 return "normalizes an image, mean value equals to edge mean.";
04216 }
04217
04218 static const string NAME;
04219
04220 protected:
04221 float calc_mean(EMData * image) const;
04222 };
04223
04226 class NormalizeCircleMeanProcessor:public NormalizeProcessor
04227 {
04228 public:
04229 string get_name() const
04230 {
04231 return NAME;
04232 }
04233
04234 static Processor *NEW()
04235 {
04236 return new NormalizeCircleMeanProcessor();
04237 }
04238
04239 string get_desc() const
04240 {
04241 return "normalizes an image, mean value equals to mean of 2 pixel circular border.";
04242 }
04243
04244 static const string NAME;
04245
04246 protected:
04247 float calc_mean(EMData * image) const;
04248 };
04249
04252 class NormalizeLREdgeMeanProcessor:public NormalizeProcessor
04253 {
04254 public:
04255 string get_name() const
04256 {
04257 return NAME;
04258 }
04259
04260 static Processor *NEW()
04261 {
04262 return new NormalizeLREdgeMeanProcessor();
04263 }
04264
04265 string get_desc() const
04266 {
04267 return "normalizes an image, uses 2 pixels on left and right edge";
04268 }
04269
04270 static const string NAME;
04271
04272 protected:
04273 float calc_mean(EMData * image) const;
04274 };
04275
04278 class NormalizeMaxMinProcessor:public NormalizeProcessor
04279 {
04280 public:
04281 string get_name() const
04282 {
04283 return NAME;
04284 }
04285
04286 static Processor *NEW()
04287 {
04288 return new NormalizeMaxMinProcessor();
04289 }
04290
04291 string get_desc() const
04292 {
04293 return "normalizes an image. mean -> (maxval-minval)/2; std dev = (maxval+minval)/2;";
04294 }
04295
04296 static const string NAME;
04297
04298 protected:
04299 float calc_sigma(EMData * image) const;
04300 float calc_mean(EMData * image) const;
04301 };
04302
04305 class NormalizeRowProcessor:public Processor
04306 {
04307 public:
04308 string get_name() const
04309 {
04310 return NAME;
04311 }
04312
04313 static Processor *NEW()
04314 {
04315 return new NormalizeRowProcessor();
04316 }
04317
04318 string get_desc() const
04319 {
04320 return "normalizes each row in the image individually";
04321 }
04322
04323 static const string NAME;
04324
04325 void process_inplace(EMData * image);
04326 };
04327
04333 class NormalizeToLeastSquareProcessor:public Processor
04334 {
04335 public:
04336 void process_inplace(EMData * image);
04337
04338 string get_name() const
04339 {
04340 return NAME;
04341 }
04342
04343 static Processor *NEW()
04344 {
04345 return new NormalizeToLeastSquareProcessor();
04346 }
04347
04348 TypeDict get_param_types() const
04349 {
04350 TypeDict d;
04351 d.put("to", EMObject::EMDATA, "reference image normalize to");
04352 d.put("ignore_zero", EMObject::BOOL, "If set, ignores any pixels which are exactly zero in either image. Defaut = True.");
04353 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)");
04354 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)");
04355 return d;
04356 }
04357
04358 string get_desc() const
04359 {
04360 return "use least square method to normalize";
04361 }
04362
04363 static const string NAME;
04364 };
04365
04368 class RotationalAverageProcessor:public Processor
04369 {
04370 public:
04371 void process_inplace(EMData * image);
04372
04373 string get_name() const
04374 {
04375 return NAME;
04376 }
04377
04378 static Processor *NEW()
04379 {
04380 return new RotationalAverageProcessor();
04381 }
04382
04383 string get_desc() const
04384 {
04385 return "Makes image circularly/spherically symmetric.";
04386 }
04387
04388 static const string NAME;
04389 };
04390
04393 class RotationalSubstractProcessor:public Processor
04394 {
04395 public:
04396 virtual void process_inplace(EMData * image);
04397
04398 virtual string get_name() const
04399 {
04400 return NAME;
04401 }
04402
04403 static Processor *NEW()
04404 {
04405 return new RotationalSubstractProcessor();
04406 }
04407
04408 virtual string get_desc() const
04409 {
04410 return "subtracts circularly/spherically symmetric part of an image.";
04411 }
04412
04413 static const string NAME;
04414 };
04415
04421 class TransposeProcessor:public Processor
04422 {
04423 public:
04424
04429 virtual void process_inplace(EMData * image);
04430
04435 virtual EMData* process(const EMData * const image);
04436
04437 virtual string get_name() const
04438 {
04439 return NAME;
04440 }
04441
04442 static Processor *NEW()
04443 {
04444 return new TransposeProcessor();
04445 }
04446
04447 virtual TypeDict get_param_types() const
04448 {
04449 TypeDict d;
04450 return d;
04451 }
04452
04453 virtual string get_desc() const
04454 {
04455 return "Get the transpose of an image. Works for 2D only";
04456 }
04457
04458 static const string NAME;
04459 };
04460
04461
04465 class FlipProcessor:public Processor
04466 {
04467 public:
04468 virtual void process_inplace(EMData * image);
04469
04470 virtual string get_name() const
04471 {
04472 return NAME;
04473 }
04474
04475 static Processor *NEW()
04476 {
04477 return new FlipProcessor();
04478 }
04479
04480 virtual TypeDict get_param_types() const
04481 {
04482 TypeDict d;
04483 d.put("axis", EMObject::STRING, "'x', 'y', or 'z' axis. 'x' means horizonal flip; 'y' means vertical flip;");
04484 return d;
04485 }
04486
04487 virtual string get_desc() const
04488 {
04489 return "flip an image around an axis.";
04490 }
04491
04492 static const string NAME;
04493 };
04494
04495
04496
04497
04498
04499
04500
04501
04502
04503
04504
04505
04506
04507
04508
04509
04510
04511
04512
04513
04514
04515
04516
04517
04518
04519
04520
04521
04522
04523
04528 class AddNoiseProcessor:public Processor
04529 {
04530 public:
04531 virtual void process_inplace(EMData * image);
04532
04533 virtual string get_name() const
04534 {
04535 return NAME;
04536 }
04537
04538 static Processor *NEW()
04539 {
04540 return new AddNoiseProcessor();
04541 }
04542
04543 virtual TypeDict get_param_types() const
04544 {
04545 TypeDict d;
04546 d.put("noise", EMObject::FLOAT, "noise factor used to generate Gaussian distribution random noise");
04547 d.put("seed", EMObject::INT, "seed for random number generator");
04548 return d;
04549 }
04550
04551 virtual string get_desc() const
04552 {
04553 return "add noise to an image, image multiply by noise then add a random value";
04554 }
04555
04556 static const string NAME;
04557
04558 protected:
04559 virtual float get_sigma(EMData *)
04560 {
04561 return 1.0;
04562 }
04563 };
04564
04567 class AddSigmaNoiseProcessor:public AddNoiseProcessor
04568 {
04569 public:
04570 virtual string get_name() const
04571 {
04572 return NAME;
04573 }
04574
04575 static Processor *NEW()
04576 {
04577 return new AddSigmaNoiseProcessor();
04578 }
04579
04580 virtual string get_desc() const
04581 {
04582 return "add sigma noise.";
04583 }
04584
04585 static const string NAME;
04586
04587 protected:
04588 float get_sigma(EMData * image);
04589 };
04590
04599 class AddRandomNoiseProcessor:public Processor
04600 {
04601 public:
04602 virtual void process_inplace(EMData * image);
04603
04604 virtual string get_name() const
04605 {
04606 return NAME;
04607 }
04608
04609 static Processor *NEW()
04610 {
04611 return new AddRandomNoiseProcessor();
04612 }
04613
04614 virtual TypeDict get_param_types() const
04615 {
04616 TypeDict d;
04617 d.put("n", EMObject::INT);
04618 d.put("x0", EMObject::FLOAT);
04619 d.put("dx", EMObject::FLOAT);
04620 d.put("y", EMObject::FLOATARRAY);
04621 d.put("interpolation", EMObject::INT);
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 spectral noise to a complex image.";
04629 }
04630
04631 static const string NAME;
04632 };
04633
04639 class FourierToCornerProcessor:public Processor
04640 {
04641 public:
04647 virtual void process_inplace(EMData * image);
04648
04649 virtual string get_name() const
04650 {
04651 return NAME;
04652 }
04653
04654 static Processor *NEW()
04655 {
04656 return new FourierToCornerProcessor();
04657 }
04658
04659 virtual string get_desc() const
04660 {
04661 return "Undoes the xform.fourierorigin.tocenter processor";
04662 }
04663
04664 static const string NAME;
04665 };
04666
04667
04679 class FourierToCenterProcessor:public Processor
04680 {
04681 public:
04687 virtual void process_inplace(EMData * image);
04688
04689 virtual string get_name() const
04690 {
04691 return NAME;
04692 }
04693
04694 static Processor *NEW()
04695 {
04696 return new FourierToCenterProcessor();
04697 }
04698
04699 virtual string get_desc() const
04700 {
04701 return "Translates the origin in Fourier space from the corner to the center in y and z - works in 2D and 3D";
04702 }
04703
04704 static const string NAME;
04705 };
04706
04716 class Phase180Processor:public Processor
04717 {
04718 protected:
04731 void swap_corners_180(EMData * image);
04732
04744 void swap_central_slices_180(EMData * image);
04745
04752 void fourier_phaseshift180(EMData * image);
04753
04754 };
04755
04765 class PhaseToCenterProcessor:public Phase180Processor
04766 {
04767 public:
04768 virtual void process_inplace(EMData * image);
04769
04770 virtual string get_name() const
04771 {
04772 return NAME;
04773 }
04774
04775 static Processor *NEW()
04776 {
04777 return new PhaseToCenterProcessor();
04778 }
04779
04780 virtual string get_desc() const
04781 {
04782 return "Undoes the effect of the xform.phaseorigin.tocorner processor";
04783 }
04784
04785 static const string NAME;
04786 };
04787
04795 class PhaseToCornerProcessor:public Phase180Processor
04796 {
04797 public:
04798 virtual void process_inplace(EMData * image);
04799
04800 virtual string get_name() const
04801 {
04802 return NAME;
04803 }
04804
04805 static Processor *NEW()
04806 {
04807 return new PhaseToCornerProcessor();
04808 }
04809
04810 virtual string get_desc() const
04811 {
04812 return "Translates a centered image to the corner in a forward fashion";
04813 }
04814
04815 static const string NAME;
04816 };
04817
04822 class AutoMask2DProcessor:public Processor
04823 {
04824 public:
04825 virtual void process_inplace(EMData * image);
04826
04827 virtual string get_name() const
04828 {
04829 return NAME;
04830 }
04831
04832 static Processor *NEW()
04833 {
04834 return new AutoMask2DProcessor();
04835 }
04836
04837 virtual TypeDict get_param_types() const
04838 {
04839 TypeDict d;
04840 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
04841 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
04842 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
04843 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
04844 d.put("nshells", EMObject::INT, "The number of dilation operations");
04845 d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
04846 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
04847 d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
04848 return d;
04849 }
04850
04851 virtual string get_desc() const
04852 {
04853 return "2D version of mask.auto3d";
04854 }
04855
04856 static const string NAME;
04857 };
04858
04859
04866 class AutoMaskAsymUnit:public Processor
04867 {
04868 public:
04869 virtual void process_inplace(EMData * image);
04870
04871 virtual string get_name() const
04872 {
04873 return NAME;
04874 }
04875
04876 static Processor *NEW()
04877 {
04878 return new AutoMaskAsymUnit();
04879 }
04880
04881 virtual TypeDict get_param_types() const
04882 {
04883 TypeDict d;
04884 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.");
04885 d.put("sym", EMObject::STRING, "The symmetry, for example, d7");
04886 return d;
04887 }
04888
04889 virtual string get_desc() const
04890 {
04891 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.";
04892 }
04893
04894 static const string NAME;
04895 };
04896
04901 class AutoMask3DProcessor:public Processor
04902 {
04903 public:
04904 virtual void process_inplace(EMData * image);
04905
04906 virtual string get_name() const
04907 {
04908 return NAME;
04909 }
04910
04911 static Processor *NEW()
04912 {
04913 return new AutoMask3DProcessor();
04914 }
04915
04916 virtual TypeDict get_param_types() const
04917 {
04918 TypeDict d;
04919 d.put("threshold1", EMObject::FLOAT);
04920 d.put("threshold2", EMObject::FLOAT);
04921 return d;
04922 }
04923
04924 virtual string get_desc() const
04925 {
04926 return "Tries to mask out only interesting density";
04927 }
04928
04929 static void search_nearby(float *dat, float *dat2, int nx, int ny, int nz, float thr);
04930 static void fill_nearby(float *dat2, int nx, int ny, int nz);
04931
04932 static const string NAME;
04933 };
04934
04942 class AutoMask3D2Processor:public Processor
04943 {
04944 public:
04945 virtual void process_inplace(EMData * image);
04946
04947 virtual string get_name() const
04948 {
04949 return NAME;
04950 }
04951
04952 static Processor *NEW()
04953 {
04954 return new AutoMask3D2Processor();
04955 }
04956
04957 virtual string get_desc() const
04958 {
04959 return "Tries to mask out only interesting density using something akin to a flood file approach.";
04960 }
04961
04962 virtual TypeDict get_param_types() const
04963 {
04964 TypeDict d;
04965 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
04966 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
04967 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
04968 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
04969 d.put("nshells", EMObject::INT, "The number of dilation operations");
04970 d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
04971 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
04972 d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
04973 return d;
04974 }
04975
04976 static const string NAME;
04977 };
04978
04982 class AddMaskShellProcessor:public Processor
04983 {
04984 public:
04985 virtual void process_inplace(EMData * image);
04986
04987 virtual string get_name() const
04988 {
04989 return NAME;
04990 }
04991
04992 virtual string get_desc() const
04993 {
04994 return "Add additional shells/rings to an existing 1/0 mask image";
04995 }
04996
04997 static Processor *NEW()
04998 {
04999 return new AddMaskShellProcessor();
05000 }
05001
05002 virtual TypeDict get_param_types() const
05003 {
05004 TypeDict d;
05005 d.put("nshells", EMObject::INT, "number of shells to add");
05006 return d;
05007 }
05008
05009 static const string NAME;
05010 };
05011
05016 class PhaseToMassCenterProcessor:public Processor
05017 {
05018 public:
05019 virtual void process_inplace(EMData * image);
05020
05021 virtual string get_name() const
05022 {
05023 return NAME;
05024 }
05025
05026 static Processor *NEW()
05027 {
05028 return new PhaseToMassCenterProcessor();
05029 }
05030
05031 virtual string get_desc() const
05032 {
05033 return "centers the image the center of mass, which is calculated using Fourier phases, ignores old dx, dy.";
05034 }
05035
05036 virtual TypeDict get_param_types() const
05037 {
05038 TypeDict d;
05039 d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05040 return d;
05041 }
05042
05043 static const string NAME;
05044 };
05045
05050 class ToMassCenterProcessor:public Processor
05051 {
05052 public:
05053 virtual void process_inplace(EMData * image);
05054
05055 virtual string get_name() const
05056 {
05057 return NAME;
05058 }
05059
05060 static Processor *NEW()
05061 {
05062 return new ToMassCenterProcessor();
05063 }
05064
05065 virtual string get_desc() const
05066 {
05067 return "ToMassCenterProcessor centers image at center of mass, with a threshold. Only values higher than the threshold are considered.";
05068 }
05069
05070 virtual TypeDict get_param_types() const
05071 {
05072 TypeDict d;
05073 d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05074 d.put("threshold", EMObject::FLOAT, "Only values larger than the threshold are included in the center of mass computation. Default is 0.");
05075
05076 return d;
05077 }
05078
05079 static const string NAME;
05080 };
05081
05085 class ACFCenterProcessor:public Processor
05086 {
05087 public:
05088 virtual void process_inplace(EMData * image);
05089
05090 virtual string get_name() const
05091 {
05092 return NAME;
05093 }
05094
05095 static Processor *NEW()
05096 {
05097 return new ACFCenterProcessor();
05098 }
05099
05100 virtual string get_desc() const
05101 {
05102 return "Center image using self-convolution.";
05103 }
05104
05105 virtual TypeDict get_param_types() const
05106 {
05107 TypeDict d;
05108 return d;
05109 }
05110
05111 static const string NAME;
05112 };
05113
05118 class SNRProcessor:public Processor
05119 {
05120 public:
05121 virtual void process_inplace(EMData * image);
05122
05123 virtual string get_name() const
05124 {
05125 return NAME;
05126 }
05127
05128 static Processor *NEW()
05129 {
05130 return new SNRProcessor();
05131 }
05132
05133 virtual string get_desc() const
05134 {
05135 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.";
05136 }
05137
05138 virtual TypeDict get_param_types() const
05139 {
05140 TypeDict d;
05141 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");
05142 d.put("snrfile", EMObject::STRING, "structure factor file name");
05143 return d;
05144 }
05145
05146 static const string NAME;
05147 };
05148
05152 class FileFourierProcessor:public Processor
05153 {
05154 public:
05155 virtual void process_inplace(EMData * image);
05156
05157 virtual string get_name() const
05158 {
05159 return NAME;
05160 }
05161
05162 virtual string get_desc() const
05163 {
05164 return "A fourier processor specified in a 2 column text file.";
05165 }
05166
05167 static Processor *NEW()
05168 {
05169 return new FileFourierProcessor();
05170 }
05171
05172 virtual TypeDict get_param_types() const
05173 {
05174 TypeDict d;
05175 d.put("filename", EMObject::STRING, "file name for a 2 column text file which specified a radial function data array.");
05176 return d;
05177 }
05178
05179 static const string NAME;
05180 };
05181
05192 class SymSearchProcessor: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 virtual string get_desc() const
05203 {
05204 return "Identifiy the best symmetry in the given symmetry list for each pixel and then apply the best symmetry to each pixel.";
05205 }
05206
05207 static Processor *NEW()
05208 {
05209 return new SymSearchProcessor();
05210 }
05211
05212 virtual TypeDict get_param_types() const
05213 {
05214 TypeDict d;
05215 d.put("sym", EMObject::STRINGARRAY, "the list of symmetries to search");
05216 d.put("thresh", EMObject::FLOAT, "the minimal level of symmetry to be accepted (0-1)");
05217 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");
05218 d.put("symlabel_map", EMObject::EMDATA, "the optional return map when output_symlabel=1");
05219 return d;
05220 }
05221
05222 static const string NAME;
05223 };
05224
05230 class LocalNormProcessor:public Processor
05231 {
05232 public:
05233 void process_inplace(EMData * image);
05234
05235 virtual string get_name() const
05236 {
05237 return NAME;
05238 }
05239
05240 static Processor *NEW()
05241 {
05242 return new LocalNormProcessor();
05243 }
05244
05245 virtual string get_desc() const
05246 {
05247 return "This processor attempts to perform a 'local normalization' so low density and high density features will be on a more even playing field in an isosurface display. threshold is an isosurface threshold at which all desired features are visible, radius is a feature size over which to equalize.";
05248 }
05249
05250 virtual TypeDict get_param_types() const
05251 {
05252 TypeDict d;
05253 d.put("threshold", EMObject::FLOAT, "an isosurface threshold at which all desired features are visible");
05254 d.put("radius", EMObject::FLOAT, "a normalization size similar to an lp= value");
05255 d.put("apix", EMObject::FLOAT, "Angstrom per pixel ratio");
05256 return d;
05257 }
05258
05259 static const string NAME;
05260 };
05261
05266 class IndexMaskFileProcessor: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 static Processor *NEW()
05277 {
05278 return new IndexMaskFileProcessor();
05279 }
05280
05281 virtual TypeDict get_param_types() const
05282 {
05283 TypeDict d;
05284 d.put("filename", EMObject::STRING, "mask image file name");
05285 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");
05286 return d;
05287 }
05288
05289 virtual string get_desc() const
05290 {
05291 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.";
05292 }
05293
05294 static const string NAME;
05295 };
05296
05300 class CoordinateMaskFileProcessor:public Processor
05301 {
05302 public:
05303 virtual void process_inplace(EMData * image);
05304
05305 virtual string get_name() const
05306 {
05307 return NAME;
05308 }
05309
05310 static Processor *NEW()
05311 {
05312 return new CoordinateMaskFileProcessor();
05313 }
05314
05315 virtual string get_desc() const
05316 {
05317 return "Multiplies the image by the specified file using pixel coordinates instead of pixel indices. The images can be different size.";
05318 }
05319
05320 virtual TypeDict get_param_types() const
05321 {
05322 TypeDict d;
05323 d.put("filename", EMObject::STRING, "mask image file name");
05324 return d;
05325 }
05326
05327 static const string NAME;
05328 };
05329
05340 class PaintProcessor:public Processor
05341 {
05342 public:
05343 PaintProcessor():x(0), y(0), z(0),r1(0), v1(0.0), r2(0), v2(0.0)
05344 {
05345 }
05346
05347 virtual string get_name() const
05348 {
05349 return NAME;
05350 }
05351
05352 static Processor *NEW()
05353 {
05354 return new PaintProcessor();
05355 }
05356
05357 virtual string get_desc() const
05358 {
05359 return "Paints a circle with a decaying edge into the image. r<r1 -> v1, r1<r<r2 -> (v1,v2), r>r2 unchanged";
05360 }
05361
05362 virtual TypeDict get_param_types() const
05363 {
05364 TypeDict d;
05365 d.put("x", EMObject::INT, "x coordinate for Center of circle");
05366 d.put("y", EMObject::INT, "y coordinate for Center of circle");
05367 d.put("z", EMObject::INT, "z coordinate for Center of circle");
05368 d.put("r1", EMObject::INT, "Inner radius");
05369 d.put("v1", EMObject::FLOAT, "Inner value");
05370 d.put("r2", EMObject::INT, "Outter radius");
05371 d.put("v2", EMObject::FLOAT, "Outer Value");
05372 return d;
05373 }
05374
05375 virtual void set_params(const Dict & new_params)
05376 {
05377 params = new_params;
05378
05379 if (params.has_key("x")) x = params["x"];
05380 if (params.has_key("y")) y = params["y"];
05381 if (params.has_key("z")) z = params["z"];
05382 if (params.has_key("r1")) r1 = params["r1"];
05383 if (params.has_key("r2")) r2 = params["r2"];
05384 if (params.has_key("v1")) v1 = params["v1"];
05385 if (params.has_key("v2")) v2 = params["v2"];
05386 }
05387
05388 static const string NAME;
05389
05390 protected:
05391 virtual void process_inplace(EMData *image);
05392
05393 int x,y,z,r1;
05394 float v1;
05395 int r2;
05396 float v2;
05397
05398 };
05399
05400
05405 class DirectionalSumProcessor : public Processor
05406 {
05407 public:
05408 virtual string get_name() const
05409 {
05410 return NAME;
05411 }
05412
05413 static Processor *NEW()
05414 {
05415 return new DirectionalSumProcessor();
05416 }
05417
05421 virtual EMData* process(const EMData* const image);
05422
05426 virtual void process_inplace(EMData*) {
05427 throw InvalidCallException("The directional sum processor does not work inplace");
05428 }
05429
05430 virtual TypeDict get_param_types() const
05431 {
05432 TypeDict d;
05433 d.put("axis", EMObject::STRING,"The direction of the sum, either x,y or z. Returned axes are xy, xz or zy.");
05434 d.put("first", EMObject::INT,"The first position along the speficied axis to use in the sum. Neg val -> nx/y/z+first (default=0)");
05435 d.put("last", EMObject::INT,"The last position along the speficied axis to use in the sum. Neg val -> nx/y/z+last (default=-1)");
05436 return d;
05437 }
05438
05439 string get_desc() const
05440 {
05441 return "Calculates the projection of the image along one of the axial directions, either x, y or z";
05442 }
05443
05444 static const string NAME;
05445 };
05446
05454 class WatershedProcessor:public Processor
05455 {
05456 public:
05457 virtual void process_inplace(EMData * image);
05458
05459 virtual string get_name() const
05460 {
05461 return NAME;
05462 }
05463
05464 static Processor *NEW()
05465 {
05466 return new WatershedProcessor();
05467 }
05468
05469 virtual string get_desc() const
05470 {
05471 return "Does a watershed";
05472 }
05473
05474 virtual TypeDict get_param_types() const
05475 {
05476 TypeDict d;
05477 d.put("xpoints", EMObject::FLOATARRAY,"x coordinates");
05478 d.put("ypoints", EMObject::FLOATARRAY,"y coordinates");
05479 d.put("zpoints", EMObject::FLOATARRAY,"z coordinates");
05480 d.put("minval", EMObject::FLOAT,"min value");
05481 return d;
05482 }
05483
05484 static const string NAME;
05485
05486 private:
05487 vector<Vec3i > watershed(EMData* mask, EMData* image, const float& threshold, const Vec3i& cordinate, const int mask_value);
05488 vector<Vec3i > find_region(EMData* mask,const vector<Vec3i >& coords, const int mask_value, vector<Vec3i >& region);
05489
05490 };
05491
05501 template<class Type>
05502 class BinaryOperateProcessor : public Processor{
05503 public:
05508 virtual void process_inplace(EMData * image) {
05509 if ( ! params.has_key("with") ) throw InvalidParameterException("You must supply the \"with\" parameter");
05510 EMData* with = params["with"];
05511
05512 if ( with->get_xsize() != image->get_xsize() || with->get_ysize() != image->get_ysize() || with->get_zsize() != image->get_zsize() )
05513 throw ImageDimensionException("The images you are operating on do not have the same dimensions");
05514
05515 float* image_data = image->get_data();
05516 float* with_data = with->get_data();
05517
05518 std::transform(image_data,image_data+image->get_size(),with_data,image_data,Type::binary_operate);
05519 image->update();
05520 }
05521
05522 virtual string get_name() const
05523 {
05524 return op.get_name();
05525 }
05526
05527 virtual string get_desc() const
05528 {
05529 return op.get_desc();
05530 }
05531
05532 static Processor *NEW()
05533 {
05534 return new BinaryOperateProcessor<Type>();
05535 }
05536
05537 virtual TypeDict get_param_types() const
05538 {
05539 TypeDict d;
05540 d.put("with", EMObject::EMDATA,"The second image");
05541 return d;
05542 }
05543
05544 static const string NAME;
05545 private:
05546 Type op;
05547 };
05548
05549 class MaxPixelOperator {
05550 public:
05551 string get_name() const
05552 {
05553 return NAME;
05554 }
05555
05556 string get_desc() const
05557 {
05558 return "Compares pixels in two images, returning an image with the maximum pixel value in each pixel location";
05559 }
05560
05561 static float binary_operate(const float& left, const float& right) {
05562 if (left > right) return left;
05563 return right;
05564 }
05565
05566 static const string NAME;
05567 };
05568
05569 class MinPixelOperator {
05570 public:
05571 string get_name() const
05572 {
05573 return NAME;
05574 }
05575
05576 string get_desc() const
05577 {
05578 return "Compares pixels in two images, returning an image with the minimum pixel value in each pixel location";
05579 }
05580
05581 static float binary_operate(const float& left, const float& right) {
05582 if (left < right) return left;
05583 return right;
05584 }
05585
05586 static const string NAME;
05587 };
05588
05592 class MatchSFProcessor:public FourierAnlProcessor
05593 {
05594 public:
05595
05596 virtual string get_name() const
05597 {
05598 return NAME;
05599 }
05600
05601 virtual string get_desc() const
05602 {
05603 return "Filters the image so its 1-D power spectrum matches a second image";
05604 }
05605
05606 static Processor *NEW()
05607 {
05608 return new MatchSFProcessor();
05609 }
05610
05611 virtual TypeDict get_param_types() const
05612 {
05613 TypeDict d;
05614 d.put("to", EMObject::EMDATA, "The image to match with. Make sure apix values are correct.");
05615 return d;
05616 }
05617
05618 static const string NAME;
05619
05620 protected:
05621 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05622 };
05623
05624
05629 class SetSFProcessor:public FourierAnlProcessor
05630 {
05631 public:
05632
05633 virtual string get_name() const
05634 {
05635 return NAME;
05636 }
05637
05638 virtual string get_desc() const
05639 {
05640 return "Filters the image so its 1-D power spectrum matches a supplied X-Y curve";
05641 }
05642
05643 static Processor *NEW()
05644 {
05645 return new SetSFProcessor();
05646 }
05647
05648 virtual TypeDict get_param_types() const
05649 {
05650 TypeDict d;
05651 d.put("strucfac", EMObject::XYDATA, "An XYData object contaning the curve to be imposed as a function of S");
05652 d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
05653 return d;
05654 }
05655
05656 static const string NAME;
05657
05658 protected:
05659 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05660 };
05661
05665 class SmartMaskProcessor:public Processor
05666 {
05667 public:
05668 virtual void process_inplace(EMData * image);
05669
05670 virtual string get_name() const
05671 {
05672 return NAME;
05673 }
05674
05675 static Processor *NEW()
05676 {
05677 return new SmartMaskProcessor();
05678 }
05679
05680 virtual string get_desc() const
05681 {
05682 return "Smart mask processor.";
05683 }
05684
05685 virtual TypeDict get_param_types() const
05686 {
05687 TypeDict d;
05688 d.put("mask", EMObject::FLOAT, "mask value");
05689 return d;
05690 }
05691
05692 static const string NAME;
05693 };
05694
05699 class IterBinMaskProcessor:public Processor
05700 {
05701 public:
05702 virtual void process_inplace(EMData * image);
05703
05704 virtual string get_name() const
05705 {
05706 return NAME;
05707 }
05708
05709 virtual string get_desc() const
05710 {
05711 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.";
05712 }
05713
05714 static Processor *NEW()
05715 {
05716 return new IterBinMaskProcessor();
05717 }
05718
05719 virtual TypeDict get_param_types() const
05720 {
05721 TypeDict d;
05722 d.put("val1", EMObject::FLOAT, "number of pixels to expand");
05723 d.put("val2", EMObject::FLOAT, "number of Gaussian pixels to expand, following the first expansion");
05724 return d;
05725 }
05726
05727 static const string NAME;
05728 };
05729
05732 class TestImageProcessor : public Processor
05733 {
05734 public:
05735 static string get_group_desc()
05736 {
05737 return "Base class for a group of 'processors' used to create test image.";
05738 }
05739
05740 protected:
05741 void preprocess(EMData * image);
05742 int nx, ny, nz;
05743 };
05744
05753 class TestImagePureGaussian : public TestImageProcessor
05754 {
05755 public:
05756 virtual void process_inplace(EMData * image);
05757
05758 virtual string get_name() const
05759 {
05760 return NAME;
05761 }
05762
05763 virtual string get_desc() const
05764 {
05765 return "Replace a source image as a strict Gaussian ";
05766 }
05767
05768 static Processor * NEW()
05769 {
05770 return new TestImagePureGaussian();
05771 }
05772
05773 virtual TypeDict get_param_types() const
05774 {
05775 TypeDict d;
05776 d.put("x_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on x direction");
05777 d.put("y_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on y direction");
05778 d.put("z_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on z direction");
05779 d.put("x_center", EMObject::FLOAT, "center for this Gaussian blob on x direction" );
05780 d.put("y_center", EMObject::FLOAT, "center for this Gaussian blob on y direction" );
05781 d.put("z_center", EMObject::FLOAT, "center for this Gaussian blob on z direction" );
05782 return d;
05783 }
05784
05785 static const string NAME;
05786 };
05787
05791 class TestImageFourierNoiseGaussian : public TestImageProcessor
05792 {
05793 public:
05794 virtual void process_inplace(EMData * image);
05795
05796 virtual string get_name() const
05797 {
05798 return NAME;
05799 }
05800
05801 virtual string get_desc() const
05802 {
05803 return "Replace a source image with pink Fourier noise, based on a Gaussian. Random phase.";
05804 }
05805
05806 static Processor * NEW()
05807 {
05808 return new TestImageFourierNoiseGaussian();
05809 }
05810
05811 virtual TypeDict get_param_types() const
05812 {
05813 TypeDict d;
05814 d.put("sigma", EMObject::FLOAT, "sigma value");
05815 return d;
05816 }
05817
05818 static const string NAME;
05819 };
05820
05825 class TestImageFourierNoiseProfile : 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 with Fourier noise using amplitude information that is stored in a profile.";
05838 }
05839
05840 static Processor * NEW()
05841 {
05842 return new TestImageFourierNoiseProfile();
05843 }
05844
05845 virtual TypeDict get_param_types() const
05846 {
05847 TypeDict d;
05848 d.put("profile", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
05849 return d;
05850 }
05851
05852 static const string NAME;
05853 };
05854
05855
05860 class CTFSNRWeightProcessor : public TestImageProcessor
05861 {
05862 public:
05863 virtual void process_inplace(EMData * image);
05864
05865 virtual string get_name() const
05866 {
05867 return NAME;
05868 }
05869
05870 virtual string get_desc() const
05871 {
05872 return "Weight the amplitudes of an image based on radial noise and snr curves ";
05873 }
05874
05875 static Processor * NEW()
05876 {
05877 return new CTFSNRWeightProcessor();
05878 }
05879
05880 virtual TypeDict get_param_types() const
05881 {
05882 TypeDict d;
05883 d.put("noise", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
05884 d.put("snr", EMObject::FLOATARRAY, "Squared amplitude divided by squared noise amplitude. As in, what is the EMAN2CTF.snr attribute");
05885 d.put("boost", EMObject::FLOAT, "Multiplicative signal boost");
05886 return d;
05887 }
05888
05889 static const string NAME;
05890 };
05891
05892
05893
05898 class TestImageLineWave : public TestImageProcessor
05899 {
05900 public:
05901 virtual void process_inplace(EMData * image);
05902
05903 virtual string get_name() const
05904 {
05905 return NAME;
05906 }
05907
05908 virtual string get_desc() const
05909 {
05910 return "Insert an oscillating sine wave into the pixel data";
05911 }
05912
05913 static Processor * NEW()
05914 {
05915 return new TestImageLineWave();
05916 }
05917
05918 virtual TypeDict get_param_types() const
05919 {
05920 TypeDict d;
05921 d.put("period", EMObject::FLOAT, "The period of the oscillating sine wave. Default 10.");
05922 return d;
05923 }
05924
05925 static const string NAME;
05926 };
05927
05928
05936 class TestTomoImage : public TestImageProcessor
05937 {
05938 public:
05942 virtual void process_inplace(EMData * image);
05943
05944 virtual string get_name() const
05945 {
05946 return NAME;
05947 }
05948
05949 virtual string get_desc() const
05950 {
05951 return "Make an image consisting various objects, useful for tomographic testing";
05952 }
05953
05954 static Processor * NEW()
05955 {
05956 return new TestTomoImage();
05957 }
05958
05959 static const string NAME;
05960
05961 private:
05962 void insert_solid_ellipse( EMData* image, const Region& region, const float& value, const Transform& t3d = Transform() );
05963 void insert_hollow_ellipse( EMData* image, const Region& region, const float& value, const int& radius, const Transform& t3d = Transform() );
05964 void insert_rectangle( EMData* image, const Region& region, const float& value, const Transform& t3d = Transform() );
05965 };
05966
05974 class TestImageGradient : public TestImageProcessor
05975 {
05976 public:
05977 virtual void process_inplace(EMData * image);
05978
05979 virtual string get_name() const
05980 {
05981 return NAME;
05982 }
05983
05984 virtual string get_desc() const
05985 {
05986 return "Make a gradient image of the form y=mx+b, where x is any of the image axes.";
05987 }
05988
05989 static Processor * NEW()
05990 {
05991 return new TestImageGradient();
05992 }
05993
05994 virtual TypeDict get_param_types() const
05995 {
05996 TypeDict d;
05997 d.put("axis", EMObject::STRING, "The axis the will be used to determine pixel values. Must be x,y or z");
05998 d.put("m", EMObject::FLOAT, "m in the equation m*axis+b. Default is 1.0");
05999 d.put("b", EMObject::FLOAT, "b in the equation m*axis+b. Default is 0.0");
06000 return d;
06001 }
06002
06003 static const string NAME;
06004 };
06005
06013 class TestImageAxes : public TestImageProcessor
06014 {
06015 public:
06020 virtual void process_inplace(EMData * image);
06021
06022 virtual string get_name() const
06023 {
06024 return NAME;
06025 }
06026
06027 virtual string get_desc() const
06028 {
06029 return "Make an image consisting of a single cross";
06030 }
06031
06032 static Processor * NEW()
06033 {
06034 return new TestImageAxes();
06035 }
06036
06037 virtual TypeDict get_param_types() const
06038 {
06039 TypeDict d;
06040 d.put("int", EMObject::FLOAT, "radius of the lines emanating from the origin");
06041 d.put("fill", EMObject::FLOAT, "value to make non-zero pixels");
06042 return d;
06043 }
06044
06045 static const string NAME;
06046 };
06047
06053 class TestImageGaussian : public TestImageProcessor
06054 {
06055 public:
06056 virtual void process_inplace(EMData * image);
06057
06058 virtual string get_name() const
06059 {
06060 return NAME;
06061 }
06062
06063 virtual string get_desc() const
06064 {
06065 return "Replace a source image as a Gaussian Blob";
06066 }
06067
06068 static Processor * NEW()
06069 {
06070 return new TestImageGaussian();
06071 }
06072
06073 virtual TypeDict get_param_types() const
06074 {
06075 TypeDict d;
06076 d.put("sigma", EMObject::FLOAT, "sigma value for this Gaussian blob");
06077 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06078 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06079 return d;
06080 }
06081
06082 static const string NAME;
06083 };
06084
06087 class TestImageScurve : public TestImageProcessor
06088 {
06089 public:
06090 virtual void process_inplace(EMData * image);
06091
06092 virtual string get_name() const
06093 {
06094 return NAME;
06095 }
06096
06097 virtual string get_desc() const
06098 {
06099 return "Replace a source image with a lumpy S-curve used for alignment testing";
06100 }
06101
06102 static Processor * NEW()
06103 {
06104 return new TestImageScurve();
06105 }
06106
06107 virtual TypeDict get_param_types() const
06108 {
06109 TypeDict d;
06110 return d;
06111 }
06112
06113 static const string NAME;
06114 };
06115
06123 class TestImageSphericalWave : public TestImageProcessor
06124 {
06125 public:
06126 virtual void process_inplace(EMData * image);
06127
06128 virtual string get_name() const
06129 {
06130 return NAME;
06131 }
06132
06133 virtual string get_desc() const
06134 {
06135 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)";
06136 }
06137
06138 static Processor * NEW()
06139 {
06140 return new TestImageSphericalWave();
06141 }
06142
06143 virtual TypeDict get_param_types() const
06144 {
06145 TypeDict d;
06146 d.put("wavelength", EMObject::FLOAT, "cos(2*pi*r/wavelength+phase)");
06147 d.put("phase", EMObject::FLOAT, "in radians");
06148 d.put("x", EMObject::FLOAT, "center of the spherical wave");
06149 d.put("y", EMObject::FLOAT, "center of the spherical wave");
06150 d.put("z", EMObject::FLOAT, "center of the spherical wave");
06151 return d;
06152 }
06153
06154 static const string NAME;
06155 };
06156
06157
06166 class TestImageSinewave : public TestImageProcessor
06167 {
06168 public:
06169 virtual void process_inplace(EMData * image);
06170
06171 virtual string get_name() const
06172 {
06173 return NAME;
06174 }
06175
06176 virtual string get_desc() const
06177 {
06178 return "Replace a source image as a sine wave in specified wave length";
06179 }
06180
06181 static Processor * NEW()
06182 {
06183 return new TestImageSinewave();
06184 }
06185
06186 virtual TypeDict get_param_types() const
06187 {
06188 TypeDict d;
06189 d.put("wavelength", EMObject::FLOAT, "wavelength in equation sin(x*2*PI/wavelength - phase*180/PI)");
06190 d.put("axis", EMObject::STRING, "(optional) specify a major axis for asymmetric features, default x axis");
06191 d.put("phase", EMObject::FLOAT, "(optional) the phase in radians");
06192 d.put("az", EMObject::FLOAT, "(optional) angle in degree. for 2D image, this is the rotated angle of the image, \
06193 in 3D image, it's az for euler angle. default is zero");
06194 d.put("alt", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, alt for euler angle, default is zero");
06195 d.put("phi", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, phi for euler angle, default is zero");
06196 return d;
06197 }
06198
06199 static const string NAME;
06200 };
06201
06208 class TestImageSinewaveCircular : public TestImageProcessor
06209 {
06210 public:
06211 virtual void process_inplace(EMData * image);
06212
06213 virtual string get_name() const
06214 {
06215 return NAME;
06216 }
06217
06218 virtual string get_desc() const
06219 {
06220 return "Replace a source image as a circular sine wave in specified wave length";
06221 }
06222
06223 static Processor * NEW()
06224 {
06225 return new TestImageSinewaveCircular();
06226 }
06227
06228 virtual TypeDict get_param_types() const
06229 {
06230 TypeDict d;
06231 d.put("wavelength", EMObject::FLOAT, "(required)this value is the d in function |sin(x/d)|, unit: pixel");
06232 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06233 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06234 d.put("phase", EMObject::FLOAT, "(optional)phase for sine wave, default is 0");
06235 return d;
06236 }
06237
06238 static const string NAME;
06239 };
06240
06247 class TestImageSquarecube : public TestImageProcessor
06248 {
06249 public:
06250 virtual void process_inplace(EMData * image);
06251
06252 virtual string get_name() const
06253 {
06254 return NAME;
06255 }
06256
06257 virtual string get_desc() const
06258 {
06259 return "Replace a source image as a square or cube depends on 2D or 3D of the source image";
06260 }
06261
06262 static Processor * NEW()
06263 {
06264 return new TestImageSquarecube();
06265 }
06266
06267 virtual TypeDict get_param_types() const
06268 {
06269 TypeDict d;
06270 d.put("edge_length", EMObject::FLOAT, "edge length of the square or cube, unit: pixel");
06271 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06272 d.put("odd_edge", EMObject::FLOAT, "edge length for the asymmetric axis");
06273 d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank");
06274 return d;
06275 }
06276
06277 static const string NAME;
06278 };
06279
06287 class TestImageEllipse : public TestImageProcessor
06288 {
06289 public:
06290 virtual void process_inplace(EMData * image);
06291
06292 virtual string get_name() const
06293 {
06294 return NAME;
06295 }
06296
06297 virtual string get_desc() const
06298 {
06299 return "Insert an ellipse into the image.";
06300 }
06301
06302 static Processor * NEW()
06303 {
06304 return new TestImageEllipse();
06305 }
06306
06307 virtual TypeDict get_param_types() const
06308 {
06309 TypeDict d;
06310 d.put("a", EMObject::FLOAT, "equatorial radius along x axes (major semiaxes)");
06311 d.put("b", EMObject::FLOAT, "equatorial radius along y axes (minor semiaxes)");
06312 d.put("c", EMObject::FLOAT, "polar radius for ellipsoid (x^2/a^2+y^2/b^2+z^2/c^2=1)");
06313 d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06314 d.put("fill", EMObject::FLOAT, "value you want to fill in ellipse, default to 1.0");
06315 return d;
06316 }
06317
06318 static const string NAME;
06319 };
06320
06332 class TestImageHollowEllipse : public TestImageProcessor
06333 {
06334 public:
06335 virtual void process_inplace(EMData * image);
06336
06337 virtual string get_name() const
06338 {
06339 return NAME;
06340 }
06341
06342 virtual string get_desc() const
06343 {
06344 return "Insert a hollow ellipse into the image.";
06345 }
06346
06347 static Processor * NEW()
06348 {
06349 return new TestImageHollowEllipse();
06350 }
06351
06352 virtual TypeDict get_param_types() const
06353 {
06354 TypeDict d;
06355 d.put("xwidth", EMObject::FLOAT, "inner equatorial radii along x axes");
06356 d.put("ywidth", EMObject::FLOAT, "inner equatorial radii along y axes");
06357 d.put("zwidth", EMObject::FLOAT, "inner polar radius");
06358 d.put("a", EMObject::FLOAT, "outter equatorial radii along x axes");
06359 d.put("b", EMObject::FLOAT, "outter equatorial radii along y axes");
06360 d.put("c", EMObject::FLOAT, "outter polar radius");
06361 d.put("width",EMObject::FLOAT, "width - specify the width or specify each width explicitly - xwidth, ywidth, zwidth");
06362 d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06363 d.put("fill", EMObject::FLOAT, "value you want to fill in hollow ellipse, default to 1.0");
06364 return d;
06365 }
06366
06367 static const string NAME;
06368 };
06369
06376 class TestImageCirclesphere : public TestImageProcessor
06377 {
06378 public:
06379 virtual void process_inplace(EMData * image);
06380
06381 virtual string get_name() const
06382 {
06383 return NAME;
06384 }
06385
06386 virtual string get_desc() const
06387 {
06388 return "Replace a source image as a circle or sphere depends on 2D or 3D of the source image";
06389 }
06390
06391 static Processor * NEW()
06392 {
06393 return new TestImageCirclesphere();
06394 }
06395
06396 virtual TypeDict get_param_types() const
06397 {
06398 TypeDict d;
06399 d.put("radius", EMObject::FLOAT, "radius of circle or sphere, unit: pixel");
06400 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06401 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06402 d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank.");
06403 return d;
06404 }
06405
06406 static const string NAME;
06407 };
06408
06413 class TestImageNoiseUniformRand : public TestImageProcessor
06414 {
06415 public:
06416 virtual void process_inplace(EMData * image);
06417
06418 virtual string get_name() const
06419 {
06420 return NAME;
06421 }
06422
06423 virtual string get_desc() const
06424 {
06425 return "Replace a source image as a uniform random noise, random number generated from gsl_rng_mt19937, the pixel value is [0, 1)";
06426 }
06427
06428 static Processor * NEW()
06429 {
06430 return new TestImageNoiseUniformRand();
06431 }
06432
06433 virtual TypeDict get_param_types() const
06434 {
06435 TypeDict d;
06436 d.put("seed", EMObject::INT, "seed for random number generator");
06437 return d;
06438 }
06439
06440 static const string NAME;
06441 };
06442
06453 class TestImageNoiseGauss : public TestImageProcessor
06454 {
06455 public:
06456 virtual void process_inplace(EMData * image);
06457
06458 virtual string get_name() const
06459 {
06460 return NAME;
06461 }
06462
06463 virtual string get_desc() const
06464 {
06465 return "Replace a source image as a random noise, the random value is gaussian distributed";
06466 }
06467
06468 static Processor * NEW()
06469 {
06470 return new TestImageNoiseGauss();
06471 }
06472
06473 virtual TypeDict get_param_types() const
06474 {
06475 TypeDict d;
06476 d.put("sigma", EMObject::FLOAT, "sigma value of gausian distributed noise, default is 0.5");
06477 d.put("mean", EMObject::FLOAT, "mean value of gausian distributed noise, default is zero.");
06478 d.put("seed", EMObject::INT, "the seed for random number generator, default is not to reseed.");
06479
06480 return d;
06481 }
06482
06483 static const string NAME;
06484 };
06485
06490 class TestImageCylinder : public TestImageProcessor
06491 {
06492 public:
06493 virtual void process_inplace(EMData * image);
06494
06495 virtual string get_name() const
06496 {
06497 return NAME;
06498 }
06499
06500 virtual string get_desc() const
06501 {
06502 return "Replace a source image as a cylinder";
06503 }
06504
06505 static Processor * NEW()
06506 {
06507 return new TestImageCylinder();
06508 }
06509
06510 virtual TypeDict get_param_types() const
06511 {
06512 TypeDict d;
06513 d.put("radius", EMObject::FLOAT, "radius for the cylinder");
06514 d.put("height", EMObject::FLOAT, "height for the cylinder, by default it's the nz");
06515
06516 return d;
06517 }
06518
06519 static const string NAME;
06520 };
06521
06527 class CCDNormProcessor:public Processor
06528 {
06529 public:
06530 virtual void process_inplace(EMData * image);
06531
06532 virtual string get_name() const
06533 {
06534 return NAME;
06535 }
06536
06537 static Processor *NEW()
06538 {
06539 return new CCDNormProcessor();
06540 }
06541
06542 virtual string get_desc() const
06543 {
06544 return "normalize the 4 quadrants of a CCD image";
06545 }
06546
06547 virtual TypeDict get_param_types() const
06548 {
06549 TypeDict d;
06550 d.put("width", EMObject::INT, "number of pixels on either side of the seam to sample");
06551 return d;
06552 }
06553
06554 static const string NAME;
06555 };
06556
06564 class WaveletProcessor:public Processor
06565 {
06566 public:
06567 virtual void process_inplace(EMData * image);
06568
06569 virtual string get_name() const
06570 {
06571 return NAME;
06572 }
06573
06574 static Processor *NEW()
06575 {
06576 return new WaveletProcessor();
06577 }
06578
06579 virtual TypeDict get_param_types() const
06580 {
06581 TypeDict d;
06582 d.put("type", EMObject::STRING, "'daub', 'harr' or 'bspl'");
06583 d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06584 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)");
06585 return d;
06586 }
06587
06588 virtual string get_desc() const
06589 {
06590 return "Computes the DWT (discrete wavelet transform) of an image in one of 3 possible bases";
06591 }
06592
06593 static const string NAME;
06594 };
06595
06611 class TomoTiltEdgeMaskProcessor : public Processor
06612 {
06613 public:
06614 virtual void process_inplace(EMData* image);
06615
06616 virtual string get_name() const
06617 {
06618 return NAME;
06619 }
06620
06621 static Processor *NEW()
06622 {
06623 return new TomoTiltEdgeMaskProcessor();
06624 }
06625
06626 virtual TypeDict get_param_types() const
06627 {
06628 TypeDict d;
06629 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");
06630 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.");
06631 d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06632 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.");
06633 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)");
06634 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");
06635 return d;
06636 }
06637
06638 virtual string get_desc() const
06639 {
06640 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.";
06641 }
06642
06643 static const string NAME;
06644
06645 private:
06646 class GaussianFunctoid
06647 {
06648 public:
06649 GaussianFunctoid(const float sigma, const float mean = 0.0) : m_mean(mean), m_sigma_squared(sigma*sigma) {}
06650 ~GaussianFunctoid() {}
06651
06652 float operator()(const float distance )
06653 {
06654 return exp( -(distance-m_mean)*(distance-m_mean)/ (m_sigma_squared ));
06655 }
06656 private:
06657 float m_mean, m_sigma_squared;
06658 };
06659
06660 };
06661
06676 class TomoTiltAngleWeightProcessor : public Processor
06677 {
06678 public:
06679 virtual void process_inplace(EMData* image);
06680
06681 virtual string get_name() const
06682 {
06683 return NAME;
06684 }
06685
06686 static Processor *NEW()
06687 {
06688 return new TomoTiltAngleWeightProcessor();
06689 }
06690
06691 virtual TypeDict get_param_types() const
06692 {
06693 TypeDict d;
06694 d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06695 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");
06696 return d;
06697 }
06698
06699 virtual string get_desc() const
06700 {
06701 return "Weights the image by 1/cos(angle)";
06702 }
06703
06704 static const string NAME;
06705
06706 };
06707
06711 class FFTProcessor : public Processor
06712 {
06713 public:
06714 void process_inplace(EMData * image);
06715
06716 string get_name() const
06717 {
06718 return NAME;
06719 }
06720
06721 static Processor *NEW()
06722 {
06723 return new FFTProcessor();
06724 }
06725
06726 TypeDict get_param_types() const
06727 {
06728 TypeDict d;
06729 d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06730 return d;
06731 }
06732
06733 string get_desc() const
06734 {
06735 return "Computes the DFFT (Discrete Fast Fourier Transform) of an image";
06736 }
06737
06738 static const string NAME;
06739 };
06740
06745 class RadialProcessor : public Processor
06746 {
06747 public:
06748 void process_inplace(EMData * image);
06749
06750 string get_name() const
06751 {
06752 return NAME;
06753 }
06754
06755 static Processor *NEW()
06756 {
06757 return new RadialProcessor();
06758 }
06759
06760 TypeDict get_param_types() const
06761 {
06762 TypeDict d;
06763 d.put("table", EMObject::FLOATARRAY, "Radial array of floats, 1 float/pixel");
06764 return d;
06765 }
06766
06767 string get_desc() const
06768 {
06769 return "Multiply a real-space image by a radial function. 1 value / pixel, extending to corner. Missing values -> 0.";
06770 }
06771
06772 static const string NAME;
06773 };
06774
06781 class HistogramBin : public Processor
06782 {
06783 public:
06784 HistogramBin() : default_bins(1024) {}
06785
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 HistogramBin();
06796 }
06797
06798 TypeDict get_param_types() const
06799 {
06800 TypeDict d;
06801 d.put("nbins", EMObject::INT, "The number of bins the pixel values will be compressed into");
06802 d.put("debug", EMObject::BOOL, "Outputs debugging information (number of pixels per bin)");
06803 return d;
06804 }
06805
06806 string get_desc() const
06807 {
06808 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";
06809 }
06810
06811 static const string NAME;
06812
06813 protected:
06814 int default_bins;
06815 };
06816
06817 class ModelHelixProcessor : public Processor
06818 {
06819 protected:
06820 float radprofile(float r, int type);
06821 };
06822
06823 class ModelEMCylinderProcessor : public ModelHelixProcessor
06824 {
06825 public:
06826 void process_inplace(EMData * in);
06827
06828 string get_name() const
06829 {
06830 return NAME;
06831 }
06832
06833 static Processor *NEW()
06834 {
06835 return new ModelEMCylinderProcessor();
06836 }
06837
06838 string get_desc() const
06839 {
06840 return "Adds a cylinder with a radial density profile similar to that of an alpha helix.";
06841 }
06842
06843 virtual TypeDict get_param_types() const
06844 {
06845 TypeDict d;
06846 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");
06847 d.put("length", EMObject::FLOAT, "cylinder length in angstroms, defaults to 3 turns (16.2 Angstroms)");
06848 d.put("x0", EMObject::INT, "x coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06849 d.put("y0", EMObject::INT, "y coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06850 d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06851
06852 return d;
06853 }
06854
06855 static const string NAME;
06856 };
06857
06858 class ApplyPolynomialProfileToHelix : public ModelHelixProcessor
06859 {
06860 public:
06861 void process_inplace(EMData * in);
06862
06863 string get_name() const
06864 {
06865 return NAME;
06866 }
06867
06868 static Processor *NEW()
06869 {
06870 return new ApplyPolynomialProfileToHelix();
06871 }
06872
06873 string get_desc() const
06874 {
06875 return "Finds the CM of each z-axis slice and applies a polynomial radial profile about it.";
06876 }
06877 virtual TypeDict get_param_types() const
06878 {
06879 TypeDict d;
06880 d.put("length", EMObject::FLOAT, "Helix length in angstroms.");
06881 d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06882 return d;
06883 }
06884
06885 static const string NAME;
06886 };
06887
06888 class BinarySkeletonizerProcessor : public Processor
06889 {
06890 public:
06891 virtual EMData* process(EMData * image);
06892 virtual void process_inplace(EMData * image);
06893
06894 virtual string get_name() const
06895 {
06896 return NAME;
06897
06898 }
06899 static Processor *NEW()
06900 {
06901 return new BinarySkeletonizerProcessor();
06902 }
06903 string get_desc() const
06904 {
06905 return "Creates a skeleton of the 3D image by considering whether density is above or below a threshold value.";
06906 }
06907 virtual TypeDict get_param_types() const
06908 {
06909 TypeDict d;
06910 d.put("threshold", EMObject::FLOAT, "Threshold value.");
06911 d.put("min_curve_width", EMObject::INT, "Minimum curve width.");
06912 d.put("min_surface_width", EMObject::INT, "Minimum surface width.");
06913 d.put("mark_surfaces", EMObject::BOOL, "Mark surfaces with a value of 2.0f, whereas curves are 1.0f.");
06914 return d;
06915 }
06916 static const string NAME;
06917 };
06918
06919 class ConvolutionKernalProcessor : public Processor
06920 {
06921 public:
06922 virtual EMData* process(const EMData* const image);
06923 virtual void process_inplace(EMData * image);
06924
06925 virtual string get_name() const
06926 {
06927 return NAME;
06928 }
06929 static Processor *NEW()
06930 {
06931 return new ConvolutionKernalProcessor();
06932 }
06933 string get_desc() const
06934 {
06935 return "Filters an image with a convolution kernal.";
06936 }
06937 virtual TypeDict get_param_types() const
06938 {
06939 TypeDict d;
06940 d.put("kernal", EMObject::FLOATARRAY, "the convolution kernal");
06941 return d;
06942 }
06943 static const string NAME;
06944 };
06945
06946 #ifdef SPARX_USING_CUDA
06947
06948
06949
06950
06951
06952 class MPICUDA_kmeans {
06953 public:
06954 MPICUDA_kmeans();
06955 ~MPICUDA_kmeans();
06956 int setup(int extm, int extN, int extn, int extK, int extn_start);
06957 void append_flat_image(EMData* im, int pos);
06958 int init_mem(int numdev);
06959 void compute_im2();
06960 int random_ASG(long int rnd);
06961 vector<int> get_ASG();
06962 vector<int> get_asg();
06963 void compute_NC();
06964 vector<int> get_NC();
06965 void set_ASG(const vector <int>& ASG);
06966 void set_NC(const vector <int>& NC);
06967 int get_ct_im_mv();
06968 void set_T(float extT);
06969 float get_T();
06970 void compute_AVE();
06971 void set_AVE(EMData* im, int pos);
06972 vector<EMData*> get_AVE();
06973 int one_iter();
06974
06975
06976 int one_iter_SA();
06977 vector<float> compute_ji();
06978 vector<float> compute_criterion(const vector <float>& Ji);
06979 int shutdown();
06980 private:
06981
06982 int m;
06983 int N;
06984 int n;
06985 int K;
06986 int nb_part;
06987 int n_start;
06988 int size_im;
06989 int size_IM;
06990 int size_AVE;
06991 int size_dist;
06992 int BLOCK_SIZE;
06993 int NB;
06994 int ins_BLOCK;
06995 int ite;
06996 float T;
06997
06998 int ct_im_mv;
06999
07000 float* h_IM;
07001 float* h_im;
07002 float* h_AVE;
07003 float* h_dist;
07004 float* h_AVE2;
07005 float* h_im2;
07006 unsigned short int* h_ASG;
07007 unsigned short int* h_asg;
07008 unsigned int* h_NC;
07009 int* params;
07010 float ttt;
07011
07012 float* d_im;
07013 float* d_AVE;
07014 float* d_dist;
07015
07016 float compute_tt();
07017 };
07018
07019 #endif //EMAN2_USING_CUDA
07020
07021 #if 0
07022
07023 class XYZProcessor:public Processor
07024 {
07025 public:
07026 void process_inplace(EMData * image);
07027
07028 string get_name() const
07029 {
07030 return NAME;
07031 }
07032
07033 static Processor *NEW()
07034 {
07035 return new XYZProcessor();
07036 }
07037
07038 string get_desc() const
07039 {
07040 return "N/A";
07041 }
07042
07043 TypeDict get_param_types() const
07044 {
07045 TypeDict d;
07046 return d;
07047 }
07048
07049 static const string NAME;
07050 };
07051
07052
07053 #endif
07054
07055
07056 #if 0
07057
07058 class XYZProcessor:public Processor
07059 {
07060 public:
07061 void process_inplace(EMData * image);
07062
07063 string get_name() const
07064 {
07065 return NAME;
07066 }
07067
07068 static Processor *NEW()
07069 {
07070 return new XYZProcessor();
07071 }
07072
07073 string get_desc() const
07074 {
07075 return "N/A";
07076 }
07077
07078 TypeDict get_param_types() const
07079 {
07080 TypeDict d;
07081 return d;
07082 }
07083
07084 static const string NAME;
07085 };
07086
07087
07088 #endif
07089
07090
07091 int multi_processors(EMData * image, vector < string > processornames);
07092 void dump_processors();
07093 map<string, vector<string> > dump_processors_list();
07094 map<string, vector<string> > group_processors();
07095
07096 template <> Factory < Processor >::Factory();
07097 }
07098
07099 #endif //eman_filter_h__
07100
07101
07102