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