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