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
01524 class ApplySymProcessor:public Processor
01525 {
01526 public:
01527 virtual string get_name() const
01528 {
01529 return NAME;
01530 }
01531
01532 static Processor *NEW()
01533 {
01534 return new ApplySymProcessor();
01535 }
01536
01537 virtual void process_inplace(EMData* image);
01538
01539 virtual EMData* process(const EMData* const image);
01540
01541 virtual TypeDict get_param_types() const
01542 {
01543 TypeDict d;
01544 d.put("sym", EMObject::STRING, "The symmetry under which to do the alignment, Default=c1" );
01545 return d;
01546 }
01547
01548 virtual string get_desc() const
01549 {
01550 return "Symmetry is applied to the 3D EM object";
01551 }
01552
01553 static const string NAME;
01554
01555 };
01556
01563 class SymAlignProcessor:public Processor
01564 {
01565 public:
01566 virtual string get_name() const
01567 {
01568 return NAME;
01569 }
01570
01571 static Processor *NEW()
01572 {
01573 return new SymAlignProcessor();
01574 }
01575
01576 virtual void process_inplace(EMData* image);
01577
01578 virtual EMData* process(const EMData* const image);
01579
01580 virtual TypeDict get_param_types() const
01581 {
01582 TypeDict d;
01583 d.put("sym", EMObject::STRING, "The symmetry under which to do the alignment, Default=c1" );
01584 d.put("delta", EMObject::FLOAT,"Angle the separates points on the sphere. This is exclusive of the \'n\' paramater. Default is 10");
01585 d.put("dphi", EMObject::FLOAT,"The angle increment in the phi direction. Default is 10");
01586 d.put("lphi", EMObject::FLOAT,"Lower bound for phi. Default it 0");
01587 d.put("uphi", EMObject::FLOAT,"Upper bound for phi. Default it 359.9");
01588 d.put("avger", EMObject::STRING, "The sort of averager to use, Default=mean" );
01589 return d;
01590 }
01591
01592 virtual string get_desc() const
01593 {
01594 return "The image is centered and rotated to the standard orientation for the specified symmetry";
01595 }
01596
01597 static const string NAME;
01598
01599 private:
01603 void assert_valid_aspect(const vector<int>& translation, const EMData* const image) const;
01604
01610 Region get_clip_region(vector<int>& translation, const EMData* const image) const;
01611 };
01612
01613
01620 class ScaleTransformProcessor:public Processor
01621 {
01622 public:
01623 virtual string get_name() const
01624 {
01625 return NAME;
01626 }
01627 static Processor *NEW()
01628 {
01629 return new ScaleTransformProcessor();
01630 }
01631
01636 virtual void process_inplace(EMData* image);
01637
01642 virtual EMData* process(const EMData* const image);
01643
01644 virtual TypeDict get_param_types() const
01645 {
01646 TypeDict d;
01647 d.put("scale", EMObject::FLOAT, "The amount by which to scale" );
01648 d.put("clip", EMObject::INT, "The length of each output dimension. Non sophisticated, output dimensions can't be different" );
01651 return d;
01652 }
01653
01654 virtual string get_desc() const
01655 {
01656 return "The image is scaled with the clip variable in mind, being sure to preserve as much pixel information as possible.";
01657 }
01658
01659 static const string NAME;
01660 };
01661
01668 class ClampingProcessor :public Processor
01669 {
01670 public:
01671 ClampingProcessor() : default_max(1.0), default_min(0.0) {}
01672
01673 string get_name() const
01674 {
01675 return NAME;
01676 }
01677 static Processor *NEW()
01678 {
01679 return new ClampingProcessor();
01680 }
01681
01682 void process_inplace(EMData *image);
01683
01684 TypeDict get_param_types() const
01685 {
01686 TypeDict d;
01687 d.put("minval", EMObject::FLOAT, "The pixel values that bounds the smallest pixel value in the output image" );
01688 d.put("maxval", EMObject::FLOAT, "The pixel values that bounds the largest pixel value in the output image" );
01689 d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01690 return d;
01691 }
01692
01693 string get_desc() const
01694 {
01695 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.";
01696 }
01697
01698 static const string NAME;
01699
01700 protected:
01701 float default_max, default_min;
01702 };
01703
01709 class NSigmaClampingProcessor : public ClampingProcessor
01710 {
01711 public:
01712 NSigmaClampingProcessor() : default_sigma(2.0) {}
01713
01714 string get_name() const
01715 {
01716 return NAME;
01717 }
01718
01719 static Processor *NEW()
01720 {
01721 return new NSigmaClampingProcessor();
01722 }
01723
01724 TypeDict get_param_types() const
01725 {
01726 TypeDict d;
01727 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" );
01728 d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01729 return d;
01730 }
01731
01732 void process_inplace(EMData *image);
01733
01734 string get_desc() const
01735 {
01736 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.";
01737 }
01738
01739 static const string NAME;
01740
01741 protected:
01742 float default_sigma;
01743 };
01744
01748 class ToMinvalProcessor:public Processor
01749 {
01750 public:
01751 string get_name() const
01752 {
01753 return NAME;
01754 }
01755 static Processor *NEW()
01756 {
01757 return new ToMinvalProcessor();
01758 }
01759
01760 void process_inplace(EMData *image);
01761
01762 TypeDict get_param_types() const
01763 {
01764 TypeDict d;
01765 d.put("minval", EMObject::FLOAT, "Everything below this value is set to this value");
01766 d.put("newval", EMObject::FLOAT, "If set, values below minval will be set to newval instead of minval ");
01767 return d;
01768 }
01769
01770 string get_desc() const
01771 {
01772 return "f(x) = x if x >= minval; f(x) = minval|newval if x < minval.";
01773 }
01774
01775 static const string NAME;
01776
01777 protected:
01778
01779 };
01780
01781
01782
01786 class CutToZeroProcessor:public RealPixelProcessor
01787 {
01788 public:
01789 string get_name() const
01790 {
01791 return NAME;
01792 }
01793 static Processor *NEW()
01794 {
01795 return new CutToZeroProcessor();
01796 }
01797 TypeDict get_param_types() const
01798 {
01799 TypeDict d;
01800 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" );
01801 return d;
01802 }
01803
01804 string get_desc() const
01805 {
01806 return "f(x) = x-minval if x >= minval; f(x) = 0 if x < minval.";
01807 }
01808
01809 static const string NAME;
01810
01811 protected:
01812 void process_pixel(float *x) const
01813 {
01814 *x = *x - value;
01815 if (*x < 0) {
01816 *x = 0;
01817 }
01818 }
01819 };
01820
01824 class BinarizeProcessor:public RealPixelProcessor
01825 {
01826 public:
01827 string get_name() const
01828 {
01829 return NAME;
01830 }
01831 static Processor *NEW()
01832 {
01833 return new BinarizeProcessor();
01834 }
01835 TypeDict get_param_types() const
01836 {
01837 TypeDict d;
01838 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" );
01839 return d;
01840 }
01841
01842 string get_desc() const
01843 {
01844 return "f(x) = 0 if x < value; f(x) = 1 if x >= value.";
01845 }
01846
01847 static const string NAME;
01848
01849 protected:
01850 void process_pixel(float *x) const
01851 {
01852 if (*x < value)
01853 {
01854 *x = 0;
01855 }
01856 else
01857 {
01858 *x = 1;
01859 }
01860 }
01861 };
01862
01870 class BinarizeFourierProcessor:public Processor
01871 {
01872 public:
01873 virtual string get_name() const
01874 {
01875 return NAME;
01876 }
01877 static Processor *NEW()
01878 {
01879 return new BinarizeFourierProcessor();
01880 }
01881
01886 virtual void process_inplace(EMData* image);
01887
01888 virtual TypeDict get_param_types() const
01889 {
01890 TypeDict d;
01891 d.put("value", EMObject::FLOAT, "The Fourier amplitude threshold cutoff" );
01892 return d;
01893 }
01894
01895 virtual string get_desc() const
01896 {
01897 return "f(k) = 0 + 0i if ||f(k)|| < value; f(k) = a + bi if ||f(k)|| >= value.";
01898 }
01899
01900 static const string NAME;
01901 };
01902
01907 class CollapseProcessor:public RealPixelProcessor
01908 {
01909 public:
01910 string get_name() const
01911 {
01912 return NAME;
01913 }
01914 static Processor *NEW()
01915 {
01916 return new CollapseProcessor();
01917 }
01918
01919 void set_params(const Dict & new_params)
01920 {
01921 params = new_params;
01922 range = params["range"];
01923 value = params["value"];
01924 }
01925
01926 TypeDict get_param_types() const
01927 {
01928 TypeDict d;
01929 d.put("range", EMObject::FLOAT, "The range about 'value' which will be collapsed to 'value'");
01930 d.put("value", EMObject::FLOAT, "The pixel value where the focus of the collapse operation is");
01931 return d;
01932 }
01933
01934 string get_desc() const
01935 {
01936 return "f(x): if v-r<x<v+r -> v; if x>v+r -> x-r; if x<v-r -> x+r";
01937 }
01938
01939 static const string NAME;
01940
01941 protected:
01942 void process_pixel(float *x) const
01943 {
01944 if (*x>value+range) *x-=range;
01945 else if (*x<value-range) *x+=range;
01946 else *x=value;
01947 }
01948 float range;
01949 };
01950
01955 class LinearXformProcessor:public RealPixelProcessor
01956 {
01957 public:
01958 LinearXformProcessor():shift(0), scale(0)
01959 {
01960 }
01961
01962 string get_name() const
01963 {
01964 return NAME;
01965 }
01966 static Processor *NEW()
01967 {
01968 return new LinearXformProcessor();
01969 }
01970
01971 void set_params(const Dict & new_params)
01972 {
01973 params = new_params;
01974 shift = params.get("shift");
01975 scale = params.get("scale");
01976 }
01977
01978 TypeDict get_param_types() const
01979 {
01980 TypeDict d;
01981 d.put("shift", EMObject::FLOAT, "The amount to shift pixel values by before scaling");
01982 d.put("scale", EMObject::FLOAT, "The scaling factor to be applied to pixel values");
01983 return d;
01984 }
01985
01986 string get_desc() const
01987 {
01988 return "linear transform processor: f(x) = x * scale + shift. This is equivalent to a regular contrast stretching operation";
01989 }
01990
01991 static const string NAME;
01992
01993 protected:
01994 void process_pixel(float *x) const
01995 {
01996 *x = (*x) * scale + shift;
01997 }
01998
01999 private:
02000 float shift;
02001 float scale;
02002 };
02003
02008 class ExpProcessor:public RealPixelProcessor
02009 {
02010 public:
02011 ExpProcessor():low(0), high(0)
02012 {
02013 }
02014
02015 string get_name() const
02016 {
02017 return NAME;
02018 }
02019
02020 static Processor *NEW()
02021 {
02022 return new ExpProcessor();
02023 }
02024
02025 void set_params(const Dict & new_params)
02026 {
02027 params = new_params;
02028 low = params.get("low");
02029 high = params.get("high");
02030 }
02031
02032 TypeDict get_param_types() const
02033 {
02034 TypeDict d;
02035 d.put("low", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
02036 d.put("high", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
02037 return d;
02038 }
02039
02040 string get_desc() const
02041 {
02042 return "f(x) = exp( x / low - high)";
02043 }
02044
02045 static const string NAME;
02046
02047 protected:
02051 void process_pixel(float *x) const
02052 {
02053 float v = *x / low - high;
02054 if (v > 40) {
02055 v = 40;
02056 }
02057 *x = exp(v);
02058 }
02059
02060 private:
02061 float low;
02062 float high;
02063 };
02064
02068 class FiniteProcessor:public RealPixelProcessor
02069 {
02070 public:
02071 FiniteProcessor():to(0)
02072 {
02073 }
02074
02075 string get_name() const
02076 {
02077 return NAME;
02078 }
02079
02080 static Processor *NEW()
02081 {
02082 return new FiniteProcessor();
02083 }
02084
02085 void set_params(const Dict & new_params)
02086 {
02087 if (new_params.has_key("to") )
02088 to = params["to"];
02089 }
02090
02091 TypeDict get_param_types() const
02092 {
02093 TypeDict d;
02094 d.put("to", EMObject::FLOAT, "Pixels which are not finite will be set to this value");
02095 return d;
02096 }
02097
02098 string get_desc() const
02099 {
02100 return "f(x) = f(x) if f(x) is finite | to if f(x) is not finite";
02101 }
02102
02103 static const string NAME;
02104
02105 protected:
02109 void process_pixel(float *x) const;
02110 private:
02111 float to;
02112 };
02113
02118 class RangeThresholdProcessor:public RealPixelProcessor
02119 {
02120 public:
02121 RangeThresholdProcessor():low(0), high(0)
02122 {
02123 }
02124
02125 string get_name() const
02126 {
02127 return NAME;
02128 }
02129 static Processor *NEW()
02130 {
02131 return new RangeThresholdProcessor();
02132 }
02133
02134 void set_params(const Dict & new_params)
02135 {
02136 params = new_params;
02137 low = params.get("low");
02138 high = params.get("high");
02139 }
02140
02141 TypeDict get_param_types() const
02142 {
02143 TypeDict d;
02144 d.put("low", EMObject::FLOAT, "The lower limit of the range that will be set to 1");
02145 d.put("high", EMObject::FLOAT, "The upper limit of the range that will be set to 1");
02146 return d;
02147 }
02148
02149 string get_desc() const
02150 {
02151 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";
02152 }
02153
02154 static const string NAME;
02155
02156 protected:
02157 void process_pixel(float *x) const
02158 {
02159 if (*x >= low && *x <= high) {
02160 *x = 1;
02161 }
02162 else {
02163 *x = 0;
02164 }
02165 }
02166 private:
02167 float low;
02168 float high;
02169
02170 };
02171
02176 class SigmaProcessor:public RealPixelProcessor
02177 {
02178 public:
02179 string get_name() const
02180 {
02181 return NAME;
02182 }
02183 static Processor *NEW()
02184 {
02185 return new SigmaProcessor();
02186 }
02187
02188 void set_params(const Dict & new_params)
02189 {
02190 params = new_params;
02191 value1 = params.get("value1");
02192 value2 = params.get("value2");
02193 }
02194
02195 TypeDict get_param_types() const
02196 {
02197 TypeDict d;
02198 d.put("value1", EMObject::FLOAT, "A number reflecting total standard deviations in the right direction");
02199 d.put("value2", EMObject::FLOAT, "A number reflecting total standard deviations in the left direction");
02200 return d;
02201 }
02202
02203 string get_desc() const
02204 {
02205 return "f(x) = mean if x<(mean-v2*sigma) or x>(mean+v1*sigma); else f(x) = x;";
02206 }
02207
02208 static const string NAME;
02209
02210 protected:
02211 void process_pixel(float *x) const
02212 {
02213 if (*x < (mean - value2 * sigma) || *x > (mean + value1 * sigma))
02214 {
02215 *x = mean;
02216 }
02217 }
02218
02219 private:
02220 float value1;
02221 float value2;
02222 };
02223
02226 class LogProcessor:public RealPixelProcessor
02227 {
02228 public:
02229 string get_name() const
02230 {
02231 return NAME;
02232 }
02233 static Processor *NEW()
02234 {
02235 return new LogProcessor();
02236 }
02237
02238 string get_desc() const
02239 {
02240 return "f(x) = log10(x) if x > 0; else f(x) = 0;";
02241 }
02242
02243 static const string NAME;
02244
02245 protected:
02246 void process_pixel(float *x) const
02247 {
02248 if (*x > 0)
02249 {
02250 *x = log10(*x);
02251 }
02252 else
02253 {
02254 *x = 0;
02255 }
02256 }
02257 };
02258
02261 class CoordinateProcessor:public Processor
02262 {
02263 public:
02264 CoordinateProcessor():nx(0), ny(0), nz(0), mean(0), sigma(0), maxval(0), is_complex(false)
02265 {
02266 }
02267 void process_inplace(EMData * image);
02268
02269 static string get_group_desc()
02270 {
02271 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().";
02272 }
02273
02274 protected:
02275 virtual void process_pixel(float *pixel, int xi, int yi, int zi) const = 0;
02276 virtual void calc_locals(EMData *)
02277 {
02278 }
02279 virtual bool is_valid() const
02280 {
02281 return true;
02282 }
02283
02284 int nx;
02285 int ny;
02286 int nz;
02287 float mean;
02288 float sigma;
02289 float maxval;
02290
02291 bool is_complex;
02292 };
02293
02301 class CircularMaskProcessor:public CoordinateProcessor
02302 {
02303 public:
02304 CircularMaskProcessor():inner_radius(0), outer_radius(0), inner_radius_square(0),
02305 outer_radius_square(0), dx(0), dy(0), dz(0), xc(0), yc(0), zc(0)
02306 {
02307 }
02308
02309 void set_params(const Dict & new_params)
02310 {
02311 params = new_params;
02312
02313 if (params.has_key("inner_radius")) {
02314 inner_radius = params["inner_radius"];
02315 inner_radius_square = inner_radius * inner_radius;
02316 }
02317 else {
02318 inner_radius = -1;
02319 inner_radius_square = -1;
02320 }
02321
02322 if (params.has_key("outer_radius")) {
02323 outer_radius = params["outer_radius"];
02324 outer_radius_square = outer_radius * outer_radius;
02325 }
02326 else {
02327 outer_radius = INT_MAX;
02328 outer_radius_square = INT_MAX;
02329 }
02330
02331 if (params.has_key("xc")) xc = params["xc"];
02332 if (params.has_key("yc")) yc = params["yc"];
02333 if (params.has_key("zc")) zc = params["zc"];
02334 if (params.has_key("dx")) dx = params["dx"];
02335 if (params.has_key("dy")) dy = params["dy"];
02336 if (params.has_key("dz")) dz = params["dz"];
02337 }
02338
02339 string get_desc() const
02340 {
02341 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().";
02342 }
02343
02344 TypeDict get_param_types() const
02345 {
02346 TypeDict d;
02347
02348 d.put("inner_radius", EMObject::INT, "inner mask radius. optional");
02349 d.put("outer_radius", EMObject::INT, "outer mask radius. Negative value -> box radius + outer_radius +1");
02350
02351 d.put("dx", EMObject::FLOAT,
02352 "Modify mask center by dx relative to the default center nx/2");
02353 d.put("dy", EMObject::FLOAT,
02354 "Modify mask center by dy relative to the default center ny/2");
02355 d.put("dz", EMObject::FLOAT,
02356 "Modify mask center by dz relative to the default center nz/2");
02357
02358 return d;
02359 }
02360 protected:
02361 void calc_locals(EMData * image);
02362
02363 bool is_valid() const
02364 {
02365 return (!is_complex);
02366 }
02367
02368 void process_pixel(float *pixel, int xi, int yi, int zi) const
02369 {
02370 float dist = (xi - xc) * (xi - xc) + (yi - yc) * (yi - yc) + (zi - zc) * (zi - zc);
02371 process_dist_pixel(pixel, dist);
02372 }
02373
02374 virtual void process_dist_pixel(float *pixel, float dist) const = 0;
02375
02376 int inner_radius;
02377 int outer_radius;
02378 int inner_radius_square;
02379 int outer_radius_square;
02380 float dx, dy, dz;
02381 float xc, yc, zc;
02382 };
02383
02387 class MaskSharpProcessor:public CircularMaskProcessor
02388 {
02389 public:
02390 MaskSharpProcessor():value(0)
02391 {
02392 }
02393
02394 string get_name() const
02395 {
02396 return NAME;
02397 }
02398 static Processor *NEW()
02399 {
02400 return new MaskSharpProcessor();
02401 }
02402
02403 void set_params(const Dict & new_params)
02404 {
02405 CircularMaskProcessor::set_params(new_params);
02406 value = params.set_default("value",0.0f);
02407 }
02408
02409 TypeDict get_param_types() const
02410 {
02411 TypeDict d = CircularMaskProcessor::get_param_types();
02412 d.put("value", EMObject::FLOAT, "step cutoff to this value. Default is 0.");
02413 return d;
02414 }
02415
02416 string get_desc() const
02417 {
02418 return "step cutoff to a user-given value in both inner and outer circles.";
02419 }
02420
02421 static const string NAME;
02422
02423 protected:
02424 void process_dist_pixel(float *pixel, float dist) const
02425 {
02426 if (dist >= outer_radius_square || dist < inner_radius_square)
02427 {
02428 *pixel = value;
02429 }
02430 }
02431
02432 float value;
02433 };
02434
02435
02439 class MaskEdgeMeanProcessor:public CircularMaskProcessor
02440 {
02441 public:
02442 string get_name() const
02443 {
02444 return NAME;
02445 }
02446 static Processor *NEW()
02447 {
02448 return new MaskEdgeMeanProcessor();
02449 }
02450
02451 void set_params(const Dict & new_params)
02452 {
02453 CircularMaskProcessor::set_params(new_params);
02454 ring_width = params["ring_width"];
02455 if (ring_width == 0) {
02456 ring_width = 1;
02457 }
02458 }
02459
02460 TypeDict get_param_types() const
02461 {
02462 TypeDict d = CircularMaskProcessor::get_param_types();
02463 d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02464 return d;
02465 }
02466
02467 string get_desc() const
02468 {
02469 return "A step cutoff to the the mean value in a ring centered on the outer radius";
02470 }
02471
02472 static const string NAME;
02473
02474 protected:
02475 void calc_locals(EMData * image);
02476
02477
02478 void process_dist_pixel(float *pixel, float dist) const
02479 {
02480 if (dist >= outer_radius_square || dist < inner_radius_square){
02481 *pixel = ring_avg;
02482 }
02483 }
02484
02485 private:
02486 int ring_width;
02487 float ring_avg;
02488 };
02489
02492 class MaskNoiseProcessor:public CircularMaskProcessor
02493 {
02494 public:
02495 string get_name() const
02496 {
02497 return NAME;
02498 }
02499 static Processor *NEW()
02500 {
02501 return new MaskNoiseProcessor();
02502 }
02503
02504 string get_desc() const
02505 {
02506 return "fills masked region";
02507 }
02508
02509 static const string NAME;
02510
02511 protected:
02512 void process_dist_pixel(float *pixel, float dist) const
02513 {
02514 if (dist >= outer_radius_square || dist < inner_radius_square)
02515 {
02516 *pixel = Util::get_gauss_rand(mean, sigma);
02517 }
02518 }
02519 };
02520
02523 class MaskGaussProcessor:public CircularMaskProcessor
02524 {
02525 public:
02526 string get_name() const
02527 {
02528 return NAME;
02529 }
02530 static Processor *NEW()
02531 {
02532 return new MaskGaussProcessor();
02533 }
02534
02535 void set_params(const Dict & new_params)
02536 {
02537 CircularMaskProcessor::set_params(new_params);
02538 exponent = params["exponent"];
02539 if (exponent <= 0.0) {
02540 exponent = 2.0;
02541 }
02542 }
02543
02544 TypeDict get_param_types() const
02545 {
02546 TypeDict d = CircularMaskProcessor::get_param_types();
02547 d.put("exponent", EMObject::FLOAT, "The exponent, f in e^-Bs^f. default 2.0, producing a Gaussian");
02548 return d;
02549 }
02550
02551 string get_desc() const
02552 {
02553 return "a gaussian falloff to zero, radius is the 1/e of the width. If inner_radius>0, then \
02554 outer radius specifies width of Gaussian starting at inner_radius rather than total radius.";
02555 }
02556
02557 static const string NAME;
02558
02559 protected:
02560 float exponent;
02561 void process_dist_pixel(float *pixel, float dist) const
02562 {
02563 if (inner_radius_square>0) {
02564 if (dist>inner_radius_square) {
02565 if (exponent==2.0f) (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,2.0f) / outer_radius_square);
02566 else (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,exponent) / pow((float)outer_radius_square,exponent/2.0f));
02567 }
02568 }
02569 else {
02570 if (exponent==2.0f) (*pixel) *= exp(-dist / outer_radius_square);
02571 else (*pixel) *= exp(-pow(dist,exponent/2.0f) / pow((float)outer_radius_square,exponent/2.0f));
02572 }
02573 }
02574 };
02575
02582 class MaskGaussNonuniformProcessor:public CoordinateProcessor
02583 {
02584 public:
02585 MaskGaussNonuniformProcessor():radius_x(0), radius_y(0), radius_z(0), gauss_width(0)
02586 {
02587 }
02588
02589 void set_params(const Dict & new_params)
02590 {
02591 params = new_params;
02592
02593 if (params.has_key("radius_x")) radius_x=params["radius_x"];
02594 else radius_x=5.0;
02595
02596 if (params.has_key("radius_y")) radius_y=params["radius_y"];
02597 else radius_y=5.0;
02598
02599 if (params.has_key("radius_z")) radius_z=params["radius_z"];
02600 else radius_z=5.0;
02601
02602 if (params.has_key("gauss_width")) gauss_width=params["gauss_width"];
02603 else gauss_width=0.05f;
02604 }
02605
02606 TypeDict get_param_types() const
02607 {
02608 TypeDict d;
02609
02610 d.put("radius_x", EMObject::INT, "x-axis radius");
02611 d.put("radius_y", EMObject::INT, "y-axis radius");
02612 d.put("radius_z", EMObject::INT, "z-axis radius");
02613 d.put("gauss_width", EMObject::FLOAT, "Gaussian falloff width, relative to each radius, default 0.05");
02614
02615 return d;
02616 }
02617
02618 string get_name() const
02619 {
02620 return NAME;
02621 }
02622 static Processor *NEW()
02623 {
02624 return new MaskGaussNonuniformProcessor();
02625 }
02626
02627 string get_desc() const
02628 {
02629 return "A Gaussian falloff to zero. Nonisotropic, specify inner radius for x,y,z and Gaussian falloff width. Falloff \
02630 width is also nonisotropic and relative to the radii, with 1 being equal to the radius on that axis.";
02631 }
02632
02633 static const string NAME;
02634
02635 protected:
02636 void process_pixel(float *pixel, int xi, int yi, int zi) const
02637 {
02638 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);
02639 if (dist>1.0) (*pixel)*=exp(-pow((sqrt(dist)-1.0f)/gauss_width,2.0f));
02640 }
02641
02642 float radius_x,radius_y,radius_z,gauss_width;
02643 };
02644
02649 class MaskGaussInvProcessor:public CircularMaskProcessor
02650 {
02651 public:
02652 TypeDict get_param_types() const
02653 {
02654 TypeDict d = CircularMaskProcessor::get_param_types();
02655 d.put("gauss_width", EMObject::FLOAT, "Used to calculate the constant factor - gauss_width / (ny*ny)" );
02656 d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02657 return d;
02658 }
02659
02660 string get_name() const
02661 {
02662 return NAME;
02663 }
02664
02665 static Processor *NEW()
02666 {
02667 return new MaskGaussInvProcessor();
02668 }
02669
02670 string get_desc() const
02671 {
02672 return "f(x) = f(x) / exp(-radius*radius * gauss_width / (ny*ny))";
02673 }
02674
02675 static const string NAME;
02676
02677 protected:
02678 void calc_locals(EMData *)
02679 {
02680 float gauss_width = params["gauss_width"];
02681 slice_value = gauss_width / (ny * ny);
02682 }
02683
02684 void process_dist_pixel(float *pixel, float dist) const
02685 {
02686 (*pixel) /= exp(-dist * slice_value);
02687 }
02688 private:
02689 float slice_value;
02690 };
02691
02692
02697 class LinearPyramidProcessor:public Processor
02698 {
02699 public:
02700 string get_name() const
02701 {
02702 return NAME;
02703 }
02704
02705 void process_inplace(EMData *image);
02706
02707 static Processor *NEW()
02708 {
02709 return new LinearPyramidProcessor();
02710 }
02711
02712 string get_desc() const
02713 {
02714 return "Multiplies image by a 'linear pyramid', 1-(|x-xsize/2|*|y-ysize/2|*4/(xsize*ysize))";
02715 }
02716
02717 static const string NAME;
02718 };
02719
02720
02723 class MakeRadiusSquaredProcessor:public CircularMaskProcessor
02724 {
02725 public:
02726 string get_name() const
02727 {
02728 return NAME;
02729 }
02730 static Processor *NEW()
02731 {
02732 return new MakeRadiusSquaredProcessor();
02733 }
02734
02735 string get_desc() const
02736 {
02737 return "overwrites input, f(x) = radius * radius";
02738 }
02739
02740 static const string NAME;
02741
02742 protected:
02743 void process_dist_pixel(float *pixel, float dist) const
02744 {
02745 *pixel = dist;
02746 }
02747 };
02748
02751 class MakeRadiusProcessor:public CircularMaskProcessor
02752 {
02753 public:
02754 string get_name() const
02755 {
02756 return NAME;
02757 }
02758 static Processor *NEW()
02759 {
02760 return new MakeRadiusProcessor();
02761 }
02762
02763 string get_desc() const
02764 {
02765 return "overwrites input, f(x) = radius;";
02766 }
02767
02768 static const string NAME;
02769
02770 protected:
02771 void process_dist_pixel(float *pixel, float dist) const
02772 {
02773 *pixel = sqrt(dist);
02774 }
02775 };
02776
02779 class ComplexPixelProcessor:public Processor
02780 {
02781 public:
02782 void process_inplace(EMData * image);
02783
02784 static string get_group_desc()
02785 {
02786 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.";
02787 }
02788
02789 protected:
02790 virtual void process_pixel(float *x) const = 0;
02791 };
02792
02795 class ComplexNormPixel:public ComplexPixelProcessor
02796 {
02797 public:
02798 string get_name() const
02799 {
02800 return NAME;
02801 }
02802 static Processor *NEW()
02803 {
02804 return new ComplexNormPixel();
02805 }
02806
02807 string get_desc() const
02808 {
02809 return "Each Fourier pixel will be normalized. ie - amp=1, phase=unmodified. Useful for performing phase-residual-like computations with dot products.";
02810 }
02811
02812 static const string NAME;
02813
02814 protected:
02815 void process_pixel(float *x) const
02816 {
02817 *x=1.0;
02818 }
02819 };
02820
02824 class AreaProcessor:public Processor
02825 {
02826 public:
02827 AreaProcessor():areasize(0), kernel(0), nx(0), ny(0), nz(0)
02828 {
02829 }
02830
02831 void process_inplace(EMData * image);
02832
02833 void set_params(const Dict & new_params)
02834 {
02835 params = new_params;
02836 areasize = params["areasize"];
02837 }
02838
02839 TypeDict get_param_types() const
02840 {
02841 TypeDict d;
02842 d.put("areasize", EMObject::INT, "The width of the area to process (not radius)");
02843 return d;
02844 }
02845
02846 string get_desc() const
02847 {
02848 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().";
02849 }
02850
02851 protected:
02852 virtual void process_pixel(float *pixel, float, float, float, float *area_matrix) const
02853 {
02854 for (int i = 0; i < matrix_size; i++)
02855 {
02856 *pixel += area_matrix[i] * kernel[i];
02857 }
02858 }
02859
02860 virtual void create_kernel() const = 0;
02861
02862 int areasize;
02863 int matrix_size;
02864 float *kernel;
02865 int nx;
02866 int ny;
02867 int nz;
02868 };
02869
02872 class LaplacianProcessor:public AreaProcessor
02873 {
02874 public:
02875 string get_name() const
02876 {
02877 return NAME;
02878 }
02879 static Processor *NEW()
02880 {
02881 return new LaplacianProcessor();
02882 }
02883
02884 string get_desc() const
02885 {
02886 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).";
02887 }
02888
02889 static const string NAME;
02890
02891 protected:
02892 void create_kernel() const;
02893
02894 };
02895
02898 class ZeroConstantProcessor:public AreaProcessor
02899 {
02900 public:
02901 string get_name() const
02902 {
02903 return NAME;
02904 }
02905 static Processor *NEW()
02906 {
02907 return new ZeroConstantProcessor();
02908 }
02909
02910 string get_desc() const
02911 {
02912 return "Contraction of data, if any nearest neighbor is 0, value -> 0, generally used iteratively";
02913 }
02914
02915 static const string NAME;
02916
02917 protected:
02918 void process_pixel(float *pixel, float, float, float, float *matrix) const
02919 {
02920 if (*pixel != 0)
02921 {
02922 if (*pixel == matrix[1] || *pixel == matrix[3] || *pixel == matrix[5] ||
02923 *pixel == matrix[7] || matrix[1] == 0 || matrix[3] == 0 ||
02924 matrix[5] == 0 || matrix[7] == 0) {
02925 *pixel = 0;
02926 }
02927 }
02928 }
02929
02930 void create_kernel() const
02931 {
02932 }
02933 };
02934
02943 class BoxStatProcessor:public Processor
02944 {
02945 public:
02946 void process_inplace(EMData * image);
02947
02948 static string get_group_desc()
02949 {
02950 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).";
02951 }
02952
02953 TypeDict get_param_types() const
02954 {
02955 TypeDict d;
02956 d.put("radius", EMObject::INT, "The radius of the search box, default is 1 which results in a 3x3 box (3 = 2xradius + 1)");
02957 return d;
02958 }
02959
02960 protected:
02961 virtual void process_pixel(float *pixel, const float *array, int n) const = 0;
02962 };
02963
02964
02967 class BoxMedianProcessor:public BoxStatProcessor
02968 {
02969 public:
02970 string get_name() const
02971 {
02972 return NAME;
02973 }
02974 static Processor *NEW()
02975 {
02976 return new BoxMedianProcessor();
02977 }
02978
02979 string get_desc() const
02980 {
02981 return "A processor for noise reduction. pixel = median of values surrounding pixel.";
02982 }
02983
02984 static const string NAME;
02985
02986 protected:
02987 void process_pixel(float *pixel, const float *array, int n) const
02988 {
02989 float *data = new float[n];
02990 memcpy(data, array, sizeof(float) * n);
02991
02992 for (int i = 0; i <= n / 2; i++)
02993 {
02994 for (int j = i + 1; j < n; j++)
02995 {
02996 if (data[i] < data[j]) {
02997 float t = data[i];
02998 data[i] = data[j];
02999 data[j] = t;
03000 }
03001 }
03002 }
03003
03004 if (n % 2 != 0)
03005 {
03006 *pixel = data[n / 2];
03007 }
03008 else {
03009 *pixel = (data[n / 2] + data[n / 2 - 1]) / 2;
03010 }
03011 if( data )
03012 {
03013 delete[]data;
03014 data = 0;
03015 }
03016 }
03017 };
03018
03021 class BoxSigmaProcessor:public BoxStatProcessor
03022 {
03023 public:
03024 string get_name() const
03025 {
03026 return NAME;
03027 }
03028 static Processor *NEW()
03029 {
03030 return new BoxSigmaProcessor();
03031 }
03032
03033 string get_desc() const
03034 {
03035 return "pixel = standard deviation of values surrounding pixel.";
03036 }
03037
03038 static const string NAME;
03039
03040 protected:
03041 void process_pixel(float *pixel, const float *data, int n) const
03042 {
03043 float sum = 0;
03044 float square_sum = 0;
03045 for (int i = 0; i < n; i++)
03046 {
03047 sum += data[i];
03048 square_sum += data[i] * data[i];
03049 }
03050
03051 float mean = sum / n;
03052 *pixel = sqrt(square_sum / n - mean * mean);
03053 }
03054 };
03055
03058 class BoxMaxProcessor:public BoxStatProcessor
03059 {
03060 public:
03061 string get_name() const
03062 {
03063 return NAME;
03064 }
03065 static Processor *NEW()
03066 {
03067 return new BoxMaxProcessor();
03068 }
03069
03070 string get_desc() const
03071 {
03072 return "peak processor: pixel = max of values surrounding pixel.";
03073 }
03074
03075 static const string NAME;
03076
03077 protected:
03078 void process_pixel(float *pixel, const float *data, int n) const
03079 {
03080 float maxval = -FLT_MAX;
03081 for (int i = 0; i < n; i++)
03082 {
03083 if (data[i] > maxval) {
03084 maxval = data[i];
03085 }
03086 }
03087 *pixel = maxval;
03088 }
03089 };
03090
03093 class MinusPeakProcessor:public BoxStatProcessor
03094 {
03095 public:
03096 string get_name() const
03097 {
03098 return NAME;
03099 }
03100 static Processor *NEW()
03101 {
03102 return new MinusPeakProcessor();
03103 }
03104
03105 string get_desc() const
03106 {
03107 return "peak processor: pixel = pixel - max of values surrounding pixel. This is a sort of positive peak-finding algorithm.";
03108 }
03109
03110 static const string NAME;
03111
03112 protected:
03113 void process_pixel(float *pixel, const float *data, int n) const
03114 {
03115 float maxval = -FLT_MAX;
03116 for (int i = 0; i < n; i++)
03117 {
03118 if (data[i] > maxval) {
03119 maxval = data[i];
03120 }
03121 }
03122 *pixel -= maxval;
03123 }
03124 };
03125
03129 class PeakOnlyProcessor:public BoxStatProcessor
03130 {
03131 public:
03132 string get_name() const
03133 {
03134 return NAME;
03135 }
03136 static Processor *NEW()
03137 {
03138 return new PeakOnlyProcessor();
03139 }
03140 void set_params(const Dict & new_params)
03141 {
03142 params = new_params;
03143 npeaks = params["npeaks"];
03144 if (npeaks == 0) {
03145 npeaks = 1;
03146 }
03147 }
03148
03149 TypeDict get_param_types() const
03150 {
03151 TypeDict d;
03152 d.put("npeaks", EMObject::INT, "the number of surrounding peaks allow to >= pixel values");
03153 return d;
03154 }
03155
03156 string get_desc() const
03157 {
03158 return "peak processor -> if npeaks or more surrounding values >= value, value->0";
03159 }
03160
03161 static const string NAME;
03162
03163 protected:
03164 void process_pixel(float *pixel, const float *data, int n) const
03165 {
03166 int r = 0;
03167
03168 for (int i = 0; i < n; i++)
03169 {
03170 if (data[i] >= *pixel) {
03171 r++;
03172 }
03173 }
03174
03175 if (r > npeaks)
03176 {
03177 *pixel = 0;
03178 }
03179 }
03180 private:
03181 int npeaks;
03182 };
03183
03188 class DiffBlockProcessor:public Processor
03189 {
03190 public:
03191 void process_inplace(EMData * image);
03192
03193 string get_name() const
03194 {
03195 return NAME;
03196 }
03197 static Processor *NEW()
03198 {
03199 return new DiffBlockProcessor();
03200 }
03201
03202 string get_desc() const
03203 {
03204 return "averages over cal_half_width, then sets the value in a local block";
03205 }
03206
03207 TypeDict get_param_types() const
03208 {
03209 TypeDict d;
03210 d.put("cal_half_width", EMObject::FLOAT, "cal_half_width is dx/dy for calculating an average");
03211 d.put("fill_half_width", EMObject::FLOAT, "fill_half_width is dx/dy for fill/step");
03212 return d;
03213 }
03214
03215 static const string NAME;
03216 };
03217
03222 class CutoffBlockProcessor:public Processor
03223 {
03224 public:
03225 void process_inplace(EMData * image);
03226
03227 string get_name() const
03228 {
03229 return NAME;
03230 }
03231 static Processor *NEW()
03232 {
03233 return new CutoffBlockProcessor();
03234 }
03235
03236 TypeDict get_param_types() const
03237 {
03238 TypeDict d;
03239 d.put("value1", EMObject::FLOAT, "val1 is dx/dy");
03240 d.put("value2", EMObject::FLOAT, "val2 is lowpass freq cutoff in pixels");
03241 return d;
03242 }
03243
03244 string get_desc() const
03245 {
03246 return "Block processor, val1 is dx/dy, val2 is lp freq cutoff in pixels. Mystery processor.";
03247 }
03248
03249 static const string NAME;
03250 };
03251
03257 class BooleanShrinkProcessor
03258 {
03259 protected:
03267 template<class LogicOp>
03268 EMData* process(const EMData *const image, Dict& params);
03269
03276 template<class LogicOp>
03277 void process_inplace(EMData * image, Dict& params);
03278
03279 };
03280
03289 class MaxShrinkProcessor:public BooleanShrinkProcessor, public Processor
03290 {
03291 public:
03298 virtual EMData* process(const EMData *const image)
03299 {
03300 return BooleanShrinkProcessor::process<GreaterThan>(image, params);
03301 }
03302
03303
03304 virtual void process_inplace(EMData * image)
03305 {
03306 BooleanShrinkProcessor::process_inplace<GreaterThan>(image, params);
03307 }
03308
03309 string get_desc() const
03310 {
03311 return "Shrink an image by a given amount (default 2), using the maximum value found in the pixel neighborhood.";
03312 }
03313
03314 string get_name() const
03315 {
03316 return NAME;
03317 }
03318 static Processor *NEW()
03319 {
03320 return new MaxShrinkProcessor();
03321 }
03322
03323 TypeDict get_param_types() const
03324 {
03325 TypeDict d;
03326 d.put("n", EMObject::INT, "The shrink factor");
03327 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03328 return d;
03329 }
03330
03331 static const string NAME;
03332
03333 private:
03334 struct GreaterThan
03335 {
03336 inline bool operator()(float left,float right) const { return left > right; }
03337 inline float get_start_val() { return -10000000; }
03338 };
03339 };
03340
03349 class MinShrinkProcessor:public BooleanShrinkProcessor, public Processor
03350 {
03351 public:
03358 virtual EMData* process(const EMData *const image)
03359 {
03360 return BooleanShrinkProcessor::process<LessThan>(image, params);
03361 }
03362
03363
03364 virtual void process_inplace(EMData * image)
03365 {
03366 BooleanShrinkProcessor::process_inplace<LessThan>(image, params);
03367 }
03368 string get_desc() const
03369 {
03370 return "Shrink an image by a given amount (default 2), using the minimum value found in the pixel neighborhood.";
03371 }
03372
03373 string get_name() const
03374 {
03375 return NAME;
03376 }
03377 static Processor *NEW()
03378 {
03379 return new MinShrinkProcessor();
03380 }
03381
03382 TypeDict get_param_types() const
03383 {
03384 TypeDict d;
03385 d.put("n", EMObject::INT, "The shrink factor");
03386 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03387 return d;
03388 }
03389
03390 static const string NAME;
03391
03392 private:
03393 struct LessThan
03394 {
03395 inline bool operator()(float left,float right) const { return left < right; }
03396 inline float get_start_val() { return 9999999999.0f; }
03397 };
03398 };
03399
03406 class MeanShrinkProcessor : public Processor
03407 {
03408 public:
03419 virtual EMData* process(const EMData *const image);
03420
03427 virtual void process_inplace(EMData * image);
03428
03429 string get_desc() const
03430 {
03431 return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
03432 }
03433
03434 virtual string get_name() const
03435 {
03436 return NAME;
03437 }
03438 static Processor *NEW()
03439 {
03440 return new MeanShrinkProcessor();
03441 }
03442
03443 virtual TypeDict get_param_types() const
03444 {
03445 TypeDict d;
03446 d.put("n", EMObject::FLOAT, "The shrink factor");
03447 return d;
03448 }
03449
03450 static const string NAME;
03451
03452 private:
03460 void accrue_mean(EMData* to, const EMData *const from, const int shrinkfactor);
03461
03468 void accrue_mean_one_p_five(EMData* to, const EMData * const from);
03469 };
03470
03471
03478 class MedianShrinkProcessor : public Processor
03479 {
03480 public:
03491 virtual EMData* process(const EMData *const image);
03492
03499 virtual void process_inplace(EMData * image);
03500
03501 string get_desc() const
03502 {
03503 return "Shrink an image by a given amount , using the median value found in the pixel neighborhood.";
03504 }
03505
03506 virtual string get_name() const
03507 {
03508 return NAME;
03509 }
03510 static Processor *NEW()
03511 {
03512 return new MedianShrinkProcessor();
03513 }
03514
03515 virtual TypeDict get_param_types() const
03516 {
03517 TypeDict d;
03518 d.put("n", EMObject::INT, "The shrink factor");
03519 return d;
03520 }
03521
03522 static const string NAME;
03523
03524 private:
03532 void accrue_median(EMData* to, const EMData* const from,const int shrink_factor);
03533 };
03534
03535
03544 class FFTResampleProcessor : public Processor
03545 {
03546 public:
03547 virtual EMData* process(const EMData *const image);
03548
03549 virtual void process_inplace(EMData * image);
03550
03551 string get_desc() const
03552 {
03553 return "Robust resampling of an image by clipping its Fourier transform.";
03554 }
03555
03556 string get_name() const
03557 {
03558 return NAME;
03559 }
03560 static Processor *NEW()
03561 {
03562 return new FFTResampleProcessor();
03563 }
03564
03565 TypeDict get_param_types() const
03566 {
03567 TypeDict d;
03568 d.put("n", EMObject::FLOAT, "The sample rate. Less than one enlarges the image, greater than one shrinks it.");
03569 return d;
03570 }
03571
03572 static const string NAME;
03573
03574 private:
03581 void fft_resample(EMData* to, const EMData *const from, const float& sample_rate);
03582
03583 };
03584
03587 class GradientRemoverProcessor:public Processor
03588 {
03589 public:
03590 void process_inplace(EMData * image);
03591
03592 string get_name() const
03593 {
03594 return NAME;
03595 }
03596 static Processor *NEW()
03597 {
03598 return new GradientRemoverProcessor();
03599 }
03600
03601 string get_desc() const
03602 {
03603 return "Gradient remover, does a rough plane fit to find linear gradients.";
03604 }
03605
03606 static const string NAME;
03607 };
03608
03617 class GradientPlaneRemoverProcessor:public Processor
03618 {
03619 public:
03620 void process_inplace(EMData * image);
03621
03622 string get_name() const
03623 {
03624 return NAME;
03625 }
03626 static Processor *NEW()
03627 {
03628 return new GradientPlaneRemoverProcessor();
03629 }
03630
03631 string get_desc() const
03632 {
03633 return "Remove gradient by least square plane fit";
03634 }
03635
03636 TypeDict get_param_types() const
03637 {
03638 TypeDict d;
03639 d.put("mask", EMObject::EMDATA, "mask object: nonzero pixel positions will be used to fit plane. default = 0");
03640 d.put("changeZero", EMObject::INT, "if zero pixels are modified when removing gradient. default = 0");
03641 d.put("planeParam", EMObject::FLOATARRAY, "fitted plane parameters output");
03642 return d;
03643 }
03644
03645 static const string NAME;
03646 };
03647
03648
03655 class FlattenBackgroundProcessor:public Processor
03656 {
03657 public:
03658 void process_inplace(EMData * image);
03659
03660 string get_name() const
03661 {
03662 return NAME;
03663 }
03664
03665 static Processor *NEW()
03666 {
03667 return new FlattenBackgroundProcessor();
03668 }
03669
03670 string get_desc() const
03671 {
03672 return "Flattens the background by subtracting the local mean";
03673 }
03674
03675 TypeDict get_param_types() const
03676 {
03677 TypeDict d;
03678 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");
03679 d.put("radius", EMObject::INT, "The radius of circle/sphere that defines the local neighborhood. Exclusive of the mask argument");
03680 return d;
03681 }
03682
03683 static const string NAME;
03684 };
03685
03686
03689 class RampProcessor:public Processor
03690 {
03691 public:
03692 void process_inplace(EMData * image);
03693
03694 string get_name() const
03695 {
03696 return NAME;
03697 }
03698 static Processor *NEW()
03699 {
03700 return new RampProcessor();
03701 }
03702
03703 string get_desc() const
03704 {
03705 return "Ramp processor -- Fits a least-squares plane "
03706 "to the picture, and subtracts the plane from "
03707 "the picture. A wedge-shaped overall density "
03708 "profile can thus be removed from the picture.";
03709 }
03710
03711 static const string NAME;
03712 };
03713
03716 class VerticalStripeProcessor:public Processor
03717 {
03718 public:
03719 void process_inplace(EMData * image);
03720
03721 string get_name() const
03722 {
03723 return NAME;
03724 }
03725
03726 static Processor *NEW()
03727 {
03728 return new VerticalStripeProcessor();
03729 }
03730
03731 string get_desc() const
03732 {
03733 return "Tries to fix images scanned on the zeiss for poor ccd normalization.";
03734 }
03735
03736 static const string NAME;
03737 };
03738
03741 class RealToFFTProcessor:public Processor
03742 {
03743 public:
03744 void process_inplace(EMData *image);
03745
03746 string get_name() const
03747 {
03748 return NAME;
03749 }
03750
03751 static Processor *NEW()
03752 {
03753 return new RealToFFTProcessor();
03754 }
03755
03756 string get_desc() const
03757 {
03758 return "This will replace the image with a full-circle 2D fft amplitude rendering. Note that this renders amplitude, when intensity is more common.";
03759 }
03760
03761 static const string NAME;
03762 };
03763
03764
03767 class SigmaZeroEdgeProcessor:public Processor
03768 {
03769 public:
03770 void process_inplace(EMData * image);
03771
03772 string get_name() const
03773 {
03774 return NAME;
03775 }
03776 static Processor *NEW()
03777 {
03778 return new SigmaZeroEdgeProcessor();
03779 }
03780
03781 string get_desc() const
03782 {
03783 return "Fill zeroes at edges with nearest horizontal/vertical value.";
03784 }
03785
03786 static const string NAME;
03787 };
03788
03794 class BeamstopProcessor:public Processor
03795 {
03796 public:
03797 void process_inplace(EMData * image);
03798
03799 string get_name() const
03800 {
03801 return NAME;
03802 }
03803
03804 static Processor *NEW()
03805 {
03806 return new BeamstopProcessor();
03807 }
03808
03809 string get_desc() const
03810 {
03811 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.";
03812 }
03813
03814 TypeDict get_param_types() const
03815 {
03816 TypeDict d;
03817 d.put("value1", EMObject::FLOAT, "sig multiplier");
03818 d.put("value2", EMObject::FLOAT, "x of center");
03819 d.put("value3", EMObject::FLOAT, "y of center");
03820 return d;
03821 }
03822
03823 static const string NAME;
03824 };
03825
03828 class MeanZeroEdgeProcessor:public Processor
03829 {
03830 public:
03831 void process_inplace(EMData * image);
03832
03833 string get_name() const
03834 {
03835 return NAME;
03836 }
03837
03838 static Processor *NEW()
03839 {
03840 return new MeanZeroEdgeProcessor();
03841 }
03842
03843 string get_desc() const
03844 {
03845 return "Fill zeroes at edges with nearest horizontal/vertical value damped towards Mean2.";
03846 }
03847
03848 static const string NAME;
03849 };
03850
03851
03854 class AverageXProcessor:public Processor
03855 {
03856 public:
03857 void process_inplace(EMData * image);
03858
03859 string get_name() const
03860 {
03861 return NAME;
03862 }
03863
03864 static Processor *NEW()
03865 {
03866 return new AverageXProcessor();
03867 }
03868
03869 string get_desc() const
03870 {
03871 return "Average along Y and replace with average";
03872 }
03873
03874 static const string NAME;
03875 };
03876
03880 class DecayEdgeProcessor:public Processor
03881 {
03882 public:
03883 void process_inplace(EMData * image);
03884 string get_name() const
03885 {
03886 return NAME;
03887 }
03888
03889 static Processor *NEW()
03890 {
03891 return new DecayEdgeProcessor();
03892 }
03893
03894 string get_desc() const
03895 {
03896 return "Decay edges of image to zero";
03897 }
03898
03899 TypeDict get_param_types() const
03900 {
03901 TypeDict d;
03902 d.put("width", EMObject::INT, "Width of the decay region around the edge of the image in pixels");
03903 return d;
03904 }
03905
03906 static const string NAME;
03907 };
03908
03915 class ZeroEdgeRowProcessor:public Processor
03916 {
03917 public:
03918 void process_inplace(EMData * image);
03919 string get_name() const
03920 {
03921 return NAME;
03922 }
03923
03924 static Processor *NEW()
03925 {
03926 return new ZeroEdgeRowProcessor();
03927 }
03928
03929 string get_desc() const
03930 {
03931 return "zero edges of image on top and bottom, and on left and right.";
03932 }
03933
03934 TypeDict get_param_types() const
03935 {
03936 TypeDict d;
03937 d.put("x0", EMObject::INT, "The number of columns to zero from left");
03938 d.put("x1", EMObject::INT, "The number of columns to zero from right");
03939 d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
03940 d.put("y1", EMObject::INT, "The number of rows to zero from the top");
03941 return d;
03942 }
03943
03944 static const string NAME;
03945 };
03946
03955 class ZeroEdgePlaneProcessor:public Processor
03956 {
03957 public:
03958 void process_inplace(EMData * image);
03959 string get_name() const
03960 {
03961 return NAME;
03962 }
03963
03964 static Processor *NEW()
03965 {
03966 return new ZeroEdgePlaneProcessor();
03967 }
03968
03969 string get_desc() const
03970 {
03971 return "zero edges of volume on all sides";
03972 }
03973
03974 TypeDict get_param_types() const
03975 {
03976 TypeDict d;
03977 d.put("x0", EMObject::INT, "The number of columns to zero from left");
03978 d.put("x1", EMObject::INT, "The number of columns to zero from right");
03979 d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
03980 d.put("y1", EMObject::INT, "The number of rows to zero from the top");
03981 d.put("z0", EMObject::INT, "The number of slices to zero from the bottom");
03982 d.put("z1", EMObject::INT, "The number of slices to zero from the top");
03983 return d;
03984 }
03985
03986 static const string NAME;
03987 };
03988
03989
03996 class BilateralProcessor:public Processor
03997 {
03998 public:
03999 void process_inplace(EMData * image);
04000 string get_name() const
04001 {
04002 return NAME;
04003 }
04004
04005 string get_desc() const
04006 {
04007 return "Bilateral processing on 2D or 3D volume data. Bilateral processing does non-linear weighted averaging processing within a certain window. ";
04008 }
04009
04010 static Processor *NEW()
04011 {
04012 return new BilateralProcessor();
04013 }
04014
04015 TypeDict get_param_types() const
04016 {
04017 TypeDict d;
04018 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.");
04019 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.");
04020 d.put("niter", EMObject::INT, "how many times to apply this processing on your data.");
04021 d.put("half_width", EMObject::INT, "processing window size = (2 * half_widthh + 1) ^ 3.");
04022 return d;
04023 }
04024
04025 static const string NAME;
04026 };
04027
04030 class NormalizeProcessor:public Processor
04031 {
04032 public:
04033 void process_inplace(EMData * image);
04034
04035 static string get_group_desc()
04036 {
04037 return "Base class for normalization processors. Each specific normalization processor needs to define how to calculate mean and how to calculate sigma.";
04038 }
04039
04040 protected:
04041 virtual float calc_sigma(EMData * image) const;
04042 virtual float calc_mean(EMData * image) const = 0;
04043 };
04044
04047 class NormalizeUnitProcessor:public NormalizeProcessor
04048 {
04049 public:
04050 string get_name() const
04051 {
04052 return NAME;
04053 }
04054
04055 static Processor *NEW()
04056 {
04057 return new NormalizeUnitProcessor();
04058 }
04059
04060 string get_desc() const
04061 {
04062 return "Normalize an image so its vector length is 1.0.";
04063 }
04064
04065 static const string NAME;
04066
04067 protected:
04068 float calc_sigma(EMData * image) const;
04069 float calc_mean(EMData * image) const;
04070 };
04071
04072 inline float NormalizeUnitProcessor::calc_mean(EMData *) const { return 0; }
04073
04076 class NormalizeUnitSumProcessor:public NormalizeProcessor
04077 {
04078 public:
04079 string get_name() const
04080 {
04081 return NAME;
04082 }
04083
04084 static Processor *NEW()
04085 {
04086 return new NormalizeUnitSumProcessor();
04087 }
04088
04089 string get_desc() const
04090 {
04091 return "Normalize an image so its elements sum to 1.0 (fails if mean=0)";
04092 }
04093
04094 static const string NAME;
04095
04096 protected:
04097 float calc_sigma(EMData * image) const;
04098 float calc_mean(EMData * image) const;
04099 };
04100
04101 inline float NormalizeUnitSumProcessor::calc_mean(EMData *) const { return 0; }
04102
04103
04106 class NormalizeStdProcessor:public NormalizeProcessor
04107 {
04108 public:
04109 string get_name() const
04110 {
04111 return NAME;
04112 }
04113
04114 static Processor *NEW()
04115 {
04116 return new NormalizeStdProcessor();
04117 }
04118
04119 string get_desc() const
04120 {
04121 return "do a standard normalization on an image.";
04122 }
04123
04124 static const string NAME;
04125
04126 protected:
04127 float calc_mean(EMData * image) const;
04128 };
04129
04134 class NormalizeMaskProcessor:public NormalizeProcessor
04135 {
04136 public:
04137 string get_name() const
04138 {
04139 return NAME;
04140 }
04141
04142 string get_desc() const
04143 {
04144 return "Uses a 1/0 mask defining a region to use for the zero-normalization.if no_sigma is 1, standard deviation not modified.";
04145 }
04146
04147 static Processor *NEW()
04148 {
04149 return new NormalizeMaskProcessor();
04150 }
04151
04152 TypeDict get_param_types() const
04153 {
04154 TypeDict d;
04155 d.put("mask", EMObject::EMDATA, "the 1/0 mask defining a region to use for the zero-normalization");
04156 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");
04157 return d;
04158 }
04159
04160 static const string NAME;
04161
04162 protected:
04163 float calc_sigma(EMData * image) const;
04164 float calc_mean(EMData * image) const;
04165 };
04166
04172 class NormalizeRampNormVar: public Processor
04173 {
04174 public:
04175 string get_name() const
04176 {
04177 return NAME;
04178 }
04179
04180 static Processor *NEW()
04181 {
04182 return new NormalizeRampNormVar();
04183 }
04184
04185 string get_desc() const
04186 {
04187 return "First call filter.ramp on the image, then make the mean 0 and norm 1";
04188 }
04189
04190 void process_inplace(EMData * image);
04191
04192 static const string NAME;
04193 };
04194
04203 class NormalizeByMassProcessor: public Processor
04204 {
04205 public:
04206 string get_name() const
04207 {
04208 return NAME;
04209 }
04210
04211 static Processor *NEW()
04212 {
04213 return new NormalizeByMassProcessor();
04214 }
04215
04216 string get_desc() const
04217 {
04218 return "Normalize the mass of the image assuming a density of 1.35 g/ml (0.81 Da/A^3) (3D only)";
04219 }
04220
04221 TypeDict get_param_types() const
04222 {
04223 TypeDict d;
04224 d.put("apix", EMObject::FLOAT,"Angstrom per pixel of the image. If not set will use the apix_x attribute of the image");
04225 d.put("mass", EMObject::FLOAT,"The approximate mass of protein/structure in kilodaltons");
04226 d.put("thr", EMObject::FLOAT,"The isosurface threshold which encapsulates the structure");
04227 return d;
04228 }
04229
04230 void process_inplace(EMData * image);
04231
04232 static const string NAME;
04233 };
04234
04235
04238 class NormalizeEdgeMeanProcessor:public NormalizeProcessor
04239 {
04240 public:
04241 string get_name() const
04242 {
04243 return NAME;
04244 }
04245
04246 static Processor *NEW()
04247 {
04248 return new NormalizeEdgeMeanProcessor();
04249 }
04250
04251 string get_desc() const
04252 {
04253 return "normalizes an image, mean value equals to edge mean.";
04254 }
04255
04256 static const string NAME;
04257
04258 protected:
04259 float calc_mean(EMData * image) const;
04260 };
04261
04264 class NormalizeCircleMeanProcessor:public NormalizeProcessor
04265 {
04266 public:
04267 string get_name() const
04268 {
04269 return NAME;
04270 }
04271
04272 static Processor *NEW()
04273 {
04274 return new NormalizeCircleMeanProcessor();
04275 }
04276
04277 string get_desc() const
04278 {
04279 return "normalizes an image, mean value equals to mean of 2 pixel circular border.";
04280 }
04281
04282 static const string NAME;
04283
04284 protected:
04285 float calc_mean(EMData * image) const;
04286 };
04287
04290 class NormalizeLREdgeMeanProcessor:public NormalizeProcessor
04291 {
04292 public:
04293 string get_name() const
04294 {
04295 return NAME;
04296 }
04297
04298 static Processor *NEW()
04299 {
04300 return new NormalizeLREdgeMeanProcessor();
04301 }
04302
04303 string get_desc() const
04304 {
04305 return "normalizes an image, uses 2 pixels on left and right edge";
04306 }
04307
04308 static const string NAME;
04309
04310 protected:
04311 float calc_mean(EMData * image) const;
04312 };
04313
04316 class NormalizeMaxMinProcessor:public NormalizeProcessor
04317 {
04318 public:
04319 string get_name() const
04320 {
04321 return NAME;
04322 }
04323
04324 static Processor *NEW()
04325 {
04326 return new NormalizeMaxMinProcessor();
04327 }
04328
04329 string get_desc() const
04330 {
04331 return "normalizes an image. mean -> (maxval-minval)/2; std dev = (maxval+minval)/2;";
04332 }
04333
04334 static const string NAME;
04335
04336 protected:
04337 float calc_sigma(EMData * image) const;
04338 float calc_mean(EMData * image) const;
04339 };
04340
04343 class NormalizeRowProcessor:public Processor
04344 {
04345 public:
04346 string get_name() const
04347 {
04348 return NAME;
04349 }
04350
04351 static Processor *NEW()
04352 {
04353 return new NormalizeRowProcessor();
04354 }
04355
04356 string get_desc() const
04357 {
04358 return "normalizes each row in the image individually";
04359 }
04360
04361 static const string NAME;
04362
04363 void process_inplace(EMData * image);
04364 };
04365
04371 class NormalizeToLeastSquareProcessor:public Processor
04372 {
04373 public:
04374 void process_inplace(EMData * image);
04375
04376 string get_name() const
04377 {
04378 return NAME;
04379 }
04380
04381 static Processor *NEW()
04382 {
04383 return new NormalizeToLeastSquareProcessor();
04384 }
04385
04386 TypeDict get_param_types() const
04387 {
04388 TypeDict d;
04389 d.put("to", EMObject::EMDATA, "reference image normalize to");
04390 d.put("ignore_zero", EMObject::BOOL, "If set, ignores any pixels which are exactly zero in either image. Defaut = True.");
04391 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)");
04392 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)");
04393 return d;
04394 }
04395
04396 string get_desc() const
04397 {
04398 return "use least square method to normalize";
04399 }
04400
04401 static const string NAME;
04402 };
04403
04406 class RotationalAverageProcessor:public Processor
04407 {
04408 public:
04409 void process_inplace(EMData * image);
04410
04411 string get_name() const
04412 {
04413 return NAME;
04414 }
04415
04416 static Processor *NEW()
04417 {
04418 return new RotationalAverageProcessor();
04419 }
04420
04421 string get_desc() const
04422 {
04423 return "Makes image circularly/spherically symmetric.";
04424 }
04425
04426 static const string NAME;
04427 };
04428
04431 class RotationalSubstractProcessor:public Processor
04432 {
04433 public:
04434 virtual void process_inplace(EMData * image);
04435
04436 virtual string get_name() const
04437 {
04438 return NAME;
04439 }
04440
04441 static Processor *NEW()
04442 {
04443 return new RotationalSubstractProcessor();
04444 }
04445
04446 virtual string get_desc() const
04447 {
04448 return "subtracts circularly/spherically symmetric part of an image.";
04449 }
04450
04451 static const string NAME;
04452 };
04453
04459 class TransposeProcessor:public Processor
04460 {
04461 public:
04462
04467 virtual void process_inplace(EMData * image);
04468
04473 virtual EMData* process(const EMData * const image);
04474
04475 virtual string get_name() const
04476 {
04477 return NAME;
04478 }
04479
04480 static Processor *NEW()
04481 {
04482 return new TransposeProcessor();
04483 }
04484
04485 virtual TypeDict get_param_types() const
04486 {
04487 TypeDict d;
04488 return d;
04489 }
04490
04491 virtual string get_desc() const
04492 {
04493 return "Get the transpose of an image. Works for 2D only";
04494 }
04495
04496 static const string NAME;
04497 };
04498
04499
04503 class FlipProcessor:public Processor
04504 {
04505 public:
04506 virtual void process_inplace(EMData * image);
04507
04508 virtual string get_name() const
04509 {
04510 return NAME;
04511 }
04512
04513 static Processor *NEW()
04514 {
04515 return new FlipProcessor();
04516 }
04517
04518 virtual TypeDict get_param_types() const
04519 {
04520 TypeDict d;
04521 d.put("axis", EMObject::STRING, "'x', 'y', or 'z' axis.");
04522 return d;
04523 }
04524
04525 virtual string get_desc() const
04526 {
04527 return "Mirrors an image along the specified axis, preserving the center. This will introduce a plane of 0's for even box sizes. Use 'xform.mirror' processor to avoid the zero plane, but not preserve the center.";
04528 }
04529
04530 static const string NAME;
04531 };
04532
04533
04534
04535
04536
04537
04538
04539
04540
04541
04542
04543
04544
04545
04546
04547
04548
04549
04550
04551
04552
04553
04554
04555
04556
04557
04558
04559
04560
04561
04566 class AddNoiseProcessor:public Processor
04567 {
04568 public:
04569 virtual void process_inplace(EMData * image);
04570
04571 virtual string get_name() const
04572 {
04573 return NAME;
04574 }
04575
04576 static Processor *NEW()
04577 {
04578 return new AddNoiseProcessor();
04579 }
04580
04581 virtual TypeDict get_param_types() const
04582 {
04583 TypeDict d;
04584 d.put("noise", EMObject::FLOAT, "noise factor used to generate Gaussian distribution random noise");
04585 d.put("seed", EMObject::INT, "seed for random number generator");
04586 return d;
04587 }
04588
04589 virtual string get_desc() const
04590 {
04591 return "add noise to an image, image multiply by noise then add a random value";
04592 }
04593
04594 static const string NAME;
04595
04596 protected:
04597 virtual float get_sigma(EMData *)
04598 {
04599 return 1.0;
04600 }
04601 };
04602
04605 class AddSigmaNoiseProcessor:public AddNoiseProcessor
04606 {
04607 public:
04608 virtual string get_name() const
04609 {
04610 return NAME;
04611 }
04612
04613 static Processor *NEW()
04614 {
04615 return new AddSigmaNoiseProcessor();
04616 }
04617
04618 virtual string get_desc() const
04619 {
04620 return "add sigma noise.";
04621 }
04622
04623 static const string NAME;
04624
04625 protected:
04626 float get_sigma(EMData * image);
04627 };
04628
04637 class AddRandomNoiseProcessor:public Processor
04638 {
04639 public:
04640 virtual void process_inplace(EMData * image);
04641
04642 virtual string get_name() const
04643 {
04644 return NAME;
04645 }
04646
04647 static Processor *NEW()
04648 {
04649 return new AddRandomNoiseProcessor();
04650 }
04651
04652 virtual TypeDict get_param_types() const
04653 {
04654 TypeDict d;
04655 d.put("n", EMObject::INT);
04656 d.put("x0", EMObject::FLOAT);
04657 d.put("dx", EMObject::FLOAT);
04658 d.put("y", EMObject::FLOATARRAY);
04659 d.put("interpolation", EMObject::INT);
04660 d.put("seed", EMObject::INT, "seed for random number generator");
04661 return d;
04662 }
04663
04664 virtual string get_desc() const
04665 {
04666 return "add spectral noise to a complex image.";
04667 }
04668
04669 static const string NAME;
04670 };
04671
04677 class FourierToCornerProcessor:public Processor
04678 {
04679 public:
04685 virtual void process_inplace(EMData * image);
04686
04687 virtual string get_name() const
04688 {
04689 return NAME;
04690 }
04691
04692 static Processor *NEW()
04693 {
04694 return new FourierToCornerProcessor();
04695 }
04696
04697 virtual string get_desc() const
04698 {
04699 return "Undoes the xform.fourierorigin.tocenter processor";
04700 }
04701
04702 static const string NAME;
04703 };
04704
04705
04717 class FourierToCenterProcessor:public Processor
04718 {
04719 public:
04725 virtual void process_inplace(EMData * image);
04726
04727 virtual string get_name() const
04728 {
04729 return NAME;
04730 }
04731
04732 static Processor *NEW()
04733 {
04734 return new FourierToCenterProcessor();
04735 }
04736
04737 virtual string get_desc() const
04738 {
04739 return "Translates the origin in Fourier space from the corner to the center in y and z - works in 2D and 3D";
04740 }
04741
04742 static const string NAME;
04743 };
04744
04754 class Phase180Processor:public Processor
04755 {
04756 protected:
04769 void swap_corners_180(EMData * image);
04770
04782 void swap_central_slices_180(EMData * image);
04783
04790 void fourier_phaseshift180(EMData * image);
04791
04792 };
04793
04803 class PhaseToCenterProcessor:public Phase180Processor
04804 {
04805 public:
04806 virtual void process_inplace(EMData * image);
04807
04808 virtual string get_name() const
04809 {
04810 return NAME;
04811 }
04812
04813 static Processor *NEW()
04814 {
04815 return new PhaseToCenterProcessor();
04816 }
04817
04818 virtual string get_desc() const
04819 {
04820 return "Undoes the effect of the xform.phaseorigin.tocorner processor";
04821 }
04822
04823 static const string NAME;
04824 };
04825
04833 class PhaseToCornerProcessor:public Phase180Processor
04834 {
04835 public:
04836 virtual void process_inplace(EMData * image);
04837
04838 virtual string get_name() const
04839 {
04840 return NAME;
04841 }
04842
04843 static Processor *NEW()
04844 {
04845 return new PhaseToCornerProcessor();
04846 }
04847
04848 virtual string get_desc() const
04849 {
04850 return "Translates a centered image to the corner in a forward fashion";
04851 }
04852
04853 static const string NAME;
04854 };
04855
04860 class AutoMask2DProcessor:public Processor
04861 {
04862 public:
04863 virtual void process_inplace(EMData * image);
04864
04865 virtual string get_name() const
04866 {
04867 return NAME;
04868 }
04869
04870 static Processor *NEW()
04871 {
04872 return new AutoMask2DProcessor();
04873 }
04874
04875 virtual TypeDict get_param_types() const
04876 {
04877 TypeDict d;
04878 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
04879 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
04880 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
04881 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
04882 d.put("nshells", EMObject::INT, "The number of dilation operations");
04883 d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
04884 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
04885 d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
04886 return d;
04887 }
04888
04889 virtual string get_desc() const
04890 {
04891 return "2D version of mask.auto3d";
04892 }
04893
04894 static const string NAME;
04895 };
04896
04897
04904 class AutoMaskAsymUnit:public Processor
04905 {
04906 public:
04907 virtual void process_inplace(EMData * image);
04908
04909 virtual string get_name() const
04910 {
04911 return NAME;
04912 }
04913
04914 static Processor *NEW()
04915 {
04916 return new AutoMaskAsymUnit();
04917 }
04918
04919 virtual TypeDict get_param_types() const
04920 {
04921 TypeDict d;
04922 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.");
04923 d.put("sym", EMObject::STRING, "The symmetry, for example, d7");
04924 return d;
04925 }
04926
04927 virtual string get_desc() const
04928 {
04929 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.";
04930 }
04931
04932 static const string NAME;
04933 };
04934
04939 class AutoMask3DProcessor:public Processor
04940 {
04941 public:
04942 virtual void process_inplace(EMData * image);
04943
04944 virtual string get_name() const
04945 {
04946 return NAME;
04947 }
04948
04949 static Processor *NEW()
04950 {
04951 return new AutoMask3DProcessor();
04952 }
04953
04954 virtual TypeDict get_param_types() const
04955 {
04956 TypeDict d;
04957 d.put("threshold1", EMObject::FLOAT);
04958 d.put("threshold2", EMObject::FLOAT);
04959 return d;
04960 }
04961
04962 virtual string get_desc() const
04963 {
04964 return "Tries to mask out only interesting density";
04965 }
04966
04967 static void search_nearby(float *dat, float *dat2, int nx, int ny, int nz, float thr);
04968 static void fill_nearby(float *dat2, int nx, int ny, int nz);
04969
04970 static const string NAME;
04971 };
04972
04980 class AutoMask3D2Processor:public Processor
04981 {
04982 public:
04983 virtual void process_inplace(EMData * image);
04984
04985 virtual string get_name() const
04986 {
04987 return NAME;
04988 }
04989
04990 static Processor *NEW()
04991 {
04992 return new AutoMask3D2Processor();
04993 }
04994
04995 virtual string get_desc() const
04996 {
04997 return "Tries to mask out only interesting density using something akin to a flood file approach.";
04998 }
04999
05000 virtual TypeDict get_param_types() const
05001 {
05002 TypeDict d;
05003 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
05004 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
05005 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
05006 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
05007 d.put("nshells", EMObject::INT, "The number of dilation operations");
05008 d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
05009 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
05010 d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
05011 return d;
05012 }
05013
05014 static const string NAME;
05015 };
05016
05020 class AddMaskShellProcessor:public Processor
05021 {
05022 public:
05023 virtual void process_inplace(EMData * image);
05024
05025 virtual string get_name() const
05026 {
05027 return NAME;
05028 }
05029
05030 virtual string get_desc() const
05031 {
05032 return "Add additional shells/rings to an existing 1/0 mask image";
05033 }
05034
05035 static Processor *NEW()
05036 {
05037 return new AddMaskShellProcessor();
05038 }
05039
05040 virtual TypeDict get_param_types() const
05041 {
05042 TypeDict d;
05043 d.put("nshells", EMObject::INT, "number of shells to add");
05044 return d;
05045 }
05046
05047 static const string NAME;
05048 };
05049
05054 class PhaseToMassCenterProcessor:public Processor
05055 {
05056 public:
05057 virtual void process_inplace(EMData * image);
05058
05059 virtual string get_name() const
05060 {
05061 return NAME;
05062 }
05063
05064 static Processor *NEW()
05065 {
05066 return new PhaseToMassCenterProcessor();
05067 }
05068
05069 virtual string get_desc() const
05070 {
05071 return "centers the image the center of mass, which is calculated using Fourier phases, ignores old dx, dy.";
05072 }
05073
05074 virtual TypeDict get_param_types() const
05075 {
05076 TypeDict d;
05077 d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05078 return d;
05079 }
05080
05081 static const string NAME;
05082 };
05083
05088 class ToMassCenterProcessor:public Processor
05089 {
05090 public:
05091 virtual void process_inplace(EMData * image);
05092
05093 virtual string get_name() const
05094 {
05095 return NAME;
05096 }
05097
05098 static Processor *NEW()
05099 {
05100 return new ToMassCenterProcessor();
05101 }
05102
05103 virtual string get_desc() const
05104 {
05105 return "ToMassCenterProcessor centers image at center of mass, with a threshold. Only values higher than the threshold are considered.";
05106 }
05107
05108 virtual TypeDict get_param_types() const
05109 {
05110 TypeDict d;
05111 d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05112 d.put("threshold", EMObject::FLOAT, "Only values larger than the threshold are included in the center of mass computation. Default is 0.");
05113
05114 return d;
05115 }
05116
05117 static const string NAME;
05118 };
05119
05123 class ACFCenterProcessor:public Processor
05124 {
05125 public:
05126 virtual void process_inplace(EMData * image);
05127
05128 virtual string get_name() const
05129 {
05130 return NAME;
05131 }
05132
05133 static Processor *NEW()
05134 {
05135 return new ACFCenterProcessor();
05136 }
05137
05138 virtual string get_desc() const
05139 {
05140 return "Center image using self-convolution.";
05141 }
05142
05143 virtual TypeDict get_param_types() const
05144 {
05145 TypeDict d;
05146 return d;
05147 }
05148
05149 static const string NAME;
05150 };
05151
05156 class SNRProcessor:public Processor
05157 {
05158 public:
05159 virtual void process_inplace(EMData * image);
05160
05161 virtual string get_name() const
05162 {
05163 return NAME;
05164 }
05165
05166 static Processor *NEW()
05167 {
05168 return new SNRProcessor();
05169 }
05170
05171 virtual string get_desc() const
05172 {
05173 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.";
05174 }
05175
05176 virtual TypeDict get_param_types() const
05177 {
05178 TypeDict d;
05179 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");
05180 d.put("snrfile", EMObject::STRING, "structure factor file name");
05181 return d;
05182 }
05183
05184 static const string NAME;
05185 };
05186
05190 class FileFourierProcessor:public Processor
05191 {
05192 public:
05193 virtual void process_inplace(EMData * image);
05194
05195 virtual string get_name() const
05196 {
05197 return NAME;
05198 }
05199
05200 virtual string get_desc() const
05201 {
05202 return "A fourier processor specified in a 2 column text file.";
05203 }
05204
05205 static Processor *NEW()
05206 {
05207 return new FileFourierProcessor();
05208 }
05209
05210 virtual TypeDict get_param_types() const
05211 {
05212 TypeDict d;
05213 d.put("filename", EMObject::STRING, "file name for a 2 column text file which specified a radial function data array.");
05214 return d;
05215 }
05216
05217 static const string NAME;
05218 };
05219
05230 class SymSearchProcessor:public Processor
05231 {
05232 public:
05233 virtual void process_inplace(EMData * image);
05234
05235 virtual string get_name() const
05236 {
05237 return NAME;
05238 }
05239
05240 virtual string get_desc() const
05241 {
05242 return "Identifiy the best symmetry in the given symmetry list for each pixel and then apply the best symmetry to each pixel.";
05243 }
05244
05245 static Processor *NEW()
05246 {
05247 return new SymSearchProcessor();
05248 }
05249
05250 virtual TypeDict get_param_types() const
05251 {
05252 TypeDict d;
05253 d.put("sym", EMObject::STRINGARRAY, "the list of symmetries to search");
05254 d.put("thresh", EMObject::FLOAT, "the minimal level of symmetry to be accepted (0-1)");
05255 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");
05256 d.put("symlabel_map", EMObject::EMDATA, "the optional return map when output_symlabel=1");
05257 return d;
05258 }
05259
05260 static const string NAME;
05261 };
05262
05268 class LocalNormProcessor:public Processor
05269 {
05270 public:
05271 void process_inplace(EMData * image);
05272
05273 virtual string get_name() const
05274 {
05275 return NAME;
05276 }
05277
05278 static Processor *NEW()
05279 {
05280 return new LocalNormProcessor();
05281 }
05282
05283 virtual string get_desc() const
05284 {
05285 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.";
05286 }
05287
05288 virtual TypeDict get_param_types() const
05289 {
05290 TypeDict d;
05291 d.put("threshold", EMObject::FLOAT, "an isosurface threshold at which all desired features are visible");
05292 d.put("radius", EMObject::FLOAT, "a normalization size similar to an lp= value");
05293 d.put("apix", EMObject::FLOAT, "Angstrom per pixel ratio");
05294 return d;
05295 }
05296
05297 static const string NAME;
05298 };
05299
05304 class IndexMaskFileProcessor:public Processor
05305 {
05306 public:
05307 virtual void process_inplace(EMData * image);
05308
05309 virtual string get_name() const
05310 {
05311 return NAME;
05312 }
05313
05314 static Processor *NEW()
05315 {
05316 return new IndexMaskFileProcessor();
05317 }
05318
05319 virtual TypeDict get_param_types() const
05320 {
05321 TypeDict d;
05322 d.put("filename", EMObject::STRING, "mask image file name");
05323 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");
05324 return d;
05325 }
05326
05327 virtual string get_desc() const
05328 {
05329 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.";
05330 }
05331
05332 static const string NAME;
05333 };
05334
05338 class CoordinateMaskFileProcessor:public Processor
05339 {
05340 public:
05341 virtual void process_inplace(EMData * image);
05342
05343 virtual string get_name() const
05344 {
05345 return NAME;
05346 }
05347
05348 static Processor *NEW()
05349 {
05350 return new CoordinateMaskFileProcessor();
05351 }
05352
05353 virtual string get_desc() const
05354 {
05355 return "Multiplies the image by the specified file using pixel coordinates instead of pixel indices. The images can be different size.";
05356 }
05357
05358 virtual TypeDict get_param_types() const
05359 {
05360 TypeDict d;
05361 d.put("filename", EMObject::STRING, "mask image file name");
05362 return d;
05363 }
05364
05365 static const string NAME;
05366 };
05367
05378 class PaintProcessor:public Processor
05379 {
05380 public:
05381 PaintProcessor():x(0), y(0), z(0),r1(0), v1(0.0), r2(0), v2(0.0)
05382 {
05383 }
05384
05385 virtual string get_name() const
05386 {
05387 return NAME;
05388 }
05389
05390 static Processor *NEW()
05391 {
05392 return new PaintProcessor();
05393 }
05394
05395 virtual string get_desc() const
05396 {
05397 return "Paints a circle with a decaying edge into the image. r<r1 -> v1, r1<r<r2 -> (v1,v2), r>r2 unchanged";
05398 }
05399
05400 virtual TypeDict get_param_types() const
05401 {
05402 TypeDict d;
05403 d.put("x", EMObject::INT, "x coordinate for Center of circle");
05404 d.put("y", EMObject::INT, "y coordinate for Center of circle");
05405 d.put("z", EMObject::INT, "z coordinate for Center of circle");
05406 d.put("r1", EMObject::INT, "Inner radius");
05407 d.put("v1", EMObject::FLOAT, "Inner value");
05408 d.put("r2", EMObject::INT, "Outter radius");
05409 d.put("v2", EMObject::FLOAT, "Outer Value");
05410 return d;
05411 }
05412
05413 virtual void set_params(const Dict & new_params)
05414 {
05415 params = new_params;
05416
05417 if (params.has_key("x")) x = params["x"];
05418 if (params.has_key("y")) y = params["y"];
05419 if (params.has_key("z")) z = params["z"];
05420 if (params.has_key("r1")) r1 = params["r1"];
05421 if (params.has_key("r2")) r2 = params["r2"];
05422 if (params.has_key("v1")) v1 = params["v1"];
05423 if (params.has_key("v2")) v2 = params["v2"];
05424 }
05425
05426 static const string NAME;
05427
05428 protected:
05429 virtual void process_inplace(EMData *image);
05430
05431 int x,y,z,r1;
05432 float v1;
05433 int r2;
05434 float v2;
05435
05436 };
05437
05438
05443 class DirectionalSumProcessor : public Processor
05444 {
05445 public:
05446 virtual string get_name() const
05447 {
05448 return NAME;
05449 }
05450
05451 static Processor *NEW()
05452 {
05453 return new DirectionalSumProcessor();
05454 }
05455
05459 virtual EMData* process(const EMData* const image);
05460
05464 virtual void process_inplace(EMData*) {
05465 throw InvalidCallException("The directional sum processor does not work inplace");
05466 }
05467
05468 virtual TypeDict get_param_types() const
05469 {
05470 TypeDict d;
05471 d.put("axis", EMObject::STRING,"The direction of the sum, either x,y or z. Returned axes are xy, xz or zy.");
05472 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)");
05473 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)");
05474 return d;
05475 }
05476
05477 string get_desc() const
05478 {
05479 return "Calculates the projection of the image along one of the axial directions, either x, y or z";
05480 }
05481
05482 static const string NAME;
05483 };
05484
05492 class WatershedProcessor:public Processor
05493 {
05494 public:
05495 virtual void process_inplace(EMData * image);
05496
05497 virtual string get_name() const
05498 {
05499 return NAME;
05500 }
05501
05502 static Processor *NEW()
05503 {
05504 return new WatershedProcessor();
05505 }
05506
05507 virtual string get_desc() const
05508 {
05509 return "Does a watershed";
05510 }
05511
05512 virtual TypeDict get_param_types() const
05513 {
05514 TypeDict d;
05515 d.put("xpoints", EMObject::FLOATARRAY,"x coordinates");
05516 d.put("ypoints", EMObject::FLOATARRAY,"y coordinates");
05517 d.put("zpoints", EMObject::FLOATARRAY,"z coordinates");
05518 d.put("minval", EMObject::FLOAT,"min value");
05519 return d;
05520 }
05521
05522 static const string NAME;
05523
05524 private:
05525 vector<Vec3i > watershed(EMData* mask, EMData* image, const float& threshold, const Vec3i& cordinate, const int mask_value);
05526 vector<Vec3i > find_region(EMData* mask,const vector<Vec3i >& coords, const int mask_value, vector<Vec3i >& region);
05527
05528 };
05529
05539 template<class Type>
05540 class BinaryOperateProcessor : public Processor{
05541 public:
05546 virtual void process_inplace(EMData * image) {
05547 if ( ! params.has_key("with") ) throw InvalidParameterException("You must supply the \"with\" parameter");
05548 EMData* with = params["with"];
05549
05550 if ( with->get_xsize() != image->get_xsize() || with->get_ysize() != image->get_ysize() || with->get_zsize() != image->get_zsize() )
05551 throw ImageDimensionException("The images you are operating on do not have the same dimensions");
05552
05553 float* image_data = image->get_data();
05554 float* with_data = with->get_data();
05555
05556 std::transform(image_data,image_data+image->get_size(),with_data,image_data,Type::binary_operate);
05557 image->update();
05558 }
05559
05560 virtual string get_name() const
05561 {
05562 return op.get_name();
05563 }
05564
05565 virtual string get_desc() const
05566 {
05567 return op.get_desc();
05568 }
05569
05570 static Processor *NEW()
05571 {
05572 return new BinaryOperateProcessor<Type>();
05573 }
05574
05575 virtual TypeDict get_param_types() const
05576 {
05577 TypeDict d;
05578 d.put("with", EMObject::EMDATA,"The second image");
05579 return d;
05580 }
05581
05582 static const string NAME;
05583 private:
05584 Type op;
05585 };
05586
05587 class MaxPixelOperator {
05588 public:
05589 string get_name() const
05590 {
05591 return NAME;
05592 }
05593
05594 string get_desc() const
05595 {
05596 return "Compares pixels in two images, returning an image with the maximum pixel value in each pixel location";
05597 }
05598
05599 static float binary_operate(const float& left, const float& right) {
05600 if (left > right) return left;
05601 return right;
05602 }
05603
05604 static const string NAME;
05605 };
05606
05607 class MinPixelOperator {
05608 public:
05609 string get_name() const
05610 {
05611 return NAME;
05612 }
05613
05614 string get_desc() const
05615 {
05616 return "Compares pixels in two images, returning an image with the minimum pixel value in each pixel location";
05617 }
05618
05619 static float binary_operate(const float& left, const float& right) {
05620 if (left < right) return left;
05621 return right;
05622 }
05623
05624 static const string NAME;
05625 };
05626
05630 class MatchSFProcessor:public FourierAnlProcessor
05631 {
05632 public:
05633
05634 virtual string get_name() const
05635 {
05636 return NAME;
05637 }
05638
05639 virtual string get_desc() const
05640 {
05641 return "Filters the image so its 1-D power spectrum matches a second image";
05642 }
05643
05644 static Processor *NEW()
05645 {
05646 return new MatchSFProcessor();
05647 }
05648
05649 virtual TypeDict get_param_types() const
05650 {
05651 TypeDict d;
05652 d.put("to", EMObject::EMDATA, "The image to match with. Make sure apix values are correct.");
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
05662
05667 class SetSFProcessor:public FourierAnlProcessor
05668 {
05669 public:
05670
05671 virtual string get_name() const
05672 {
05673 return NAME;
05674 }
05675
05676 virtual string get_desc() const
05677 {
05678 return "Filters the image so its 1-D power spectrum matches a supplied X-Y curve";
05679 }
05680
05681 static Processor *NEW()
05682 {
05683 return new SetSFProcessor();
05684 }
05685
05686 virtual TypeDict get_param_types() const
05687 {
05688 TypeDict d;
05689 d.put("strucfac", EMObject::XYDATA, "An XYData object contaning the curve to be imposed as a function of S");
05690 d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
05691 return d;
05692 }
05693
05694 static const string NAME;
05695
05696 protected:
05697 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05698 };
05699
05703 class SmartMaskProcessor:public Processor
05704 {
05705 public:
05706 virtual void process_inplace(EMData * image);
05707
05708 virtual string get_name() const
05709 {
05710 return NAME;
05711 }
05712
05713 static Processor *NEW()
05714 {
05715 return new SmartMaskProcessor();
05716 }
05717
05718 virtual string get_desc() const
05719 {
05720 return "Smart mask processor.";
05721 }
05722
05723 virtual TypeDict get_param_types() const
05724 {
05725 TypeDict d;
05726 d.put("mask", EMObject::FLOAT, "mask value");
05727 return d;
05728 }
05729
05730 static const string NAME;
05731 };
05732
05737 class IterBinMaskProcessor:public Processor
05738 {
05739 public:
05740 virtual void process_inplace(EMData * image);
05741
05742 virtual string get_name() const
05743 {
05744 return NAME;
05745 }
05746
05747 virtual string get_desc() const
05748 {
05749 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.";
05750 }
05751
05752 static Processor *NEW()
05753 {
05754 return new IterBinMaskProcessor();
05755 }
05756
05757 virtual TypeDict get_param_types() const
05758 {
05759 TypeDict d;
05760 d.put("val1", EMObject::FLOAT, "number of pixels to expand");
05761 d.put("val2", EMObject::FLOAT, "number of Gaussian pixels to expand, following the first expansion");
05762 return d;
05763 }
05764
05765 static const string NAME;
05766 };
05767
05770 class TestImageProcessor : public Processor
05771 {
05772 public:
05773 static string get_group_desc()
05774 {
05775 return "Base class for a group of 'processors' used to create test image.";
05776 }
05777
05778 protected:
05779 void preprocess(EMData * image);
05780 int nx, ny, nz;
05781 };
05782
05791 class TestImagePureGaussian : 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 as a strict Gaussian ";
05804 }
05805
05806 static Processor * NEW()
05807 {
05808 return new TestImagePureGaussian();
05809 }
05810
05811 virtual TypeDict get_param_types() const
05812 {
05813 TypeDict d;
05814 d.put("x_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on x direction");
05815 d.put("y_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on y direction");
05816 d.put("z_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on z direction");
05817 d.put("x_center", EMObject::FLOAT, "center for this Gaussian blob on x direction" );
05818 d.put("y_center", EMObject::FLOAT, "center for this Gaussian blob on y direction" );
05819 d.put("z_center", EMObject::FLOAT, "center for this Gaussian blob on z direction" );
05820 return d;
05821 }
05822
05823 static const string NAME;
05824 };
05825
05829 class TestImageFourierNoiseGaussian : public TestImageProcessor
05830 {
05831 public:
05832 virtual void process_inplace(EMData * image);
05833
05834 virtual string get_name() const
05835 {
05836 return NAME;
05837 }
05838
05839 virtual string get_desc() const
05840 {
05841 return "Replace a source image with pink Fourier noise, based on a Gaussian. Random phase.";
05842 }
05843
05844 static Processor * NEW()
05845 {
05846 return new TestImageFourierNoiseGaussian();
05847 }
05848
05849 virtual TypeDict get_param_types() const
05850 {
05851 TypeDict d;
05852 d.put("sigma", EMObject::FLOAT, "sigma value");
05853 return d;
05854 }
05855
05856 static const string NAME;
05857 };
05858
05863 class TestImageFourierNoiseProfile : public TestImageProcessor
05864 {
05865 public:
05866 virtual void process_inplace(EMData * image);
05867
05868 virtual string get_name() const
05869 {
05870 return NAME;
05871 }
05872
05873 virtual string get_desc() const
05874 {
05875 return "Replace a source image with Fourier noise using amplitude information that is stored in a profile.";
05876 }
05877
05878 static Processor * NEW()
05879 {
05880 return new TestImageFourierNoiseProfile();
05881 }
05882
05883 virtual TypeDict get_param_types() const
05884 {
05885 TypeDict d;
05886 d.put("profile", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
05887 return d;
05888 }
05889
05890 static const string NAME;
05891 };
05892
05893
05898 class CTFSNRWeightProcessor : 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 "Weight the amplitudes of an image based on radial noise and snr curves ";
05911 }
05912
05913 static Processor * NEW()
05914 {
05915 return new CTFSNRWeightProcessor();
05916 }
05917
05918 virtual TypeDict get_param_types() const
05919 {
05920 TypeDict d;
05921 d.put("noise", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
05922 d.put("snr", EMObject::FLOATARRAY, "Squared amplitude divided by squared noise amplitude. As in, what is the EMAN2CTF.snr attribute");
05923 d.put("boost", EMObject::FLOAT, "Multiplicative signal boost");
05924 return d;
05925 }
05926
05927 static const string NAME;
05928 };
05929
05930
05931
05936 class TestImageLineWave : public TestImageProcessor
05937 {
05938 public:
05939 virtual void process_inplace(EMData * image);
05940
05941 virtual string get_name() const
05942 {
05943 return NAME;
05944 }
05945
05946 virtual string get_desc() const
05947 {
05948 return "Insert an oscillating sine wave into the pixel data";
05949 }
05950
05951 static Processor * NEW()
05952 {
05953 return new TestImageLineWave();
05954 }
05955
05956 virtual TypeDict get_param_types() const
05957 {
05958 TypeDict d;
05959 d.put("period", EMObject::FLOAT, "The period of the oscillating sine wave. Default 10.");
05960 return d;
05961 }
05962
05963 static const string NAME;
05964 };
05965
05966
05974 class TestTomoImage : public TestImageProcessor
05975 {
05976 public:
05980 virtual void process_inplace(EMData * image);
05981
05982 virtual string get_name() const
05983 {
05984 return NAME;
05985 }
05986
05987 virtual string get_desc() const
05988 {
05989 return "Make an image consisting various objects, useful for tomographic testing";
05990 }
05991
05992 static Processor * NEW()
05993 {
05994 return new TestTomoImage();
05995 }
05996
05997 static const string NAME;
05998
05999 private:
06000 void insert_solid_ellipse( EMData* image, const Region& region, const float& value, const Transform& t3d = Transform() );
06001 void insert_hollow_ellipse( EMData* image, const Region& region, const float& value, const int& radius, const Transform& t3d = Transform() );
06002 void insert_rectangle( EMData* image, const Region& region, const float& value, const Transform& t3d = Transform() );
06003 };
06004
06012 class TestImageGradient : public TestImageProcessor
06013 {
06014 public:
06015 virtual void process_inplace(EMData * image);
06016
06017 virtual string get_name() const
06018 {
06019 return NAME;
06020 }
06021
06022 virtual string get_desc() const
06023 {
06024 return "Make a gradient image of the form y=mx+b, where x is any of the image axes.";
06025 }
06026
06027 static Processor * NEW()
06028 {
06029 return new TestImageGradient();
06030 }
06031
06032 virtual TypeDict get_param_types() const
06033 {
06034 TypeDict d;
06035 d.put("axis", EMObject::STRING, "The axis the will be used to determine pixel values. Must be x,y or z");
06036 d.put("m", EMObject::FLOAT, "m in the equation m*axis+b. Default is 1.0");
06037 d.put("b", EMObject::FLOAT, "b in the equation m*axis+b. Default is 0.0");
06038 return d;
06039 }
06040
06041 static const string NAME;
06042 };
06043
06051 class TestImageAxes : public TestImageProcessor
06052 {
06053 public:
06058 virtual void process_inplace(EMData * image);
06059
06060 virtual string get_name() const
06061 {
06062 return NAME;
06063 }
06064
06065 virtual string get_desc() const
06066 {
06067 return "Make an image consisting of a single cross";
06068 }
06069
06070 static Processor * NEW()
06071 {
06072 return new TestImageAxes();
06073 }
06074
06075 virtual TypeDict get_param_types() const
06076 {
06077 TypeDict d;
06078 d.put("int", EMObject::FLOAT, "radius of the lines emanating from the origin");
06079 d.put("fill", EMObject::FLOAT, "value to make non-zero pixels");
06080 return d;
06081 }
06082
06083 static const string NAME;
06084 };
06085
06091 class TestImageGaussian : public TestImageProcessor
06092 {
06093 public:
06094 virtual void process_inplace(EMData * image);
06095
06096 virtual string get_name() const
06097 {
06098 return NAME;
06099 }
06100
06101 virtual string get_desc() const
06102 {
06103 return "Replace a source image as a Gaussian Blob";
06104 }
06105
06106 static Processor * NEW()
06107 {
06108 return new TestImageGaussian();
06109 }
06110
06111 virtual TypeDict get_param_types() const
06112 {
06113 TypeDict d;
06114 d.put("sigma", EMObject::FLOAT, "sigma value for this Gaussian blob");
06115 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06116 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06117 return d;
06118 }
06119
06120 static const string NAME;
06121 };
06122
06125 class TestImageScurve : public TestImageProcessor
06126 {
06127 public:
06128 virtual void process_inplace(EMData * image);
06129
06130 virtual string get_name() const
06131 {
06132 return NAME;
06133 }
06134
06135 virtual string get_desc() const
06136 {
06137 return "Replace a source image with a lumpy S-curve used for alignment testing";
06138 }
06139
06140 static Processor * NEW()
06141 {
06142 return new TestImageScurve();
06143 }
06144
06145 virtual TypeDict get_param_types() const
06146 {
06147 TypeDict d;
06148 return d;
06149 }
06150
06151 static const string NAME;
06152 };
06153
06161 class TestImageSphericalWave : public TestImageProcessor
06162 {
06163 public:
06164 virtual void process_inplace(EMData * image);
06165
06166 virtual string get_name() const
06167 {
06168 return NAME;
06169 }
06170
06171 virtual string get_desc() const
06172 {
06173 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)";
06174 }
06175
06176 static Processor * NEW()
06177 {
06178 return new TestImageSphericalWave();
06179 }
06180
06181 virtual TypeDict get_param_types() const
06182 {
06183 TypeDict d;
06184 d.put("wavelength", EMObject::FLOAT, "cos(2*pi*r/wavelength+phase)");
06185 d.put("phase", EMObject::FLOAT, "in radians");
06186 d.put("x", EMObject::FLOAT, "center of the spherical wave");
06187 d.put("y", EMObject::FLOAT, "center of the spherical wave");
06188 d.put("z", EMObject::FLOAT, "center of the spherical wave");
06189 return d;
06190 }
06191
06192 static const string NAME;
06193 };
06194
06195
06204 class TestImageSinewave : public TestImageProcessor
06205 {
06206 public:
06207 virtual void process_inplace(EMData * image);
06208
06209 virtual string get_name() const
06210 {
06211 return NAME;
06212 }
06213
06214 virtual string get_desc() const
06215 {
06216 return "Replace a source image as a sine wave in specified wave length";
06217 }
06218
06219 static Processor * NEW()
06220 {
06221 return new TestImageSinewave();
06222 }
06223
06224 virtual TypeDict get_param_types() const
06225 {
06226 TypeDict d;
06227 d.put("wavelength", EMObject::FLOAT, "wavelength in equation sin(x*2*PI/wavelength - phase*180/PI)");
06228 d.put("axis", EMObject::STRING, "(optional) specify a major axis for asymmetric features, default x axis");
06229 d.put("phase", EMObject::FLOAT, "(optional) the phase in radians");
06230 d.put("az", EMObject::FLOAT, "(optional) angle in degree. for 2D image, this is the rotated angle of the image, \
06231 in 3D image, it's az for euler angle. default is zero");
06232 d.put("alt", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, alt for euler angle, default is zero");
06233 d.put("phi", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, phi for euler angle, default is zero");
06234 return d;
06235 }
06236
06237 static const string NAME;
06238 };
06239
06246 class TestImageSinewaveCircular : public TestImageProcessor
06247 {
06248 public:
06249 virtual void process_inplace(EMData * image);
06250
06251 virtual string get_name() const
06252 {
06253 return NAME;
06254 }
06255
06256 virtual string get_desc() const
06257 {
06258 return "Replace a source image as a circular sine wave in specified wave length";
06259 }
06260
06261 static Processor * NEW()
06262 {
06263 return new TestImageSinewaveCircular();
06264 }
06265
06266 virtual TypeDict get_param_types() const
06267 {
06268 TypeDict d;
06269 d.put("wavelength", EMObject::FLOAT, "(required)this value is the d in function |sin(x/d)|, unit: pixel");
06270 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06271 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06272 d.put("phase", EMObject::FLOAT, "(optional)phase for sine wave, default is 0");
06273 return d;
06274 }
06275
06276 static const string NAME;
06277 };
06278
06285 class TestImageSquarecube : public TestImageProcessor
06286 {
06287 public:
06288 virtual void process_inplace(EMData * image);
06289
06290 virtual string get_name() const
06291 {
06292 return NAME;
06293 }
06294
06295 virtual string get_desc() const
06296 {
06297 return "Replace a source image as a square or cube depends on 2D or 3D of the source image";
06298 }
06299
06300 static Processor * NEW()
06301 {
06302 return new TestImageSquarecube();
06303 }
06304
06305 virtual TypeDict get_param_types() const
06306 {
06307 TypeDict d;
06308 d.put("edge_length", EMObject::FLOAT, "edge length of the square or cube, unit: pixel");
06309 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06310 d.put("odd_edge", EMObject::FLOAT, "edge length for the asymmetric axis");
06311 d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank");
06312 return d;
06313 }
06314
06315 static const string NAME;
06316 };
06317
06325 class TestImageEllipse : public TestImageProcessor
06326 {
06327 public:
06328 virtual void process_inplace(EMData * image);
06329
06330 virtual string get_name() const
06331 {
06332 return NAME;
06333 }
06334
06335 virtual string get_desc() const
06336 {
06337 return "Insert an ellipse into the image.";
06338 }
06339
06340 static Processor * NEW()
06341 {
06342 return new TestImageEllipse();
06343 }
06344
06345 virtual TypeDict get_param_types() const
06346 {
06347 TypeDict d;
06348 d.put("a", EMObject::FLOAT, "equatorial radius along x axes (major semiaxes)");
06349 d.put("b", EMObject::FLOAT, "equatorial radius along y axes (minor semiaxes)");
06350 d.put("c", EMObject::FLOAT, "polar radius for ellipsoid (x^2/a^2+y^2/b^2+z^2/c^2=1)");
06351 d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06352 d.put("fill", EMObject::FLOAT, "value you want to fill in ellipse, default to 1.0");
06353 return d;
06354 }
06355
06356 static const string NAME;
06357 };
06358
06370 class TestImageHollowEllipse : public TestImageProcessor
06371 {
06372 public:
06373 virtual void process_inplace(EMData * image);
06374
06375 virtual string get_name() const
06376 {
06377 return NAME;
06378 }
06379
06380 virtual string get_desc() const
06381 {
06382 return "Insert a hollow ellipse into the image.";
06383 }
06384
06385 static Processor * NEW()
06386 {
06387 return new TestImageHollowEllipse();
06388 }
06389
06390 virtual TypeDict get_param_types() const
06391 {
06392 TypeDict d;
06393 d.put("xwidth", EMObject::FLOAT, "inner equatorial radii along x axes");
06394 d.put("ywidth", EMObject::FLOAT, "inner equatorial radii along y axes");
06395 d.put("zwidth", EMObject::FLOAT, "inner polar radius");
06396 d.put("a", EMObject::FLOAT, "outter equatorial radii along x axes");
06397 d.put("b", EMObject::FLOAT, "outter equatorial radii along y axes");
06398 d.put("c", EMObject::FLOAT, "outter polar radius");
06399 d.put("width",EMObject::FLOAT, "width - specify the width or specify each width explicitly - xwidth, ywidth, zwidth");
06400 d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06401 d.put("fill", EMObject::FLOAT, "value you want to fill in hollow ellipse, default to 1.0");
06402 return d;
06403 }
06404
06405 static const string NAME;
06406 };
06407
06414 class TestImageCirclesphere : public TestImageProcessor
06415 {
06416 public:
06417 virtual void process_inplace(EMData * image);
06418
06419 virtual string get_name() const
06420 {
06421 return NAME;
06422 }
06423
06424 virtual string get_desc() const
06425 {
06426 return "Replace a source image as a circle or sphere depends on 2D or 3D of the source image";
06427 }
06428
06429 static Processor * NEW()
06430 {
06431 return new TestImageCirclesphere();
06432 }
06433
06434 virtual TypeDict get_param_types() const
06435 {
06436 TypeDict d;
06437 d.put("radius", EMObject::FLOAT, "radius of circle or sphere, unit: pixel");
06438 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06439 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06440 d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank.");
06441 return d;
06442 }
06443
06444 static const string NAME;
06445 };
06446
06451 class TestImageNoiseUniformRand : public TestImageProcessor
06452 {
06453 public:
06454 virtual void process_inplace(EMData * image);
06455
06456 virtual string get_name() const
06457 {
06458 return NAME;
06459 }
06460
06461 virtual string get_desc() const
06462 {
06463 return "Replace a source image as a uniform random noise, random number generated from gsl_rng_mt19937, the pixel value is [0, 1)";
06464 }
06465
06466 static Processor * NEW()
06467 {
06468 return new TestImageNoiseUniformRand();
06469 }
06470
06471 virtual TypeDict get_param_types() const
06472 {
06473 TypeDict d;
06474 d.put("seed", EMObject::INT, "seed for random number generator");
06475 return d;
06476 }
06477
06478 static const string NAME;
06479 };
06480
06491 class TestImageNoiseGauss : public TestImageProcessor
06492 {
06493 public:
06494 virtual void process_inplace(EMData * image);
06495
06496 virtual string get_name() const
06497 {
06498 return NAME;
06499 }
06500
06501 virtual string get_desc() const
06502 {
06503 return "Replace a source image as a random noise, the random value is gaussian distributed";
06504 }
06505
06506 static Processor * NEW()
06507 {
06508 return new TestImageNoiseGauss();
06509 }
06510
06511 virtual TypeDict get_param_types() const
06512 {
06513 TypeDict d;
06514 d.put("sigma", EMObject::FLOAT, "sigma value of gausian distributed noise, default is 0.5");
06515 d.put("mean", EMObject::FLOAT, "mean value of gausian distributed noise, default is zero.");
06516 d.put("seed", EMObject::INT, "the seed for random number generator, default is not to reseed.");
06517
06518 return d;
06519 }
06520
06521 static const string NAME;
06522 };
06523
06528 class TestImageCylinder : public TestImageProcessor
06529 {
06530 public:
06531 virtual void process_inplace(EMData * image);
06532
06533 virtual string get_name() const
06534 {
06535 return NAME;
06536 }
06537
06538 virtual string get_desc() const
06539 {
06540 return "Replace a source image as a cylinder";
06541 }
06542
06543 static Processor * NEW()
06544 {
06545 return new TestImageCylinder();
06546 }
06547
06548 virtual TypeDict get_param_types() const
06549 {
06550 TypeDict d;
06551 d.put("radius", EMObject::FLOAT, "radius for the cylinder");
06552 d.put("height", EMObject::FLOAT, "height for the cylinder, by default it's the nz");
06553
06554 return d;
06555 }
06556
06557 static const string NAME;
06558 };
06559
06565 class CCDNormProcessor:public Processor
06566 {
06567 public:
06568 virtual void process_inplace(EMData * image);
06569
06570 virtual string get_name() const
06571 {
06572 return NAME;
06573 }
06574
06575 static Processor *NEW()
06576 {
06577 return new CCDNormProcessor();
06578 }
06579
06580 virtual string get_desc() const
06581 {
06582 return "normalize the 4 quadrants of a CCD image";
06583 }
06584
06585 virtual TypeDict get_param_types() const
06586 {
06587 TypeDict d;
06588 d.put("width", EMObject::INT, "number of pixels on either side of the seam to sample");
06589 return d;
06590 }
06591
06592 static const string NAME;
06593 };
06594
06602 class WaveletProcessor:public Processor
06603 {
06604 public:
06605 virtual void process_inplace(EMData * image);
06606
06607 virtual string get_name() const
06608 {
06609 return NAME;
06610 }
06611
06612 static Processor *NEW()
06613 {
06614 return new WaveletProcessor();
06615 }
06616
06617 virtual TypeDict get_param_types() const
06618 {
06619 TypeDict d;
06620 d.put("type", EMObject::STRING, "'daub', 'harr' or 'bspl'");
06621 d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06622 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)");
06623 return d;
06624 }
06625
06626 virtual string get_desc() const
06627 {
06628 return "Computes the DWT (discrete wavelet transform) of an image in one of 3 possible bases";
06629 }
06630
06631 static const string NAME;
06632 };
06633
06649 class TomoTiltEdgeMaskProcessor : public Processor
06650 {
06651 public:
06652 virtual void process_inplace(EMData* image);
06653
06654 virtual string get_name() const
06655 {
06656 return NAME;
06657 }
06658
06659 static Processor *NEW()
06660 {
06661 return new TomoTiltEdgeMaskProcessor();
06662 }
06663
06664 virtual TypeDict get_param_types() const
06665 {
06666 TypeDict d;
06667 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");
06668 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.");
06669 d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06670 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.");
06671 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)");
06672 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");
06673 return d;
06674 }
06675
06676 virtual string get_desc() const
06677 {
06678 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.";
06679 }
06680
06681 static const string NAME;
06682
06683 private:
06684 class GaussianFunctoid
06685 {
06686 public:
06687 GaussianFunctoid(const float sigma, const float mean = 0.0) : m_mean(mean), m_sigma_squared(sigma*sigma) {}
06688 ~GaussianFunctoid() {}
06689
06690 float operator()(const float distance )
06691 {
06692 return exp( -(distance-m_mean)*(distance-m_mean)/ (m_sigma_squared ));
06693 }
06694 private:
06695 float m_mean, m_sigma_squared;
06696 };
06697
06698 };
06699
06714 class TomoTiltAngleWeightProcessor : public Processor
06715 {
06716 public:
06717 virtual void process_inplace(EMData* image);
06718
06719 virtual string get_name() const
06720 {
06721 return NAME;
06722 }
06723
06724 static Processor *NEW()
06725 {
06726 return new TomoTiltAngleWeightProcessor();
06727 }
06728
06729 virtual TypeDict get_param_types() const
06730 {
06731 TypeDict d;
06732 d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06733 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");
06734 return d;
06735 }
06736
06737 virtual string get_desc() const
06738 {
06739 return "Weights the image by 1/cos(angle)";
06740 }
06741
06742 static const string NAME;
06743
06744 };
06745
06749 class FFTProcessor : public Processor
06750 {
06751 public:
06752 void process_inplace(EMData * image);
06753
06754 string get_name() const
06755 {
06756 return NAME;
06757 }
06758
06759 static Processor *NEW()
06760 {
06761 return new FFTProcessor();
06762 }
06763
06764 TypeDict get_param_types() const
06765 {
06766 TypeDict d;
06767 d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06768 return d;
06769 }
06770
06771 string get_desc() const
06772 {
06773 return "Computes the DFFT (Discrete Fast Fourier Transform) of an image";
06774 }
06775
06776 static const string NAME;
06777 };
06778
06783 class RadialProcessor : public Processor
06784 {
06785 public:
06786 void process_inplace(EMData * image);
06787
06788 string get_name() const
06789 {
06790 return NAME;
06791 }
06792
06793 static Processor *NEW()
06794 {
06795 return new RadialProcessor();
06796 }
06797
06798 TypeDict get_param_types() const
06799 {
06800 TypeDict d;
06801 d.put("table", EMObject::FLOATARRAY, "Radial array of floats, 1 float/pixel");
06802 return d;
06803 }
06804
06805 string get_desc() const
06806 {
06807 return "Multiply a real-space image by a radial function. 1 value / pixel, extending to corner. Missing values -> 0.";
06808 }
06809
06810 static const string NAME;
06811 };
06812
06819 class HistogramBin : public Processor
06820 {
06821 public:
06822 HistogramBin() : default_bins(1024) {}
06823
06824 void process_inplace(EMData * image);
06825
06826 string get_name() const
06827 {
06828 return NAME;
06829 }
06830
06831 static Processor *NEW()
06832 {
06833 return new HistogramBin();
06834 }
06835
06836 TypeDict get_param_types() const
06837 {
06838 TypeDict d;
06839 d.put("nbins", EMObject::INT, "The number of bins the pixel values will be compressed into");
06840 d.put("debug", EMObject::BOOL, "Outputs debugging information (number of pixels per bin)");
06841 return d;
06842 }
06843
06844 string get_desc() const
06845 {
06846 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";
06847 }
06848
06849 static const string NAME;
06850
06851 protected:
06852 int default_bins;
06853 };
06854
06855 class ModelHelixProcessor : public Processor
06856 {
06857 protected:
06858 float radprofile(float r, int type);
06859 };
06860
06861 class ModelEMCylinderProcessor : public ModelHelixProcessor
06862 {
06863 public:
06864 void process_inplace(EMData * in);
06865
06866 string get_name() const
06867 {
06868 return NAME;
06869 }
06870
06871 static Processor *NEW()
06872 {
06873 return new ModelEMCylinderProcessor();
06874 }
06875
06876 string get_desc() const
06877 {
06878 return "Adds a cylinder with a radial density profile similar to that of an alpha helix.";
06879 }
06880
06881 virtual TypeDict get_param_types() const
06882 {
06883 TypeDict d;
06884 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");
06885 d.put("length", EMObject::FLOAT, "cylinder length in angstroms, defaults to 3 turns (16.2 Angstroms)");
06886 d.put("x0", EMObject::INT, "x coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06887 d.put("y0", EMObject::INT, "y coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06888 d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06889
06890 return d;
06891 }
06892
06893 static const string NAME;
06894 };
06895
06896 class ApplyPolynomialProfileToHelix : public ModelHelixProcessor
06897 {
06898 public:
06899 void process_inplace(EMData * in);
06900
06901 string get_name() const
06902 {
06903 return NAME;
06904 }
06905
06906 static Processor *NEW()
06907 {
06908 return new ApplyPolynomialProfileToHelix();
06909 }
06910
06911 string get_desc() const
06912 {
06913 return "Finds the CM of each z-axis slice and applies a polynomial radial profile about it.";
06914 }
06915 virtual TypeDict get_param_types() const
06916 {
06917 TypeDict d;
06918 d.put("length", EMObject::FLOAT, "Helix length in angstroms.");
06919 d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06920 return d;
06921 }
06922
06923 static const string NAME;
06924 };
06925
06926 class BinarySkeletonizerProcessor : public Processor
06927 {
06928 public:
06929 virtual EMData* process(EMData * image);
06930 virtual void process_inplace(EMData * image);
06931
06932 virtual string get_name() const
06933 {
06934 return NAME;
06935
06936 }
06937 static Processor *NEW()
06938 {
06939 return new BinarySkeletonizerProcessor();
06940 }
06941 string get_desc() const
06942 {
06943 return "Creates a skeleton of the 3D image by considering whether density is above or below a threshold value.";
06944 }
06945 virtual TypeDict get_param_types() const
06946 {
06947 TypeDict d;
06948 d.put("threshold", EMObject::FLOAT, "Threshold value.");
06949 d.put("min_curve_width", EMObject::INT, "Minimum curve width.");
06950 d.put("min_surface_width", EMObject::INT, "Minimum surface width.");
06951 d.put("mark_surfaces", EMObject::BOOL, "Mark surfaces with a value of 2.0f, whereas curves are 1.0f.");
06952 return d;
06953 }
06954 static const string NAME;
06955 };
06956
06957 class ConvolutionKernelProcessor : public Processor
06958 {
06959 public:
06960 virtual EMData* process(const EMData* const image);
06961 virtual void process_inplace(EMData * image);
06962
06963 virtual string get_name() const
06964 {
06965 return NAME;
06966 }
06967 static Processor *NEW()
06968 {
06969 return new ConvolutionKernelProcessor();
06970 }
06971 string get_desc() const
06972 {
06973 return "Filters an image with a convolution kernel in real space.";
06974 }
06975 virtual TypeDict get_param_types() const
06976 {
06977 TypeDict d;
06978 d.put("kernel", EMObject::FLOATARRAY, "the convolution kernel");
06979 return d;
06980 }
06981 static const string NAME;
06982 };
06983
06984 #ifdef SPARX_USING_CUDA
06985
06986
06987
06988
06989
06990 class MPICUDA_kmeans {
06991 public:
06992 MPICUDA_kmeans();
06993 ~MPICUDA_kmeans();
06994 int setup(int extm, int extN, int extn, int extK, int extn_start);
06995 void append_flat_image(EMData* im, int pos);
06996 int init_mem(int numdev);
06997 void compute_im2();
06998 int random_ASG(long int rnd);
06999 vector<int> get_ASG();
07000 vector<int> get_asg();
07001 void compute_NC();
07002 vector<int> get_NC();
07003 void set_ASG(const vector <int>& ASG);
07004 void set_NC(const vector <int>& NC);
07005 int get_ct_im_mv();
07006 void set_T(float extT);
07007 float get_T();
07008 void compute_AVE();
07009 void set_AVE(EMData* im, int pos);
07010 vector<EMData*> get_AVE();
07011 int one_iter();
07012
07013
07014 int one_iter_SA();
07015 vector<float> compute_ji();
07016 vector<float> compute_criterion(const vector <float>& Ji);
07017 int shutdown();
07018 private:
07019
07020 int m;
07021 int N;
07022 int n;
07023 int K;
07024 int nb_part;
07025 int n_start;
07026 int size_im;
07027 int size_IM;
07028 int size_AVE;
07029 int size_dist;
07030 int BLOCK_SIZE;
07031 int NB;
07032 int ins_BLOCK;
07033 int ite;
07034 float T;
07035
07036 int ct_im_mv;
07037
07038 float* h_IM;
07039 float* h_im;
07040 float* h_AVE;
07041 float* h_dist;
07042 float* h_AVE2;
07043 float* h_im2;
07044 unsigned short int* h_ASG;
07045 unsigned short int* h_asg;
07046 unsigned int* h_NC;
07047 int* params;
07048 float ttt;
07049
07050 float* d_im;
07051 float* d_AVE;
07052 float* d_dist;
07053
07054 float compute_tt();
07055 };
07056
07057 #endif //EMAN2_USING_CUDA
07058
07059 #if 0
07060
07061 class XYZProcessor:public Processor
07062 {
07063 public:
07064 void process_inplace(EMData * image);
07065
07066 string get_name() const
07067 {
07068 return NAME;
07069 }
07070
07071 static Processor *NEW()
07072 {
07073 return new XYZProcessor();
07074 }
07075
07076 string get_desc() const
07077 {
07078 return "N/A";
07079 }
07080
07081 TypeDict get_param_types() const
07082 {
07083 TypeDict d;
07084 return d;
07085 }
07086
07087 static const string NAME;
07088 };
07089
07090
07091 #endif
07092
07093
07094 #if 0
07095
07096 class XYZProcessor:public Processor
07097 {
07098 public:
07099 void process_inplace(EMData * image);
07100
07101 string get_name() const
07102 {
07103 return NAME;
07104 }
07105
07106 static Processor *NEW()
07107 {
07108 return new XYZProcessor();
07109 }
07110
07111 string get_desc() const
07112 {
07113 return "N/A";
07114 }
07115
07116 TypeDict get_param_types() const
07117 {
07118 TypeDict d;
07119 return d;
07120 }
07121
07122 static const string NAME;
07123 };
07124
07125
07126 #endif
07127
07128
07129 int multi_processors(EMData * image, vector < string > processornames);
07130 void dump_processors();
07131 map<string, vector<string> > dump_processors_list();
07132 map<string, vector<string> > group_processors();
07133
07134 template <> Factory < Processor >::Factory();
07135 }
07136
07137 #endif //eman_filter_h__
07138
07139
07140