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, "1/Resolution in 1/A (0 - 1 / 2*apix). eg - a 20 A filter is cutoff_freq=0.05");
00352 d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
00353 return d;
00354 }
00355
00356 protected:
00357 virtual void preprocess(EMData *image) {
00358 if(params.has_key("apix")) {
00359 image->set_attr("apix_x", (float)params["apix"]);
00360 image->set_attr("apix_y", (float)params["apix"]);
00361 image->set_attr("apix_z", (float)params["apix"]);
00362 }
00363
00364 const Dict dict = image->get_attr_dict();
00365 if( params.has_key("sigma")) {
00366 params["cutoff_abs"] = (float)params["sigma"];
00367 }
00368 else if( params.has_key("cutoff_abs") ) {
00369 params["sigma"] = (float)params["cutoff_abs"];
00370 }
00371 else if( params.has_key("cutoff_freq") ) {
00372 float val = (float)params["cutoff_freq"] * (float)dict["apix_x"];
00373 params["cutoff_abs"] = val;
00374 params["sigma"] = val;
00375 }
00376 else if( params.has_key("cutoff_pixels") ) {
00377 float val = (0.5f*(float)params["cutoff_pixels"] / (float)dict["nx"]);
00378 params["cutoff_abs"] = val;
00379 params["sigma"] = val;
00380 }
00381
00382 }
00383 virtual void create_radial_func(vector < float >&radial_mask) const = 0;
00384 };
00385
00393 class FourierAnlProcessor:public Processor
00394 {
00395 public:
00396 void process_inplace(EMData * image);
00397
00398 static string get_group_desc()
00399 {
00400 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]. ";
00401 }
00402
00403 TypeDict get_param_types() const
00404 {
00405 TypeDict d;
00406 d.put("cutoff_abs", EMObject::FLOAT, "Processor radius in terms of Nyquist (0-.5)");
00407 d.put("cutoff_pixels", EMObject::FLOAT, " Width in Fourier pixels (0 - size()/2)");
00408 d.put("cutoff_freq", EMObject::FLOAT, "1/Resolution in 1/A (0 - 1 / 2*apix). eg - a 20 A filter is cutoff_freq=0.05");
00409 d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
00410 return d;
00411 }
00412
00413 protected:
00414 virtual void preprocess(EMData *) {}
00415 virtual void create_radial_func(vector < float >&radial_mask,EMData *image) const = 0;
00416 };
00417
00420 class SNREvalProcessor:public Processor
00421 {
00422 public:
00423 string get_name() const
00424 {
00425 return NAME;
00426 }
00427
00428 void process_inplace(EMData * image);
00429
00430 void set_params(const Dict & new_params)
00431 {
00432 params = new_params;
00433
00434
00435
00436 }
00437
00438 TypeDict get_param_types() const
00439 {
00440 TypeDict d;
00441
00442
00443 return d;
00444 }
00445
00446 static Processor *NEW()
00447 {
00448 return new SNREvalProcessor();
00449 }
00450
00451 string get_desc() const
00452 {
00453 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";
00454 }
00455
00456 static const string NAME;
00457
00458 protected:
00459 EMData *sum;
00460 int dosqrt;
00461 };
00462
00463
00468 class AmpweightFourierProcessor:public Processor
00469 {
00470 public:
00471 string get_name() const
00472 {
00473 return NAME;
00474 }
00475
00476 void process_inplace(EMData * image);
00477
00478 void set_params(const Dict & new_params)
00479 {
00480 params = new_params;
00481 sum = params["sum"];
00482 dosqrt = params["sqrt"];
00483
00484 }
00485
00486 TypeDict get_param_types() const
00487 {
00488 TypeDict d;
00489 d.put("sum", EMObject::EMDATA, "Adds the weights to sum for normalization");
00490 d.put("sqrt", EMObject::INT, "Weights using sqrt of the amplitude if set");
00491 return d;
00492 }
00493
00494 static Processor *NEW()
00495 {
00496 return new AmpweightFourierProcessor();
00497 }
00498
00499 string get_desc() const
00500 {
00501 return "Multiplies each Fourier pixel by its amplitude";
00502 }
00503
00504 static const string NAME;
00505
00506 protected:
00507 EMData *sum;
00508 int dosqrt;
00509 };
00516 class ConvolutionProcessor : public Processor
00517 {
00518 public:
00519 ConvolutionProcessor() {}
00520
00521 string get_name() const
00522 {
00523 return NAME;
00524 }
00525
00526 void process_inplace(EMData *image);
00527
00528 static Processor *NEW()
00529 {
00530 return new ConvolutionProcessor();
00531 }
00532
00533 string get_desc() const
00534 {
00535 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.";
00536 }
00537
00538 TypeDict get_param_types() const
00539 {
00540 TypeDict d;
00541 d.put("with", EMObject::EMDATA, "The image that will convolute the other image");
00542 return d;
00543 }
00544
00545 static const string NAME;
00546 };
00547
00554 class XGradientProcessor : public Processor
00555 {
00556 public:
00557 XGradientProcessor() {}
00558
00559 string get_name() const
00560 {
00561 return NAME;
00562 }
00563
00564 void process_inplace(EMData *image);
00565
00566 static Processor *NEW()
00567 {
00568 return new XGradientProcessor();
00569 }
00570
00571 string get_desc() const
00572 {
00573 return "Determines the image gradient in the x direction";
00574 }
00575
00576 TypeDict get_param_types() const
00577 {
00578 TypeDict d;
00579 return d;
00580 }
00581
00582 static const string NAME;
00583 };
00584
00585 class YGradientProcessor : public Processor
00586 {
00587 public:
00588 YGradientProcessor() {}
00589
00590 string get_name() const
00591 {
00592 return NAME;
00593 }
00594
00595 void process_inplace(EMData *image);
00596
00597 static Processor *NEW()
00598 {
00599 return new YGradientProcessor();
00600 }
00601
00602 string get_desc() const
00603 {
00604 return "Determines the image gradient in the y direction";
00605 }
00606
00607
00608 TypeDict get_param_types() const
00609 {
00610 TypeDict d;
00611 return d;
00612 }
00613
00614 static const string NAME;
00615 };
00616
00617 class ZGradientProcessor : public Processor
00618 {
00619 public:
00620 ZGradientProcessor() {}
00621
00622 string get_name() const
00623 {
00624 return NAME;
00625 }
00626
00627 void process_inplace(EMData *image);
00628
00629 static Processor *NEW()
00630 {
00631 return new ZGradientProcessor();
00632 }
00633
00634 string get_desc() const
00635 {
00636 return "Determines the image gradient in the z direction";
00637 }
00638
00639 TypeDict get_param_types() const
00640 {
00641 TypeDict d;
00642 return d;
00643 }
00644
00645 static const string NAME;
00646 };
00647
00656 class Wiener2DAutoAreaProcessor:public Processor
00657 {
00658 public:
00659 string get_name() const
00660 {
00661 return NAME;
00662 }
00663
00664 virtual EMData* process(const EMData * const image);
00665
00666 void process_inplace(EMData *image);
00667
00668 void set_params(const Dict & new_params)
00669 {
00670 params = new_params;
00671 bgsize = params["size"];
00672
00673 }
00674
00675 TypeDict get_param_types() const
00676 {
00677 TypeDict d;
00678 d.put("size", EMObject::INT, "Size in pixels of the boxes to chop the image into");
00679 return d;
00680 }
00681
00682 static Processor *NEW()
00683 {
00684 return new Wiener2DAutoAreaProcessor();
00685 }
00686
00687 string get_desc() const
00688 {
00689 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";
00690 }
00691
00692 static const string NAME;
00693
00694 protected:
00695 int bgsize;
00696 };
00697
00704 class DistanceSegmentProcessor:public Processor
00705 {
00706 public:
00707 string get_name() const
00708 {
00709 return NAME;
00710 }
00711
00712 virtual EMData* process(const EMData * const image);
00713 void process_inplace( EMData * image);
00714
00715 TypeDict get_param_types() const
00716 {
00717 TypeDict d ;
00718 d.put("thr",EMObject::FLOAT,"Optional : Isosurface threshold value. Pixels below this will not be segment centers (default = 0.9)");
00719 d.put("minsegsep",EMObject::FLOAT,"Required: Minimum segment separation in pixels. Segments too close will trigger a reseed");
00720 d.put("maxsegsep",EMObject::FLOAT,"Required: Maximum segment separation in pixels. Segments too close will trigger a reseed");
00721 d.put("verbose",EMObject::INT,"Be verbose while running");
00722 return d;
00723 }
00724
00725 static Processor *NEW()
00726 {
00727 return new DistanceSegmentProcessor();
00728 }
00729
00730 string get_desc() const
00731 {
00732 return "Segments a volume into pieces separated by distances in the specified range.";
00733 }
00734
00735 static const string NAME;
00736
00737 };
00738
00745 class KmeansSegmentProcessor:public Processor
00746 {
00747 public:
00748 string get_name() const
00749 {
00750 return NAME;
00751 }
00752
00753 virtual EMData* process(const EMData * const image);
00754 void process_inplace( EMData * image);
00755
00756 TypeDict get_param_types() const
00757 {
00758 TypeDict d ;
00759 d.put("nseg", EMObject::INT, "Number of segments to divide the image into. default=12" );
00760 d.put("thr",EMObject::FLOAT,"Isosurface threshold value. Pixels below this will not be segmented");
00761 d.put("ampweight",EMObject::INT,"If set, will weight centers by voxel amplitude. default = 1");
00762 d.put("maxsegsize",EMObject::FLOAT,"Maximum radial distance from segment center to member voxel. Default=10000");
00763 d.put("minsegsep",EMObject::FLOAT,"Minimum segment separation. Segments too close will trigger a reseed");
00764 d.put("maxiter",EMObject::FLOAT,"Maximum number of iterations to run before stopping. Default=100");
00765 d.put("maxvoxmove",EMObject::FLOAT,"Maximum number of voxels that can move before quitting. Default=25");
00766 d.put("verbose",EMObject::INT,"Be verbose while running");
00767 return d;
00768 }
00769
00770 static Processor *NEW()
00771 {
00772 return new KmeansSegmentProcessor();
00773 }
00774
00775 string get_desc() const
00776 {
00777 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.";
00778 }
00779
00780 static const string NAME;
00781
00782 };
00783
00797 class CtfSimProcessor:public Processor
00798 {
00799 public:
00800 string get_name() const
00801 {
00802 return NAME;
00803 }
00804
00805 virtual EMData* process(const EMData * const image);
00806
00807 void process_inplace(EMData *image);
00808
00809 TypeDict get_param_types() const
00810 {
00811 TypeDict d;
00812 d.put("defocus", EMObject::FLOAT, "Defocus in microns (underfocus positive)");
00813 d.put("ampcont", EMObject::FLOAT, "% amplitude contrast (0-100)");
00814 d.put("bfactor", EMObject::FLOAT, "B-factor in A^2, uses MRC convention rather than EMAN1 convention");
00815 d.put("noiseamp", EMObject::FLOAT, "Amplitude of the added empirical pink noise");
00816 d.put("noiseampwhite", EMObject::FLOAT, "Amplitude of added white noise");
00817 d.put("voltage", EMObject::FLOAT, "Microscope voltage in KV");
00818 d.put("cs", EMObject::FLOAT, "Cs of microscope in mm");
00819 d.put("apix", EMObject::FLOAT, "A/pix of data");
00820 return d;
00821 }
00822
00823 static Processor *NEW()
00824 {
00825 return new CtfSimProcessor();
00826 }
00827
00828 string get_desc() const
00829 {
00830 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. ";
00831 }
00832
00833 static const string NAME;
00834
00835
00836 };
00837
00838
00845 class Wiener2DFourierProcessor:public Processor
00846 {
00847 public:
00848 string get_name() const
00849 {
00850 return NAME;
00851 }
00852
00853 virtual EMData* process(const EMData * const image);
00854
00855 void process_inplace(EMData *image);
00856
00857 void set_params(const Dict & new_params)
00858 {
00859 params = new_params;
00860 ctf = params["ctf"];
00861
00862 }
00863
00864 TypeDict get_param_types() const
00865 {
00866 TypeDict d;
00867 d.put("ctf", EMObject::EMDATA, "Ctf object to use for Wiener filter parameters");
00868 return d;
00869 }
00870
00871 static Processor *NEW()
00872 {
00873 return new Wiener2DFourierProcessor();
00874 }
00875
00876 string get_desc() const
00877 {
00878 return "Applies a 2-D Wiener filter to an image based on its Ctf parameters";
00879 }
00880
00881 static const string NAME;
00882
00883 protected:
00884 Ctf *ctf;
00885 };
00886
00887 class LinearRampFourierProcessor:public FourierProcessor
00888 {
00889 public:
00890 virtual string get_name() const
00891 {
00892 return NAME;
00893 }
00894
00895 virtual string get_desc() const
00896 {
00897 return "";
00898 }
00899
00900 static Processor *NEW()
00901 {
00902 return new LinearRampFourierProcessor();
00903 }
00904
00905 static const string NAME;
00906
00907 protected:
00908 virtual void create_radial_func(vector < float >&radial_mask) const ;
00909 };
00910
00911
00914 class LowpassRandomPhaseProcessor:public FourierProcessor
00915 {
00916 public:
00917 string get_name() const
00918 { return NAME; }
00919 static Processor *NEW() { return new LowpassRandomPhaseProcessor(); }
00920 string get_desc() const
00921 {
00922 return "Above the cutoff frequency, phases will be completely randomized, but amplitudes will be unchanged. Used for testing for noise bias. If you can reconstruct information that isn't there, then you have noise bias problems.";
00923 }
00924 void process_inplace(EMData * image);
00925 void create_radial_func(vector < float >&radial_mask) const;
00926
00927 static const string NAME;
00928 };
00929
00930
00933 class LowpassAutoBProcessor:public FourierAnlProcessor
00934 {
00935 public:
00936 string get_name() const
00937 {
00938 return NAME;
00939 }
00940
00941 static Processor *NEW()
00942 {
00943 return new LowpassAutoBProcessor();
00944 }
00945
00946 string get_desc() const
00947 {
00948 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.";
00949 }
00950
00951 static const string NAME;
00952
00953 virtual TypeDict get_param_types() const
00954 {
00955 TypeDict d = FourierAnlProcessor::get_param_types();
00956 d.put("bfactor", EMObject::FLOAT, "B-factor in terms of e^-(B s^2/4)");
00957 d.put("noisecutoff", EMObject::FLOAT, "Spatial frequency past which inverse-B will not be applied");
00958
00959 d.put("verbose", EMObject::INT, "Print information about the determined B-factor");
00960 return d;
00961 }
00962
00963 protected:
00964 virtual void preprocess(EMData * image) {
00965 if(params.has_key("apix")) {
00966 image->set_attr("apix_x", (float)params["apix"]);
00967 image->set_attr("apix_y", (float)params["apix"]);
00968 image->set_attr("apix_z", (float)params["apix"]);
00969 }
00970 float apix=(float)image->get_attr("apix_x");
00971
00972 const Dict dict = image->get_attr_dict();
00973 if (params.has_key("cutoff_abs")) {
00974 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00975 }
00976 else if( params.has_key("cutoff_freq") ) {
00977 float val = (float)params["cutoff_freq"] * apix;
00978 params["cutoff_abs"] = val;
00979 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00980 }
00981 else if( params.has_key("cutoff_pixels") ) {
00982 float val = 0.5f*(float)params["cutoff_pixels"] / (float)dict["nx"];
00983 params["cutoff_abs"] = val;
00984 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00985 }
00986 }
00987
00988 void create_radial_func(vector < float >&radial_mask,EMData *image) const;
00989 };
00990
00993 class HighpassAutoPeakProcessor:public FourierAnlProcessor
00994 {
00995 public:
00996 string get_name() const
00997 {
00998 return NAME;
00999 }
01000 static Processor *NEW()
01001 {
01002 return new HighpassAutoPeakProcessor();
01003 }
01004
01005 string get_desc() const
01006 {
01007 return "Attempts to automatically remove the low resolution peak present in virtually all cryoEM data.";
01008 }
01009
01010 static const string NAME;
01011
01012 protected:
01013 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
01014 virtual void preprocess(EMData * image);
01015 float highpass;
01016 };
01017
01022 class LinearRampProcessor:public FourierProcessor
01023 {
01024 public:
01025 LinearRampProcessor():intercept(0), slope(0)
01026 {
01027 }
01028
01029 string get_name() const
01030 {
01031 return NAME;
01032 }
01033 static Processor *NEW()
01034 {
01035 return new LinearRampProcessor();
01036 }
01037
01038 string get_desc() const
01039 {
01040 return "processor radial function: f(x) = slope * x + intercept;";
01041 }
01042
01043 void set_params(const Dict & new_params)
01044 {
01045 params = new_params;
01046 intercept = params["intercept"];
01047 slope = params["slope"];
01048 }
01049
01050 TypeDict get_param_types() const
01051 {
01052 TypeDict d;
01053 d.put("intercept", EMObject::FLOAT, "intercept in 'f(x) = slope * x + intercept'");
01054 d.put("slope", EMObject::FLOAT, "slope in 'f(x) = slope * x + intercept'");
01055 return d;
01056 }
01057
01058 static const string NAME;
01059
01060 protected:
01061 void create_radial_func(vector < float >&radial_mask) const;
01062
01063 private:
01064 float intercept;
01065 float slope;
01066 };
01067
01071 class LoGFourierProcessor:public FourierProcessor
01072 {
01073 public:
01074 LoGFourierProcessor():sigma(0)
01075 {
01076 }
01077
01078 string get_name() const
01079 {
01080 return NAME;
01081 }
01082 static Processor *NEW()
01083 {
01084 return new LoGFourierProcessor();
01085 }
01086
01087 string get_desc() const
01088 {
01089 return "processor radial function: f(x) = ((x^2 - s^2)/s^4)e^-(x^2/2s^2)";
01090 }
01091
01092 void set_params(const Dict & new_params)
01093 {
01094 params = new_params;
01095 sigma = params["sigma"];
01096 }
01097
01098 TypeDict get_param_types() const
01099 {
01100 TypeDict d;
01101 d.put("sigma", EMObject::FLOAT, "LoG sigma");
01102 return d;
01103 }
01104
01105 static const string NAME;
01106
01107 protected:
01108 void create_radial_func(vector < float >&radial_mask) const;
01109
01110 private:
01111 float sigma;
01112 };
01113
01118 class DoGFourierProcessor:public FourierProcessor
01119 {
01120 public:
01121 DoGFourierProcessor():sigma1(0), sigma2(0)
01122 {
01123 }
01124
01125 string get_name() const
01126 {
01127 return NAME;
01128 }
01129 static Processor *NEW()
01130 {
01131 return new DoGFourierProcessor();
01132 }
01133
01134 string get_desc() const
01135 {
01136 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)]";
01137 }
01138
01139 void set_params(const Dict & new_params)
01140 {
01141 params = new_params;
01142 sigma1 = params["sigma1"];
01143 sigma2 = params["sigma2"];
01144 }
01145
01146 TypeDict get_param_types() const
01147 {
01148 TypeDict d;
01149 d.put("sigma1", EMObject::FLOAT, "DoG sigma1");
01150 d.put("sigma2", EMObject::FLOAT, "DoG sigma2");
01151 return d;
01152 }
01153
01154 static const string NAME;
01155
01156 protected:
01157 void create_radial_func(vector < float >&radial_mask) const;
01158
01159 private:
01160 float sigma1;
01161 float sigma2;
01162 };
01163
01166 class RealPixelProcessor:public Processor
01167 {
01168 public:
01169 RealPixelProcessor():value(0), maxval(1), mean(0), sigma(0)
01170 {
01171 }
01172 void process_inplace(EMData * image);
01173
01174 virtual void set_params(const Dict & new_params)
01175 {
01176 params = new_params;
01177 if (params.size() == 1) {
01178 vector < EMObject > dict_values = params.values();
01179 value = dict_values[0];
01180 }
01181 }
01182
01183 static string get_group_desc()
01184 {
01185 return "The base class for real space processor working on individual pixels. The processor won't consider the pixel's coordinates and neighbors.";
01186 }
01187
01188 protected:
01189 virtual void process_pixel(float *x) const = 0;
01190 virtual void calc_locals(EMData *)
01191 {
01192 }
01193 virtual void normalize(EMData *) const
01194 {
01195 }
01196
01197 float value;
01198 float maxval;
01199 float mean;
01200 float sigma;
01201 };
01202
01205 class AbsoluateValueProcessor:public RealPixelProcessor
01206 {
01207 public:
01208 string get_name() const
01209 {
01210 return NAME;
01211 }
01212 static Processor *NEW()
01213 {
01214 return new AbsoluateValueProcessor();
01215 }
01216
01217 static const string NAME;
01218
01219 protected:
01220 void process_pixel(float *x) const
01221 {
01222 *x = fabs(*x);
01223 }
01224
01225 string get_desc() const
01226 {
01227 return "f(x) = |x|";
01228 }
01229 };
01230
01233 class FloorValueProcessor:public RealPixelProcessor
01234 {
01235 public:
01236 string get_name() const
01237 {
01238 return NAME;
01239 }
01240 static Processor *NEW()
01241 {
01242 return new FloorValueProcessor();
01243 }
01244
01245 static const string NAME;
01246
01247 protected:
01248 void process_pixel(float *x) const
01249 {
01250 *x = floor(*x);
01251 }
01252
01253 string get_desc() const
01254 {
01255 return "f(x) = floor(x)";
01256 }
01257 };
01258
01259
01262 class BooleanProcessor:public RealPixelProcessor
01263 {
01264 public:
01265 string get_name() const
01266 {
01267 return NAME;
01268 }
01269 static Processor *NEW()
01270 {
01271 return new BooleanProcessor();
01272 }
01273
01274 string get_desc() const
01275 {
01276 return "f(x) = 0 if x = 0; f(x) = 1 if x != 0;";
01277 }
01278
01279 static const string NAME;
01280
01281 protected:
01282 void process_pixel(float *x) const
01283 {
01284 if (*x != 0)
01285 {
01286 *x = 1.0;
01287 }
01288 }
01289 };
01290
01294 class RecipCarefullyProcessor:public RealPixelProcessor
01295 {
01296 public:
01297 string get_name() const
01298 {
01299 return NAME;
01300 }
01301 static Processor *NEW()
01302 {
01303 return new RecipCarefullyProcessor();
01304 }
01305
01306 void set_params(const Dict & new_params)
01307 {
01308 params = new_params;
01309 zero_to = params.set_default("zero_to",0.0f);
01310 }
01311
01312 TypeDict get_param_types() const
01313 {
01314 TypeDict d;
01315 d.put("zero_to", EMObject::FLOAT, "Inverted zero values are set to this value, default is 0.");
01316 return d;
01317 }
01318
01319 string get_desc() const
01320 {
01321 return "if f(x) != 0: f(x) = 1/f(x) else: f(x) = zero_to";
01322 }
01323
01324 static const string NAME;
01325
01326 protected:
01327 void process_pixel(float *x) const
01328 {
01329 if (*x == 0.0) *x = zero_to;
01330 else *x = 1.0f/(*x);
01331 }
01332 private:
01333 float zero_to;
01334 };
01335
01339 class ValuePowProcessor:public RealPixelProcessor
01340 {
01341 public:
01342 string get_name() const
01343 {
01344 return NAME;
01345 }
01346 static Processor *NEW()
01347 {
01348 return new ValuePowProcessor();
01349 }
01350
01351 void set_params(const Dict & new_params)
01352 {
01353 params = new_params;
01354 pwr = params["pow"];
01355 }
01356
01357 TypeDict get_param_types() const
01358 {
01359 TypeDict d;
01360 d.put("pow", EMObject::FLOAT, "Each pixel is raised to this power");
01361 return d;
01362 }
01363
01364 string get_desc() const
01365 {
01366 return "f(x) = x ^ pow;";
01367 }
01368
01369 static const string NAME;
01370
01371 protected:
01372 void process_pixel(float *x) const
01373 {
01374 if (*x<0 && pwr!=(int)pwr) *x=0;
01375 else (*x) = pow(*x,pwr);
01376 }
01377 private:
01378 float pwr;
01379 };
01380
01383 class ValueSquaredProcessor:public RealPixelProcessor
01384 {
01385 public:
01386 string get_name() const
01387 {
01388 return NAME;
01389 }
01390 static Processor *NEW()
01391 {
01392 return new ValueSquaredProcessor();
01393 }
01394
01395
01396 string get_desc() const
01397 {
01398 return "f(x) = x * x;";
01399 }
01400
01401 static const string NAME;
01402
01403 protected:
01404 void process_pixel(float *x) const
01405 {
01406 (*x) *= (*x);
01407 }
01408 };
01409
01412 class ValueSqrtProcessor:public RealPixelProcessor
01413 {
01414 public:
01415 string get_name() const
01416 {
01417 return NAME;
01418 }
01419 static Processor *NEW()
01420 {
01421 return new ValueSqrtProcessor();
01422 }
01423
01424 string get_desc() const
01425 {
01426 return "f(x) = sqrt(x)";
01427 }
01428
01429 static const string NAME;
01430
01431 protected:
01432 void process_pixel(float *x) const
01433 {
01434 *x = sqrt(*x);
01435 }
01436 };
01437
01441 class ToZeroProcessor:public RealPixelProcessor
01442 {
01443 public:
01444 string get_name() const
01445 {
01446 return NAME;
01447 }
01448 static Processor *NEW()
01449 {
01450 return new ToZeroProcessor();
01451 }
01452 TypeDict get_param_types() const
01453 {
01454 TypeDict d;
01455 d.put("minval", EMObject::FLOAT, "Everything below this value is set to zero");
01456 return d;
01457 }
01458
01459 string get_desc() const
01460 {
01461 return "f(x) = x if x >= minval; f(x) = 0 if x < minval.";
01462 }
01463
01464 static const string NAME;
01465
01466 protected:
01467 inline void process_pixel(float *x) const
01468 {
01469 if (*x < value) {
01470 *x = 0;
01471 }
01472 }
01473 };
01474
01480 class Rotate180Processor:public Processor
01481 {
01482 public:
01483 string get_name() const
01484 {
01485 return NAME;
01486 }
01487 static Processor *NEW()
01488 {
01489 return new Rotate180Processor();
01490 }
01491
01495 void process_inplace(EMData* image);
01496
01497 string get_desc() const
01498 {
01499 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.";
01500 }
01501
01502 static const string NAME;
01503 };
01504
01511 class TransformProcessor:public Processor
01512 {
01513 public:
01514 virtual string get_name() const
01515 {
01516 return NAME;
01517 }
01518 static Processor *NEW()
01519 {
01520 return new TransformProcessor();
01521 }
01522
01527 virtual void process_inplace(EMData* image);
01528
01533 virtual EMData* process(const EMData* const image);
01534
01535 virtual TypeDict get_param_types() const
01536 {
01537 TypeDict d;
01538 d.put("transform", EMObject::TRANSFORM, "The Transform object that will be applied to the image" );
01539 return d;
01540 }
01541
01542 virtual string get_desc() const
01543 {
01544 return "The image is transformed using Transform parameter.";
01545 }
01546
01547 static const string NAME;
01548
01549 float* transform(const EMData* const image, const Transform& t) const;
01550 private:
01551
01552
01553
01554
01555 void assert_valid_aspect(const EMData* const image) const;
01556 };
01557
01565 class IntTranslateProcessor:public Processor
01566 {
01567 public:
01568 virtual string get_name() const
01569 {
01570 return NAME;
01571 }
01572
01573 static Processor *NEW()
01574 {
01575 return new IntTranslateProcessor();
01576 }
01577
01582 virtual void process_inplace(EMData* image);
01583
01588 virtual EMData* process(const EMData* const image);
01589
01590 virtual TypeDict get_param_types() const
01591 {
01592 TypeDict d;
01593 d.put("trans", EMObject::INTARRAY, "The displacement array, can be length 1-3" );
01594 return d;
01595 }
01596
01597 virtual string get_desc() const
01598 {
01599 return "The image is translated an integer amount";
01600 }
01601
01602 static const string NAME;
01603
01604 private:
01608 void assert_valid_aspect(const vector<int>& translation, const EMData* const image) const;
01609
01615 Region get_clip_region(vector<int>& translation, const EMData* const image) const;
01616 };
01617
01623 class ApplySymProcessor:public Processor
01624 {
01625 public:
01626 virtual string get_name() const
01627 {
01628 return NAME;
01629 }
01630
01631 static Processor *NEW()
01632 {
01633 return new ApplySymProcessor();
01634 }
01635
01636 virtual void process_inplace(EMData* image);
01637
01638 virtual EMData* process(const EMData* const image);
01639
01640 virtual TypeDict get_param_types() const
01641 {
01642 TypeDict d;
01643 d.put("sym", EMObject::STRING, "The symmetry under which to do the alignment, Default=c1" );
01644 return d;
01645 }
01646
01647 virtual string get_desc() const
01648 {
01649 return "Symmetry is applied to the 3D EM object";
01650 }
01651
01652 static const string NAME;
01653
01654 };
01655
01662 class ScaleTransformProcessor:public Processor
01663 {
01664 public:
01665 virtual string get_name() const
01666 {
01667 return NAME;
01668 }
01669 static Processor *NEW()
01670 {
01671 return new ScaleTransformProcessor();
01672 }
01677 virtual void process_inplace(EMData* image);
01678
01683 virtual EMData* process(const EMData* const image);
01684
01685 virtual TypeDict get_param_types() const
01686 {
01687 TypeDict d;
01688 d.put("scale", EMObject::FLOAT, "The amount by which to scale" );
01689 d.put("clip", EMObject::INT, "The length of each output dimension. Non sophisticated, output dimensions can't be different" );
01692 return d;
01693 }
01694
01695 virtual string get_desc() const
01696 {
01697 return "The image is scaled with the clip variable in mind, being sure to preserve as much pixel information as possible.";
01698 }
01699
01700 static const string NAME;
01701 };
01702
01709 class ClampingProcessor :public Processor
01710 {
01711 public:
01712 ClampingProcessor() : default_max(1.0), default_min(0.0) {}
01713
01714 string get_name() const
01715 {
01716 return NAME;
01717 }
01718 static Processor *NEW()
01719 {
01720 return new ClampingProcessor();
01721 }
01722
01723 void process_inplace(EMData *image);
01724
01725 TypeDict get_param_types() const
01726 {
01727 TypeDict d;
01728 d.put("minval", EMObject::FLOAT, "The pixel values that bounds the smallest pixel value in the output image" );
01729 d.put("maxval", EMObject::FLOAT, "The pixel values that bounds the largest pixel value in the output image" );
01730 d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01731 d.put("tozero", EMObject::BOOL, "Replace outlying pixels values with zero" );
01732 return d;
01733 }
01734
01735 string get_desc() const
01736 {
01737 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.";
01738 }
01739
01740 static const string NAME;
01741
01742 protected:
01743 float default_max, default_min;
01744 };
01745
01751 class NSigmaClampingProcessor : public ClampingProcessor
01752 {
01753 public:
01754 NSigmaClampingProcessor() : default_sigma(2.0) {}
01755
01756 string get_name() const
01757 {
01758 return NAME;
01759 }
01760
01761 static Processor *NEW()
01762 {
01763 return new NSigmaClampingProcessor();
01764 }
01765
01766 TypeDict get_param_types() const
01767 {
01768 TypeDict d;
01769 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" );
01770 d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01771 d.put("tozero", EMObject::BOOL, "Replace outlying pixels values with zero" );
01772 return d;
01773 }
01774
01775 void process_inplace(EMData *image);
01776
01777 string get_desc() const
01778 {
01779 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.";
01780 }
01781
01782 static const string NAME;
01783
01784 protected:
01785 float default_sigma;
01786 };
01787
01791 class ToMinvalProcessor:public Processor
01792 {
01793 public:
01794 string get_name() const
01795 {
01796 return NAME;
01797 }
01798 static Processor *NEW()
01799 {
01800 return new ToMinvalProcessor();
01801 }
01802
01803 void process_inplace(EMData *image);
01804
01805 TypeDict get_param_types() const
01806 {
01807 TypeDict d;
01808 d.put("minval", EMObject::FLOAT, "Everything below this value is set to this value");
01809 d.put("newval", EMObject::FLOAT, "If set, values below minval will be set to newval instead of minval ");
01810 return d;
01811 }
01812
01813 string get_desc() const
01814 {
01815 return "f(x) = x if x >= minval; f(x) = minval|newval if x < minval.";
01816 }
01817
01818 static const string NAME;
01819
01820 protected:
01821
01822 };
01823
01824
01825
01829 class CutToZeroProcessor:public RealPixelProcessor
01830 {
01831 public:
01832 string get_name() const
01833 {
01834 return NAME;
01835 }
01836 static Processor *NEW()
01837 {
01838 return new CutToZeroProcessor();
01839 }
01840 TypeDict get_param_types() const
01841 {
01842 TypeDict d;
01843 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" );
01844 return d;
01845 }
01846
01847 string get_desc() const
01848 {
01849 return "f(x) = x-minval if x >= minval; f(x) = 0 if x < minval.";
01850 }
01851
01852 static const string NAME;
01853
01854 protected:
01855 void process_pixel(float *x) const
01856 {
01857 *x = *x - value;
01858 if (*x < 0) {
01859 *x = 0;
01860 }
01861 }
01862 };
01863
01867 class BinarizeProcessor:public RealPixelProcessor
01868 {
01869 public:
01870 string get_name() const
01871 {
01872 return NAME;
01873 }
01874 static Processor *NEW()
01875 {
01876 return new BinarizeProcessor();
01877 }
01878 TypeDict get_param_types() const
01879 {
01880 TypeDict d;
01881 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" );
01882 return d;
01883 }
01884
01885 string get_desc() const
01886 {
01887 return "f(x) = 0 if x < value; f(x) = 1 if x >= value.";
01888 }
01889
01890 static const string NAME;
01891
01892 protected:
01893 void process_pixel(float *x) const
01894 {
01895 if (*x < value)
01896 {
01897 *x = 0;
01898 }
01899 else
01900 {
01901 *x = 1;
01902 }
01903 }
01904 };
01905
01913 class BinarizeFourierProcessor:public Processor
01914 {
01915 public:
01916 virtual string get_name() const
01917 {
01918 return NAME;
01919 }
01920 static Processor *NEW()
01921 {
01922 return new BinarizeFourierProcessor();
01923 }
01924
01929 virtual void process_inplace(EMData* image);
01930
01931 virtual TypeDict get_param_types() const
01932 {
01933 TypeDict d;
01934 d.put("value", EMObject::FLOAT, "The Fourier amplitude threshold cutoff" );
01935 return d;
01936 }
01937
01938 virtual string get_desc() const
01939 {
01940 return "f(k) = 0 + 0i if ||f(k)|| < value; f(k) = a + bi if ||f(k)|| >= value.";
01941 }
01942
01943 static const string NAME;
01944 };
01945
01950 class CollapseProcessor:public RealPixelProcessor
01951 {
01952 public:
01953 string get_name() const
01954 {
01955 return NAME;
01956 }
01957 static Processor *NEW()
01958 {
01959 return new CollapseProcessor();
01960 }
01961
01962 void set_params(const Dict & new_params)
01963 {
01964 params = new_params;
01965 range = params["range"];
01966 value = params["value"];
01967 }
01968
01969 TypeDict get_param_types() const
01970 {
01971 TypeDict d;
01972 d.put("range", EMObject::FLOAT, "The range about 'value' which will be collapsed to 'value'");
01973 d.put("value", EMObject::FLOAT, "The pixel value where the focus of the collapse operation is");
01974 return d;
01975 }
01976
01977 string get_desc() const
01978 {
01979 return "f(x): if v-r<x<v+r -> v; if x>v+r -> x-r; if x<v-r -> x+r";
01980 }
01981
01982 static const string NAME;
01983
01984 protected:
01985 void process_pixel(float *x) const
01986 {
01987 if (*x>value+range) *x-=range;
01988 else if (*x<value-range) *x+=range;
01989 else *x=value;
01990 }
01991 float range;
01992 };
01993
01998 class LinearXformProcessor:public RealPixelProcessor
01999 {
02000 public:
02001 LinearXformProcessor():shift(0), scale(0)
02002 {
02003 }
02004
02005 string get_name() const
02006 {
02007 return NAME;
02008 }
02009 static Processor *NEW()
02010 {
02011 return new LinearXformProcessor();
02012 }
02013
02014 void set_params(const Dict & new_params)
02015 {
02016 params = new_params;
02017 shift = params.get("shift");
02018 scale = params.get("scale");
02019 }
02020
02021 TypeDict get_param_types() const
02022 {
02023 TypeDict d;
02024 d.put("shift", EMObject::FLOAT, "The amount to shift pixel values by before scaling");
02025 d.put("scale", EMObject::FLOAT, "The scaling factor to be applied to pixel values");
02026 return d;
02027 }
02028
02029 string get_desc() const
02030 {
02031 return "linear transform processor: f(x) = x * scale + shift. This is equivalent to a regular contrast stretching operation";
02032 }
02033
02034 static const string NAME;
02035
02036 protected:
02037 void process_pixel(float *x) const
02038 {
02039 *x = (*x) * scale + shift;
02040 }
02041
02042 private:
02043 float shift;
02044 float scale;
02045 };
02046
02051 class ExpProcessor:public RealPixelProcessor
02052 {
02053 public:
02054 ExpProcessor():low(0), high(0)
02055 {
02056 }
02057
02058 string get_name() const
02059 {
02060 return NAME;
02061 }
02062
02063 static Processor *NEW()
02064 {
02065 return new ExpProcessor();
02066 }
02067
02068 void set_params(const Dict & new_params)
02069 {
02070 params = new_params;
02071 low = params.get("low");
02072 high = params.get("high");
02073 }
02074
02075 TypeDict get_param_types() const
02076 {
02077 TypeDict d;
02078 d.put("low", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
02079 d.put("high", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
02080 return d;
02081 }
02082
02083 string get_desc() const
02084 {
02085 return "f(x) = exp( x / low - high)";
02086 }
02087
02088 static const string NAME;
02089
02090 protected:
02094 void process_pixel(float *x) const
02095 {
02096 float v = *x / low - high;
02097 if (v > 40) {
02098 v = 40;
02099 }
02100 *x = exp(v);
02101 }
02102
02103 private:
02104 float low;
02105 float high;
02106 };
02107
02111 class FiniteProcessor:public RealPixelProcessor
02112 {
02113 public:
02114 FiniteProcessor():to(0)
02115 {
02116 }
02117
02118 string get_name() const
02119 {
02120 return NAME;
02121 }
02122
02123 static Processor *NEW()
02124 {
02125 return new FiniteProcessor();
02126 }
02127
02128 void set_params(const Dict & new_params)
02129 {
02130 if (new_params.has_key("to") )
02131 to = params["to"];
02132 }
02133
02134 TypeDict get_param_types() const
02135 {
02136 TypeDict d;
02137 d.put("to", EMObject::FLOAT, "Pixels which are not finite will be set to this value");
02138 return d;
02139 }
02140
02141 string get_desc() const
02142 {
02143 return "f(x) = f(x) if f(x) is finite | to if f(x) is not finite";
02144 }
02145
02146 static const string NAME;
02147
02148 protected:
02152 void process_pixel(float *x) const;
02153 private:
02154 float to;
02155 };
02156
02161 class RangeThresholdProcessor:public RealPixelProcessor
02162 {
02163 public:
02164 RangeThresholdProcessor():low(0), high(0)
02165 {
02166 }
02167
02168 string get_name() const
02169 {
02170 return NAME;
02171 }
02172 static Processor *NEW()
02173 {
02174 return new RangeThresholdProcessor();
02175 }
02176
02177 void set_params(const Dict & new_params)
02178 {
02179 params = new_params;
02180 low = params.get("low");
02181 high = params.get("high");
02182 }
02183
02184 TypeDict get_param_types() const
02185 {
02186 TypeDict d;
02187 d.put("low", EMObject::FLOAT, "The lower limit of the range that will be set to 1");
02188 d.put("high", EMObject::FLOAT, "The upper limit of the range that will be set to 1");
02189 return d;
02190 }
02191
02192 string get_desc() const
02193 {
02194 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";
02195 }
02196
02197 static const string NAME;
02198
02199 protected:
02200 void process_pixel(float *x) const
02201 {
02202 if (*x >= low && *x <= high) {
02203 *x = 1;
02204 }
02205 else {
02206 *x = 0;
02207 }
02208 }
02209 private:
02210 float low;
02211 float high;
02212
02213 };
02214
02219 class SigmaProcessor:public RealPixelProcessor
02220 {
02221 public:
02222 string get_name() const
02223 {
02224 return NAME;
02225 }
02226 static Processor *NEW()
02227 {
02228 return new SigmaProcessor();
02229 }
02230
02231 void set_params(const Dict & new_params)
02232 {
02233 params = new_params;
02234 value1 = params.get("value1");
02235 value2 = params.get("value2");
02236 }
02237
02238 TypeDict get_param_types() const
02239 {
02240 TypeDict d;
02241 d.put("value1", EMObject::FLOAT, "A number reflecting total standard deviations in the right direction");
02242 d.put("value2", EMObject::FLOAT, "A number reflecting total standard deviations in the left direction");
02243 return d;
02244 }
02245
02246 string get_desc() const
02247 {
02248 return "f(x) = mean if x<(mean-v2*sigma) or x>(mean+v1*sigma); else f(x) = x;";
02249 }
02250
02251 static const string NAME;
02252
02253 protected:
02254 void process_pixel(float *x) const
02255 {
02256 if (*x < (mean - value2 * sigma) || *x > (mean + value1 * sigma))
02257 {
02258 *x = mean;
02259 }
02260 }
02261
02262 private:
02263 float value1;
02264 float value2;
02265 };
02266
02269 class LogProcessor:public RealPixelProcessor
02270 {
02271 public:
02272 string get_name() const
02273 {
02274 return NAME;
02275 }
02276 static Processor *NEW()
02277 {
02278 return new LogProcessor();
02279 }
02280
02281 string get_desc() const
02282 {
02283 return "f(x) = log10(x) if x > 0; else f(x) = 0;";
02284 }
02285
02286 static const string NAME;
02287
02288 protected:
02289 void process_pixel(float *x) const
02290 {
02291 if (*x > 0)
02292 {
02293 *x = log10(*x);
02294 }
02295 else
02296 {
02297 *x = 0;
02298 }
02299 }
02300 };
02301
02304 class CoordinateProcessor:public Processor
02305 {
02306 public:
02307 CoordinateProcessor():nx(0), ny(0), nz(0), mean(0), sigma(0), maxval(0), is_complex(false)
02308 {
02309 }
02310 void process_inplace(EMData * image);
02311
02312 static string get_group_desc()
02313 {
02314 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().";
02315 }
02316
02317 protected:
02318 virtual void process_pixel(float *pixel, int xi, int yi, int zi) const = 0;
02319 virtual void calc_locals(EMData *)
02320 {
02321 }
02322 virtual bool is_valid() const
02323 {
02324 return true;
02325 }
02326
02327 int nx;
02328 int ny;
02329 int nz;
02330 float mean;
02331 float sigma;
02332 float maxval;
02333
02334 bool is_complex;
02335 };
02336
02344 class CircularMaskProcessor:public CoordinateProcessor
02345 {
02346 public:
02347 CircularMaskProcessor():inner_radius(0), outer_radius(0), inner_radius_square(0),
02348 outer_radius_square(0), dx(0), dy(0), dz(0), xc(0), yc(0), zc(0)
02349 {
02350 }
02351
02352 void set_params(const Dict & new_params)
02353 {
02354 params = new_params;
02355
02356 if (params.has_key("inner_radius")) {
02357 inner_radius = params["inner_radius"];
02358 inner_radius_square = inner_radius * inner_radius;
02359 }
02360 else {
02361 inner_radius = -1;
02362 inner_radius_square = -1;
02363 }
02364
02365 if (params.has_key("outer_radius")) {
02366 outer_radius = params["outer_radius"];
02367 outer_radius_square = outer_radius * outer_radius;
02368 }
02369 else {
02370 outer_radius = INT_MAX;
02371 outer_radius_square = INT_MAX;
02372 }
02373
02374 if (params.has_key("xc")) xc = params["xc"];
02375 if (params.has_key("yc")) yc = params["yc"];
02376 if (params.has_key("zc")) zc = params["zc"];
02377 if (params.has_key("dx")) dx = params["dx"];
02378 if (params.has_key("dy")) dy = params["dy"];
02379 if (params.has_key("dz")) dz = params["dz"];
02380 }
02381
02382 string get_desc() const
02383 {
02384 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().";
02385 }
02386
02387 TypeDict get_param_types() const
02388 {
02389 TypeDict d;
02390
02391 d.put("inner_radius", EMObject::INT, "inner mask radius. optional");
02392 d.put("outer_radius", EMObject::INT, "outer mask radius. Negative value -> box radius + outer_radius +1");
02393
02394 d.put("dx", EMObject::FLOAT,
02395 "Modify mask center by dx relative to the default center nx/2");
02396 d.put("dy", EMObject::FLOAT,
02397 "Modify mask center by dy relative to the default center ny/2");
02398 d.put("dz", EMObject::FLOAT,
02399 "Modify mask center by dz relative to the default center nz/2");
02400
02401 return d;
02402 }
02403 protected:
02404 void calc_locals(EMData * image);
02405
02406 bool is_valid() const
02407 {
02408 return (!is_complex);
02409 }
02410
02411 void process_pixel(float *pixel, int xi, int yi, int zi) const
02412 {
02413 float dist = (xi - xc) * (xi - xc) + (yi - yc) * (yi - yc) + (zi - zc) * (zi - zc);
02414 process_dist_pixel(pixel, dist);
02415 }
02416
02417 virtual void process_dist_pixel(float *pixel, float dist) const = 0;
02418
02419 int inner_radius;
02420 int outer_radius;
02421 int inner_radius_square;
02422 int outer_radius_square;
02423 float dx, dy, dz;
02424 float xc, yc, zc;
02425 };
02426
02430 class MaskSharpProcessor:public CircularMaskProcessor
02431 {
02432 public:
02433 MaskSharpProcessor():value(0)
02434 {
02435 }
02436
02437 string get_name() const
02438 {
02439 return NAME;
02440 }
02441 static Processor *NEW()
02442 {
02443 return new MaskSharpProcessor();
02444 }
02445
02446 void set_params(const Dict & new_params)
02447 {
02448 CircularMaskProcessor::set_params(new_params);
02449 value = params.set_default("value",0.0f);
02450 }
02451
02452 TypeDict get_param_types() const
02453 {
02454 TypeDict d = CircularMaskProcessor::get_param_types();
02455 d.put("value", EMObject::FLOAT, "step cutoff to this value. Default is 0.");
02456 return d;
02457 }
02458
02459 string get_desc() const
02460 {
02461 return "step cutoff to a user-given value in both inner and outer circles.";
02462 }
02463
02464 static const string NAME;
02465
02466 protected:
02467 void process_dist_pixel(float *pixel, float dist) const
02468 {
02469 if (dist >= outer_radius_square || dist < inner_radius_square)
02470 {
02471 *pixel = value;
02472 }
02473 }
02474
02475 float value;
02476 };
02477
02478
02482 class MaskEdgeMeanProcessor:public CircularMaskProcessor
02483 {
02484 public:
02485 string get_name() const
02486 {
02487 return NAME;
02488 }
02489 static Processor *NEW()
02490 {
02491 return new MaskEdgeMeanProcessor();
02492 }
02493
02494 void set_params(const Dict & new_params)
02495 {
02496 CircularMaskProcessor::set_params(new_params);
02497 ring_width = params["ring_width"];
02498 if (ring_width == 0) {
02499 ring_width = 1;
02500 }
02501 }
02502
02503 TypeDict get_param_types() const
02504 {
02505 TypeDict d = CircularMaskProcessor::get_param_types();
02506 d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02507 return d;
02508 }
02509
02510 string get_desc() const
02511 {
02512 return "A step cutoff to the the mean value in a ring centered on the outer radius";
02513 }
02514
02515 static const string NAME;
02516
02517 protected:
02518 void calc_locals(EMData * image);
02519
02520
02521 void process_dist_pixel(float *pixel, float dist) const
02522 {
02523 if (dist >= outer_radius_square || dist < inner_radius_square){
02524 *pixel = ring_avg;
02525 }
02526 }
02527
02528 private:
02529 int ring_width;
02530 float ring_avg;
02531 };
02532
02535 class MaskNoiseProcessor:public CircularMaskProcessor
02536 {
02537 public:
02538 string get_name() const
02539 {
02540 return NAME;
02541 }
02542 static Processor *NEW()
02543 {
02544 return new MaskNoiseProcessor();
02545 }
02546
02547 string get_desc() const
02548 {
02549 return "fills masked region";
02550 }
02551
02552 static const string NAME;
02553
02554 protected:
02555 void process_dist_pixel(float *pixel, float dist) const
02556 {
02557 if (dist >= outer_radius_square || dist < inner_radius_square)
02558 {
02559 *pixel = Util::get_gauss_rand(mean, sigma);
02560 }
02561 }
02562 };
02563
02566 class MaskGaussProcessor:public CircularMaskProcessor
02567 {
02568 public:
02569 string get_name() const
02570 {
02571 return NAME;
02572 }
02573 static Processor *NEW()
02574 {
02575 return new MaskGaussProcessor();
02576 }
02577
02578 void set_params(const Dict & new_params)
02579 {
02580 CircularMaskProcessor::set_params(new_params);
02581 exponent = params["exponent"];
02582 if (exponent <= 0.0) {
02583 exponent = 2.0;
02584 }
02585 }
02586
02587 TypeDict get_param_types() const
02588 {
02589 TypeDict d = CircularMaskProcessor::get_param_types();
02590 d.put("exponent", EMObject::FLOAT, "The exponent, f in e^-Bs^f. default 2.0, producing a Gaussian");
02591 return d;
02592 }
02593
02594 string get_desc() const
02595 {
02596 return "a gaussian falloff to zero, radius is the 1/e of the width. If inner_radius>0, then \
02597 outer radius specifies width of Gaussian starting at inner_radius rather than total radius.";
02598 }
02599
02600 static const string NAME;
02601
02602 protected:
02603 float exponent;
02604 void process_dist_pixel(float *pixel, float dist) const
02605 {
02606 if (inner_radius_square>0) {
02607 if (dist>inner_radius_square) {
02608 if (exponent==2.0f) (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,2.0f) / outer_radius_square);
02609 else (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,exponent) / pow((float)outer_radius_square,exponent/2.0f));
02610 }
02611 }
02612 else {
02613 if (exponent==2.0f) (*pixel) *= exp(-dist / outer_radius_square);
02614 else (*pixel) *= exp(-pow(dist,exponent/2.0f) / pow((float)outer_radius_square,exponent/2.0f));
02615 }
02616 }
02617 };
02618
02625 class MaskGaussNonuniformProcessor:public CoordinateProcessor
02626 {
02627 public:
02628 MaskGaussNonuniformProcessor():radius_x(0), radius_y(0), radius_z(0), gauss_width(0)
02629 {
02630 }
02631
02632 void set_params(const Dict & new_params)
02633 {
02634 params = new_params;
02635
02636 if (params.has_key("radius_x")) radius_x=params["radius_x"];
02637 else radius_x=5.0;
02638
02639 if (params.has_key("radius_y")) radius_y=params["radius_y"];
02640 else radius_y=5.0;
02641
02642 if (params.has_key("radius_z")) radius_z=params["radius_z"];
02643 else radius_z=5.0;
02644
02645 if (params.has_key("gauss_width")) gauss_width=params["gauss_width"];
02646 else gauss_width=0.05f;
02647 }
02648
02649 TypeDict get_param_types() const
02650 {
02651 TypeDict d;
02652
02653 d.put("radius_x", EMObject::INT, "x-axis radius");
02654 d.put("radius_y", EMObject::INT, "y-axis radius");
02655 d.put("radius_z", EMObject::INT, "z-axis radius");
02656 d.put("gauss_width", EMObject::FLOAT, "Gaussian falloff width, relative to each radius, default 0.05");
02657
02658 return d;
02659 }
02660
02661 string get_name() const
02662 {
02663 return NAME;
02664 }
02665 static Processor *NEW()
02666 {
02667 return new MaskGaussNonuniformProcessor();
02668 }
02669
02670 string get_desc() const
02671 {
02672 return "A Gaussian falloff to zero. Nonisotropic, specify inner radius for x,y,z and Gaussian falloff width. Falloff \
02673 width is also nonisotropic and relative to the radii, with 1 being equal to the radius on that axis.";
02674 }
02675
02676 static const string NAME;
02677
02678 protected:
02679 void process_pixel(float *pixel, int xi, int yi, int zi) const
02680 {
02681 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);
02682 if (dist>1.0) (*pixel)*=exp(-pow((sqrt(dist)-1.0f)/gauss_width,2.0f));
02683 }
02684
02685 float radius_x,radius_y,radius_z,gauss_width;
02686 };
02687
02692 class MaskGaussInvProcessor:public CircularMaskProcessor
02693 {
02694 public:
02695 TypeDict get_param_types() const
02696 {
02697 TypeDict d = CircularMaskProcessor::get_param_types();
02698 d.put("gauss_width", EMObject::FLOAT, "Used to calculate the constant factor - gauss_width / (ny*ny)" );
02699 d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02700 return d;
02701 }
02702
02703 string get_name() const
02704 {
02705 return NAME;
02706 }
02707
02708 static Processor *NEW()
02709 {
02710 return new MaskGaussInvProcessor();
02711 }
02712
02713 string get_desc() const
02714 {
02715 return "f(x) = f(x) / exp(-radius*radius * gauss_width / (ny*ny))";
02716 }
02717
02718 static const string NAME;
02719
02720 protected:
02721 void calc_locals(EMData *)
02722 {
02723 float gauss_width = params["gauss_width"];
02724 slice_value = gauss_width / (ny * ny);
02725 }
02726
02727 void process_dist_pixel(float *pixel, float dist) const
02728 {
02729 (*pixel) /= exp(-dist * slice_value);
02730 }
02731 private:
02732 float slice_value;
02733 };
02734
02735
02740 class LinearPyramidProcessor:public Processor
02741 {
02742 public:
02743 string get_name() const
02744 {
02745 return NAME;
02746 }
02747
02748 void process_inplace(EMData *image);
02749
02750 static Processor *NEW()
02751 {
02752 return new LinearPyramidProcessor();
02753 }
02754
02755 string get_desc() const
02756 {
02757 return "Multiplies image by a 'linear pyramid', 1-(|x-xsize/2|*|y-ysize/2|*4/(xsize*ysize))";
02758 }
02759
02760 static const string NAME;
02761 };
02762
02763
02766 class MakeRadiusSquaredProcessor:public CircularMaskProcessor
02767 {
02768 public:
02769 string get_name() const
02770 {
02771 return NAME;
02772 }
02773 static Processor *NEW()
02774 {
02775 return new MakeRadiusSquaredProcessor();
02776 }
02777
02778 string get_desc() const
02779 {
02780 return "overwrites input, f(x) = radius * radius";
02781 }
02782
02783 static const string NAME;
02784
02785 protected:
02786 void process_dist_pixel(float *pixel, float dist) const
02787 {
02788 *pixel = dist;
02789 }
02790 };
02791
02794 class MakeRadiusProcessor:public CircularMaskProcessor
02795 {
02796 public:
02797 string get_name() const
02798 {
02799 return NAME;
02800 }
02801 static Processor *NEW()
02802 {
02803 return new MakeRadiusProcessor();
02804 }
02805
02806 string get_desc() const
02807 {
02808 return "overwrites input, f(x) = radius;";
02809 }
02810
02811 static const string NAME;
02812
02813 protected:
02814 void process_dist_pixel(float *pixel, float dist) const
02815 {
02816 *pixel = sqrt(dist);
02817 }
02818 };
02819
02822 class ComplexPixelProcessor:public Processor
02823 {
02824 public:
02825 void process_inplace(EMData * image);
02826
02827 static string get_group_desc()
02828 {
02829 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.";
02830 }
02831
02832 protected:
02833 virtual void process_pixel(float *x) const = 0;
02834 };
02835
02838 class ComplexNormPixel:public ComplexPixelProcessor
02839 {
02840 public:
02841 string get_name() const
02842 {
02843 return NAME;
02844 }
02845 static Processor *NEW()
02846 {
02847 return new ComplexNormPixel();
02848 }
02849
02850 string get_desc() const
02851 {
02852 return "Each Fourier pixel will be normalized. ie - amp=1, phase=unmodified. Useful for performing phase-residual-like computations with dot products.";
02853 }
02854
02855 static const string NAME;
02856
02857 protected:
02858 void process_pixel(float *x) const
02859 {
02860 *x=1.0;
02861 }
02862 };
02863
02867 class AreaProcessor:public Processor
02868 {
02869 public:
02870 AreaProcessor():areasize(0), kernel(0), nx(0), ny(0), nz(0)
02871 {
02872 }
02873
02874 void process_inplace(EMData * image);
02875
02876 void set_params(const Dict & new_params)
02877 {
02878 params = new_params;
02879 areasize = params["areasize"];
02880 }
02881
02882 TypeDict get_param_types() const
02883 {
02884 TypeDict d;
02885 d.put("areasize", EMObject::INT, "The width of the area to process (not radius)");
02886 return d;
02887 }
02888
02889 string get_desc() const
02890 {
02891 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().";
02892 }
02893
02894 protected:
02895 virtual void process_pixel(float *pixel, float, float, float, float *area_matrix) const
02896 {
02897 for (int i = 0; i < matrix_size; i++)
02898 {
02899 *pixel += area_matrix[i] * kernel[i];
02900 }
02901 }
02902
02903 virtual void create_kernel() const = 0;
02904
02905 int areasize;
02906 int matrix_size;
02907 float *kernel;
02908 int nx;
02909 int ny;
02910 int nz;
02911 };
02912
02915 class LaplacianProcessor:public AreaProcessor
02916 {
02917 public:
02918 string get_name() const
02919 {
02920 return NAME;
02921 }
02922 static Processor *NEW()
02923 {
02924 return new LaplacianProcessor();
02925 }
02926
02927 string get_desc() const
02928 {
02929 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).";
02930 }
02931
02932 static const string NAME;
02933
02934 protected:
02935 void create_kernel() const;
02936
02937 };
02938
02941 class ZeroConstantProcessor:public AreaProcessor
02942 {
02943 public:
02944 string get_name() const
02945 {
02946 return NAME;
02947 }
02948 static Processor *NEW()
02949 {
02950 return new ZeroConstantProcessor();
02951 }
02952
02953 string get_desc() const
02954 {
02955 return "Contraction of data, if any nearest neighbor is 0, value -> 0, generally used iteratively";
02956 }
02957
02958 static const string NAME;
02959
02960 protected:
02961 void process_pixel(float *pixel, float, float, float, float *matrix) const
02962 {
02963 if (*pixel != 0)
02964 {
02965 if (*pixel == matrix[1] || *pixel == matrix[3] || *pixel == matrix[5] ||
02966 *pixel == matrix[7] || matrix[1] == 0 || matrix[3] == 0 ||
02967 matrix[5] == 0 || matrix[7] == 0) {
02968 *pixel = 0;
02969 }
02970 }
02971 }
02972
02973 void create_kernel() const
02974 {
02975 }
02976 };
02977
02986 class BoxStatProcessor:public Processor
02987 {
02988 public:
02989 void process_inplace(EMData * image);
02990
02991 static string get_group_desc()
02992 {
02993 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).";
02994 }
02995
02996 TypeDict get_param_types() const
02997 {
02998 TypeDict d;
02999 d.put("radius", EMObject::INT, "The radius of the search box, default is 1 which results in a 3x3 box (3 = 2xradius + 1)");
03000 return d;
03001 }
03002
03003 protected:
03004 virtual void process_pixel(float *pixel, const float *array, int n) const = 0;
03005 };
03006
03007
03010 class BoxMedianProcessor:public BoxStatProcessor
03011 {
03012 public:
03013 string get_name() const
03014 {
03015 return NAME;
03016 }
03017 static Processor *NEW()
03018 {
03019 return new BoxMedianProcessor();
03020 }
03021
03022 string get_desc() const
03023 {
03024 return "A processor for noise reduction. pixel = median of values surrounding pixel.";
03025 }
03026
03027 static const string NAME;
03028
03029 protected:
03030 void process_pixel(float *pixel, const float *array, int n) const
03031 {
03032 float *data = new float[n];
03033 memcpy(data, array, sizeof(float) * n);
03034
03035 for (int i = 0; i <= n / 2; i++)
03036 {
03037 for (int j = i + 1; j < n; j++)
03038 {
03039 if (data[i] < data[j]) {
03040 float t = data[i];
03041 data[i] = data[j];
03042 data[j] = t;
03043 }
03044 }
03045 }
03046
03047 if (n % 2 != 0)
03048 {
03049 *pixel = data[n / 2];
03050 }
03051 else {
03052 *pixel = (data[n / 2] + data[n / 2 - 1]) / 2;
03053 }
03054 if( data )
03055 {
03056 delete[]data;
03057 data = 0;
03058 }
03059 }
03060 };
03061
03064 class BoxSigmaProcessor:public BoxStatProcessor
03065 {
03066 public:
03067 string get_name() const
03068 {
03069 return NAME;
03070 }
03071 static Processor *NEW()
03072 {
03073 return new BoxSigmaProcessor();
03074 }
03075
03076 string get_desc() const
03077 {
03078 return "pixel = standard deviation of values surrounding pixel.";
03079 }
03080
03081 static const string NAME;
03082
03083 protected:
03084 void process_pixel(float *pixel, const float *data, int n) const
03085 {
03086 float sum = 0;
03087 float square_sum = 0;
03088 for (int i = 0; i < n; i++)
03089 {
03090 sum += data[i];
03091 square_sum += data[i] * data[i];
03092 }
03093
03094 float mean = sum / n;
03095 *pixel = sqrt(square_sum / n - mean * mean);
03096 }
03097 };
03098
03101 class BoxMaxProcessor:public BoxStatProcessor
03102 {
03103 public:
03104 string get_name() const
03105 {
03106 return NAME;
03107 }
03108 static Processor *NEW()
03109 {
03110 return new BoxMaxProcessor();
03111 }
03112
03113 string get_desc() const
03114 {
03115 return "peak processor: pixel = max of values surrounding pixel.";
03116 }
03117
03118 static const string NAME;
03119
03120 protected:
03121 void process_pixel(float *pixel, const float *data, int n) const
03122 {
03123 float maxval = -FLT_MAX;
03124 for (int i = 0; i < n; i++)
03125 {
03126 if (data[i] > maxval) {
03127 maxval = data[i];
03128 }
03129 }
03130 *pixel = maxval;
03131 }
03132 };
03133
03136 class MinusPeakProcessor:public BoxStatProcessor
03137 {
03138 public:
03139 string get_name() const
03140 {
03141 return NAME;
03142 }
03143 static Processor *NEW()
03144 {
03145 return new MinusPeakProcessor();
03146 }
03147
03148 string get_desc() const
03149 {
03150 return "peak processor: pixel = pixel - max of values surrounding pixel. This is a sort of positive peak-finding algorithm.";
03151 }
03152
03153 static const string NAME;
03154
03155 protected:
03156 void process_pixel(float *pixel, const float *data, int n) const
03157 {
03158 float maxval = -FLT_MAX;
03159 for (int i = 0; i < n; i++)
03160 {
03161 if (data[i] > maxval) {
03162 maxval = data[i];
03163 }
03164 }
03165 *pixel -= maxval;
03166 }
03167 };
03168
03172 class PeakOnlyProcessor:public BoxStatProcessor
03173 {
03174 public:
03175 string get_name() const
03176 {
03177 return NAME;
03178 }
03179 static Processor *NEW()
03180 {
03181 return new PeakOnlyProcessor();
03182 }
03183 void set_params(const Dict & new_params)
03184 {
03185 params = new_params;
03186 npeaks = params["npeaks"];
03187 if (npeaks == 0) {
03188 npeaks = 1;
03189 }
03190 }
03191
03192 TypeDict get_param_types() const
03193 {
03194 TypeDict d;
03195 d.put("npeaks", EMObject::INT, "the number of surrounding peaks allow to >= pixel values");
03196 return d;
03197 }
03198
03199 string get_desc() const
03200 {
03201 return "peak processor -> if npeaks or more surrounding values >= value, value->0";
03202 }
03203
03204 static const string NAME;
03205
03206 protected:
03207 void process_pixel(float *pixel, const float *data, int n) const
03208 {
03209 int r = 0;
03210
03211 for (int i = 0; i < n; i++)
03212 {
03213 if (data[i] >= *pixel) {
03214 r++;
03215 }
03216 }
03217
03218 if (r > npeaks)
03219 {
03220 *pixel = 0;
03221 }
03222 }
03223 private:
03224 int npeaks;
03225 };
03226
03231 class DiffBlockProcessor:public Processor
03232 {
03233 public:
03234 void process_inplace(EMData * image);
03235
03236 string get_name() const
03237 {
03238 return NAME;
03239 }
03240 static Processor *NEW()
03241 {
03242 return new DiffBlockProcessor();
03243 }
03244
03245 string get_desc() const
03246 {
03247 return "averages over cal_half_width, then sets the value in a local block";
03248 }
03249
03250 TypeDict get_param_types() const
03251 {
03252 TypeDict d;
03253 d.put("cal_half_width", EMObject::FLOAT, "cal_half_width is dx/dy for calculating an average");
03254 d.put("fill_half_width", EMObject::FLOAT, "fill_half_width is dx/dy for fill/step");
03255 return d;
03256 }
03257
03258 static const string NAME;
03259 };
03260
03265 class CutoffBlockProcessor:public Processor
03266 {
03267 public:
03268 void process_inplace(EMData * image);
03269
03270 string get_name() const
03271 {
03272 return NAME;
03273 }
03274 static Processor *NEW()
03275 {
03276 return new CutoffBlockProcessor();
03277 }
03278
03279 TypeDict get_param_types() const
03280 {
03281 TypeDict d;
03282 d.put("value1", EMObject::FLOAT, "val1 is dx/dy");
03283 d.put("value2", EMObject::FLOAT, "val2 is lowpass freq cutoff in pixels");
03284 return d;
03285 }
03286
03287 string get_desc() const
03288 {
03289 return "Block processor, val1 is dx/dy, val2 is lp freq cutoff in pixels. Mystery processor.";
03290 }
03291
03292 static const string NAME;
03293 };
03294
03300 class BooleanShrinkProcessor
03301 {
03302 protected:
03310 template<class LogicOp>
03311 EMData* process(const EMData *const image, Dict& params);
03312
03319 template<class LogicOp>
03320 void process_inplace(EMData * image, Dict& params);
03321
03322 };
03323
03332 class MaxShrinkProcessor:public BooleanShrinkProcessor, public Processor
03333 {
03334 public:
03341 virtual EMData* process(const EMData *const image)
03342 {
03343 return BooleanShrinkProcessor::process<GreaterThan>(image, params);
03344 }
03345
03346
03347 virtual void process_inplace(EMData * image)
03348 {
03349 BooleanShrinkProcessor::process_inplace<GreaterThan>(image, params);
03350 }
03351
03352 string get_desc() const
03353 {
03354 return "Shrink an image by a given amount (default 2), using the maximum value found in the pixel neighborhood.";
03355 }
03356
03357 string get_name() const
03358 {
03359 return NAME;
03360 }
03361 static Processor *NEW()
03362 {
03363 return new MaxShrinkProcessor();
03364 }
03365
03366 TypeDict get_param_types() const
03367 {
03368 TypeDict d;
03369 d.put("n", EMObject::INT, "The shrink factor");
03370 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03371 return d;
03372 }
03373
03374 static const string NAME;
03375
03376 private:
03377 struct GreaterThan
03378 {
03379 inline bool operator()(float left,float right) const { return left > right; }
03380 inline float get_start_val() { return -10000000; }
03381 };
03382 };
03383
03392 class MinShrinkProcessor:public BooleanShrinkProcessor, public Processor
03393 {
03394 public:
03401 virtual EMData* process(const EMData *const image)
03402 {
03403 return BooleanShrinkProcessor::process<LessThan>(image, params);
03404 }
03405
03406
03407 virtual void process_inplace(EMData * image)
03408 {
03409 BooleanShrinkProcessor::process_inplace<LessThan>(image, params);
03410 }
03411 string get_desc() const
03412 {
03413 return "Shrink an image by a given amount (default 2), using the minimum value found in the pixel neighborhood.";
03414 }
03415
03416 string get_name() const
03417 {
03418 return NAME;
03419 }
03420 static Processor *NEW()
03421 {
03422 return new MinShrinkProcessor();
03423 }
03424
03425 TypeDict get_param_types() const
03426 {
03427 TypeDict d;
03428 d.put("n", EMObject::INT, "The shrink factor");
03429 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03430 return d;
03431 }
03432
03433 static const string NAME;
03434
03435 private:
03436 struct LessThan
03437 {
03438 inline bool operator()(float left,float right) const { return left < right; }
03439 inline float get_start_val() { return 9999999999.0f; }
03440 };
03441 };
03442
03449 class MeanShrinkProcessor : public Processor
03450 {
03451 public:
03462 virtual EMData* process(const EMData *const image);
03463
03470 virtual void process_inplace(EMData * image);
03471
03472 string get_desc() const
03473 {
03474 return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
03475 }
03476
03477 virtual string get_name() const
03478 {
03479 return NAME;
03480 }
03481 static Processor *NEW()
03482 {
03483 return new MeanShrinkProcessor();
03484 }
03485
03486 virtual TypeDict get_param_types() const
03487 {
03488 TypeDict d;
03489 d.put("n", EMObject::FLOAT, "The shrink factor");
03490 return d;
03491 }
03492
03493 static const string NAME;
03494
03495 private:
03503 void accrue_mean(EMData* to, const EMData *const from, const int shrinkfactor);
03504
03511 void accrue_mean_one_p_five(EMData* to, const EMData * const from);
03512 };
03513
03514
03521 class MedianShrinkProcessor : public Processor
03522 {
03523 public:
03534 virtual EMData* process(const EMData *const image);
03535
03542 virtual void process_inplace(EMData * image);
03543
03544 string get_desc() const
03545 {
03546 return "Shrink an image by a given amount , using the median value found in the pixel neighborhood.";
03547 }
03548
03549 virtual string get_name() const
03550 {
03551 return NAME;
03552 }
03553 static Processor *NEW()
03554 {
03555 return new MedianShrinkProcessor();
03556 }
03557
03558 virtual TypeDict get_param_types() const
03559 {
03560 TypeDict d;
03561 d.put("n", EMObject::INT, "The shrink factor");
03562 return d;
03563 }
03564
03565 static const string NAME;
03566
03567 private:
03575 void accrue_median(EMData* to, const EMData* const from,const int shrink_factor);
03576 };
03577
03578
03587 class FFTResampleProcessor : public Processor
03588 {
03589 public:
03590 virtual EMData* process(const EMData *const image);
03591
03592 virtual void process_inplace(EMData * image);
03593
03594 string get_desc() const
03595 {
03596 return "Robust resampling of an image by clipping its Fourier transform.";
03597 }
03598
03599 string get_name() const
03600 {
03601 return NAME;
03602 }
03603 static Processor *NEW()
03604 {
03605 return new FFTResampleProcessor();
03606 }
03607
03608 TypeDict get_param_types() const
03609 {
03610 TypeDict d;
03611 d.put("n", EMObject::FLOAT, "The sample rate. Less than one enlarges the image, greater than one shrinks it.");
03612 return d;
03613 }
03614
03615 static const string NAME;
03616
03617 private:
03624 void fft_resample(EMData* to, const EMData *const from, const float& sample_rate);
03625
03626 };
03627
03630 class GradientRemoverProcessor:public Processor
03631 {
03632 public:
03633 void process_inplace(EMData * image);
03634
03635 string get_name() const
03636 {
03637 return NAME;
03638 }
03639 static Processor *NEW()
03640 {
03641 return new GradientRemoverProcessor();
03642 }
03643
03644 string get_desc() const
03645 {
03646 return "Gradient remover, does a rough plane fit to find linear gradients.";
03647 }
03648
03649 static const string NAME;
03650 };
03651
03660 class GradientPlaneRemoverProcessor:public Processor
03661 {
03662 public:
03663 void process_inplace(EMData * image);
03664
03665 string get_name() const
03666 {
03667 return NAME;
03668 }
03669 static Processor *NEW()
03670 {
03671 return new GradientPlaneRemoverProcessor();
03672 }
03673
03674 string get_desc() const
03675 {
03676 return "Remove gradient by least square plane fit";
03677 }
03678
03679 TypeDict get_param_types() const
03680 {
03681 TypeDict d;
03682 d.put("mask", EMObject::EMDATA, "mask object: nonzero pixel positions will be used to fit plane. default = 0");
03683 d.put("changeZero", EMObject::INT, "if zero pixels are modified when removing gradient. default = 0");
03684 d.put("planeParam", EMObject::FLOATARRAY, "fitted plane parameters output");
03685 return d;
03686 }
03687
03688 static const string NAME;
03689 };
03690
03696 class NonConvexProcessor:public Processor
03697 {
03698 public:
03699 void process_inplace(EMData * image);
03700
03701 string get_name() const
03702 {
03703 return NAME;
03704 }
03705 static Processor *NEW()
03706 {
03707 return new NonConvexProcessor();
03708 }
03709
03710 string get_desc() const
03711 {
03712 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).";
03713 }
03714
03715 TypeDict get_param_types() const
03716 {
03717 TypeDict d;
03718
03719
03720
03721 return d;
03722 }
03723
03724 static const string NAME;
03725 };
03726
03733 class FlattenBackgroundProcessor:public Processor
03734 {
03735 public:
03736 void process_inplace(EMData * image);
03737
03738 string get_name() const
03739 {
03740 return NAME;
03741 }
03742
03743 static Processor *NEW()
03744 {
03745 return new FlattenBackgroundProcessor();
03746 }
03747
03748 string get_desc() const
03749 {
03750 return "Flattens the background by subtracting the local mean";
03751 }
03752
03753 TypeDict get_param_types() const
03754 {
03755 TypeDict d;
03756 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");
03757 d.put("radius", EMObject::INT, "The radius of circle/sphere that defines the local neighborhood. Exclusive of the mask argument");
03758 return d;
03759 }
03760
03761 static const string NAME;
03762 };
03763
03764
03767 class RampProcessor:public Processor
03768 {
03769 public:
03770 void process_inplace(EMData * image);
03771
03772 string get_name() const
03773 {
03774 return NAME;
03775 }
03776 static Processor *NEW()
03777 {
03778 return new RampProcessor();
03779 }
03780
03781 string get_desc() const
03782 {
03783 return "Ramp processor -- Fits a least-squares plane "
03784 "to the picture, and subtracts the plane from "
03785 "the picture. A wedge-shaped overall density "
03786 "profile can thus be removed from the picture.";
03787 }
03788
03789 static const string NAME;
03790 };
03791
03794 class VerticalStripeProcessor:public Processor
03795 {
03796 public:
03797 void process_inplace(EMData * image);
03798
03799 string get_name() const
03800 {
03801 return NAME;
03802 }
03803
03804 static Processor *NEW()
03805 {
03806 return new VerticalStripeProcessor();
03807 }
03808
03809 string get_desc() const
03810 {
03811 return "Tries to fix images scanned on the zeiss for poor ccd normalization.";
03812 }
03813
03814 static const string NAME;
03815 };
03816
03819 class RealToFFTProcessor:public Processor
03820 {
03821 public:
03822 void process_inplace(EMData *image);
03823
03824 string get_name() const
03825 {
03826 return NAME;
03827 }
03828
03829 static Processor *NEW()
03830 {
03831 return new RealToFFTProcessor();
03832 }
03833
03834 string get_desc() const
03835 {
03836 return "This will replace the image with a full-circle 2D fft amplitude rendering. Note that this renders amplitude, when intensity is more common.";
03837 }
03838
03839 static const string NAME;
03840 };
03841
03842
03845 class SigmaZeroEdgeProcessor:public Processor
03846 {
03847 public:
03848 void process_inplace(EMData * image);
03849
03850 string get_name() const
03851 {
03852 return NAME;
03853 }
03854 static Processor *NEW()
03855 {
03856 return new SigmaZeroEdgeProcessor();
03857 }
03858
03859 string get_desc() const
03860 {
03861 return "Fill zeroes at edges with nearest horizontal/vertical value.";
03862 }
03863
03864 static const string NAME;
03865 };
03866
03872 class BeamstopProcessor:public Processor
03873 {
03874 public:
03875 void process_inplace(EMData * image);
03876
03877 string get_name() const
03878 {
03879 return NAME;
03880 }
03881
03882 static Processor *NEW()
03883 {
03884 return new BeamstopProcessor();
03885 }
03886
03887 string get_desc() const
03888 {
03889 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.";
03890 }
03891
03892 TypeDict get_param_types() const
03893 {
03894 TypeDict d;
03895 d.put("value1", EMObject::FLOAT, "sig multiplier");
03896 d.put("value2", EMObject::FLOAT, "x of center");
03897 d.put("value3", EMObject::FLOAT, "y of center");
03898 return d;
03899 }
03900
03901 static const string NAME;
03902 };
03903
03906 class MeanZeroEdgeProcessor:public Processor
03907 {
03908 public:
03909 void process_inplace(EMData * image);
03910
03911 string get_name() const
03912 {
03913 return NAME;
03914 }
03915
03916 static Processor *NEW()
03917 {
03918 return new MeanZeroEdgeProcessor();
03919 }
03920
03921 string get_desc() const
03922 {
03923 return "Fill zeroes at edges with nearest horizontal/vertical value damped towards Mean2.";
03924 }
03925
03926 static const string NAME;
03927 };
03928
03929
03932 class AverageXProcessor:public Processor
03933 {
03934 public:
03935 void process_inplace(EMData * image);
03936
03937 string get_name() const
03938 {
03939 return NAME;
03940 }
03941
03942 static Processor *NEW()
03943 {
03944 return new AverageXProcessor();
03945 }
03946
03947 string get_desc() const
03948 {
03949 return "Average along Y and replace with average";
03950 }
03951
03952 static const string NAME;
03953 };
03954
03958 class DecayEdgeProcessor:public Processor
03959 {
03960 public:
03961 void process_inplace(EMData * image);
03962 string get_name() const
03963 {
03964 return NAME;
03965 }
03966
03967 static Processor *NEW()
03968 {
03969 return new DecayEdgeProcessor();
03970 }
03971
03972 string get_desc() const
03973 {
03974 return "Decay edges of image to zero";
03975 }
03976
03977 TypeDict get_param_types() const
03978 {
03979 TypeDict d;
03980 d.put("width", EMObject::INT, "Width of the decay region around the edge of the image in pixels");
03981 return d;
03982 }
03983
03984 static const string NAME;
03985 };
03986
03993 class ZeroEdgeRowProcessor:public Processor
03994 {
03995 public:
03996 void process_inplace(EMData * image);
03997 string get_name() const
03998 {
03999 return NAME;
04000 }
04001
04002 static Processor *NEW()
04003 {
04004 return new ZeroEdgeRowProcessor();
04005 }
04006
04007 string get_desc() const
04008 {
04009 return "zero edges of image on top and bottom, and on left and right.";
04010 }
04011
04012 TypeDict get_param_types() const
04013 {
04014 TypeDict d;
04015 d.put("x0", EMObject::INT, "The number of columns to zero from left");
04016 d.put("x1", EMObject::INT, "The number of columns to zero from right");
04017 d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
04018 d.put("y1", EMObject::INT, "The number of rows to zero from the top");
04019 return d;
04020 }
04021
04022 static const string NAME;
04023 };
04024
04033 class ZeroEdgePlaneProcessor:public Processor
04034 {
04035 public:
04036 void process_inplace(EMData * image);
04037 string get_name() const
04038 {
04039 return NAME;
04040 }
04041
04042 static Processor *NEW()
04043 {
04044 return new ZeroEdgePlaneProcessor();
04045 }
04046
04047 string get_desc() const
04048 {
04049 return "zero edges of volume on all sides";
04050 }
04051
04052 TypeDict get_param_types() const
04053 {
04054 TypeDict d;
04055 d.put("x0", EMObject::INT, "The number of columns to zero from left");
04056 d.put("x1", EMObject::INT, "The number of columns to zero from right");
04057 d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
04058 d.put("y1", EMObject::INT, "The number of rows to zero from the top");
04059 d.put("z0", EMObject::INT, "The number of slices to zero from the bottom");
04060 d.put("z1", EMObject::INT, "The number of slices to zero from the top");
04061 return d;
04062 }
04063
04064 static const string NAME;
04065 };
04066
04067
04074 class BilateralProcessor:public Processor
04075 {
04076 public:
04077 void process_inplace(EMData * image);
04078 string get_name() const
04079 {
04080 return NAME;
04081 }
04082
04083 string get_desc() const
04084 {
04085 return "Bilateral processing on 2D or 3D volume data. Bilateral processing does non-linear weighted averaging processing within a certain window. ";
04086 }
04087
04088 static Processor *NEW()
04089 {
04090 return new BilateralProcessor();
04091 }
04092
04093 TypeDict get_param_types() const
04094 {
04095 TypeDict d;
04096 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.");
04097 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.");
04098 d.put("niter", EMObject::INT, "how many times to apply this processing on your data.");
04099 d.put("half_width", EMObject::INT, "processing window size = (2 * half_widthh + 1) ^ 3.");
04100 return d;
04101 }
04102
04103 static const string NAME;
04104 };
04105
04108 class NormalizeProcessor:public Processor
04109 {
04110 public:
04111 void process_inplace(EMData * image);
04112
04113 static string get_group_desc()
04114 {
04115 return "Base class for normalization processors. Each specific normalization processor needs to define how to calculate mean and how to calculate sigma.";
04116 }
04117
04118 protected:
04119 virtual float calc_sigma(EMData * image) const;
04120 virtual float calc_mean(EMData * image) const = 0;
04121 };
04122
04125 class NormalizeUnitProcessor:public NormalizeProcessor
04126 {
04127 public:
04128 string get_name() const
04129 {
04130 return NAME;
04131 }
04132
04133 static Processor *NEW()
04134 {
04135 return new NormalizeUnitProcessor();
04136 }
04137
04138 string get_desc() const
04139 {
04140 return "Normalize an image so its vector length is 1.0.";
04141 }
04142
04143 static const string NAME;
04144
04145 protected:
04146 float calc_sigma(EMData * image) const;
04147 float calc_mean(EMData * image) const;
04148 };
04149
04150 inline float NormalizeUnitProcessor::calc_mean(EMData *) const { return 0; }
04151
04154 class NormalizeUnitSumProcessor:public NormalizeProcessor
04155 {
04156 public:
04157 string get_name() const
04158 {
04159 return NAME;
04160 }
04161
04162 static Processor *NEW()
04163 {
04164 return new NormalizeUnitSumProcessor();
04165 }
04166
04167 string get_desc() const
04168 {
04169 return "Normalize an image so its elements sum to 1.0 (fails if mean=0)";
04170 }
04171
04172 static const string NAME;
04173
04174 protected:
04175 float calc_sigma(EMData * image) const;
04176 float calc_mean(EMData * image) const;
04177 };
04178
04179 inline float NormalizeUnitSumProcessor::calc_mean(EMData *) const { return 0; }
04180
04181
04184 class NormalizeStdProcessor:public NormalizeProcessor
04185 {
04186 public:
04187 string get_name() const
04188 {
04189 return NAME;
04190 }
04191
04192 static Processor *NEW()
04193 {
04194 return new NormalizeStdProcessor();
04195 }
04196
04197 string get_desc() const
04198 {
04199 return "do a standard normalization on an image.";
04200 }
04201
04202 static const string NAME;
04203
04204 protected:
04205 float calc_mean(EMData * image) const;
04206 };
04207
04212 class NormalizeMaskProcessor:public NormalizeProcessor
04213 {
04214 public:
04215 string get_name() const
04216 {
04217 return NAME;
04218 }
04219
04220 string get_desc() const
04221 {
04222 return "Uses a 1/0 mask defining a region to use for the zero-normalization.if no_sigma is 1, standard deviation not modified.";
04223 }
04224
04225 static Processor *NEW()
04226 {
04227 return new NormalizeMaskProcessor();
04228 }
04229
04230 TypeDict get_param_types() const
04231 {
04232 TypeDict d;
04233 d.put("mask", EMObject::EMDATA, "the 1/0 mask defining a region to use for the zero-normalization");
04234 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");
04235 return d;
04236 }
04237
04238 static const string NAME;
04239
04240 protected:
04241 float calc_sigma(EMData * image) const;
04242 float calc_mean(EMData * image) const;
04243 };
04244
04250 class NormalizeRampNormVar: public Processor
04251 {
04252 public:
04253 string get_name() const
04254 {
04255 return NAME;
04256 }
04257
04258 static Processor *NEW()
04259 {
04260 return new NormalizeRampNormVar();
04261 }
04262
04263 string get_desc() const
04264 {
04265 return "First call filter.ramp on the image, then make the mean 0 and norm 1";
04266 }
04267
04268 void process_inplace(EMData * image);
04269
04270 static const string NAME;
04271 };
04272
04281 class NormalizeByMassProcessor: public Processor
04282 {
04283 public:
04284 string get_name() const
04285 {
04286 return NAME;
04287 }
04288
04289 static Processor *NEW()
04290 {
04291 return new NormalizeByMassProcessor();
04292 }
04293
04294 string get_desc() const
04295 {
04296 return "Normalize the mass of the image assuming a density of 1.35 g/ml (0.81 Da/A^3) (3D only)";
04297 }
04298
04299 TypeDict get_param_types() const
04300 {
04301 TypeDict d;
04302 d.put("apix", EMObject::FLOAT,"Angstrom per pixel of the image. If not set will use the apix_x attribute of the image");
04303 d.put("mass", EMObject::FLOAT,"The approximate mass of protein/structure in kilodaltons");
04304 d.put("thr", EMObject::FLOAT,"The isosurface threshold which encapsulates the structure");
04305 return d;
04306 }
04307
04308 void process_inplace(EMData * image);
04309
04310 static const string NAME;
04311 };
04312
04313
04316 class NormalizeEdgeMeanProcessor:public NormalizeProcessor
04317 {
04318 public:
04319 string get_name() const
04320 {
04321 return NAME;
04322 }
04323
04324 static Processor *NEW()
04325 {
04326 return new NormalizeEdgeMeanProcessor();
04327 }
04328
04329 string get_desc() const
04330 {
04331 return "normalizes an image, mean value equals to edge mean.";
04332 }
04333
04334 static const string NAME;
04335
04336 protected:
04337 float calc_mean(EMData * image) const;
04338 };
04339
04342 class NormalizeCircleMeanProcessor:public NormalizeProcessor
04343 {
04344 public:
04345 string get_name() const
04346 {
04347 return NAME;
04348 }
04349
04350 static Processor *NEW()
04351 {
04352 return new NormalizeCircleMeanProcessor();
04353 }
04354
04355 string get_desc() const
04356 {
04357 return "normalizes an image, mean value equals to mean of 2 pixel circular border.";
04358 }
04359
04360 static const string NAME;
04361
04362 protected:
04363 float calc_mean(EMData * image) const;
04364 };
04365
04368 class NormalizeLREdgeMeanProcessor:public NormalizeProcessor
04369 {
04370 public:
04371 string get_name() const
04372 {
04373 return NAME;
04374 }
04375
04376 static Processor *NEW()
04377 {
04378 return new NormalizeLREdgeMeanProcessor();
04379 }
04380
04381 string get_desc() const
04382 {
04383 return "normalizes an image, uses 2 pixels on left and right edge";
04384 }
04385
04386 static const string NAME;
04387
04388 protected:
04389 float calc_mean(EMData * image) const;
04390 };
04391
04394 class NormalizeMaxMinProcessor:public NormalizeProcessor
04395 {
04396 public:
04397 string get_name() const
04398 {
04399 return NAME;
04400 }
04401
04402 static Processor *NEW()
04403 {
04404 return new NormalizeMaxMinProcessor();
04405 }
04406
04407 string get_desc() const
04408 {
04409 return "normalizes an image. mean -> (maxval-minval)/2; std dev = (maxval+minval)/2;";
04410 }
04411
04412 static const string NAME;
04413
04414 protected:
04415 float calc_sigma(EMData * image) const;
04416 float calc_mean(EMData * image) const;
04417 };
04418
04421 class NormalizeRowProcessor:public Processor
04422 {
04423 public:
04424 string get_name() const
04425 {
04426 return NAME;
04427 }
04428
04429 static Processor *NEW()
04430 {
04431 return new NormalizeRowProcessor();
04432 }
04433
04434 string get_desc() const
04435 {
04436 return "normalizes each row in the image individually";
04437 }
04438
04439 static const string NAME;
04440
04441 void process_inplace(EMData * image);
04442 };
04443
04449 class NormalizeToLeastSquareProcessor:public Processor
04450 {
04451 public:
04452 void process_inplace(EMData * image);
04453
04454 string get_name() const
04455 {
04456 return NAME;
04457 }
04458
04459 static Processor *NEW()
04460 {
04461 return new NormalizeToLeastSquareProcessor();
04462 }
04463
04464 TypeDict get_param_types() const
04465 {
04466 TypeDict d;
04467 d.put("to", EMObject::EMDATA, "reference image normalize to");
04468 d.put("ignore_zero", EMObject::BOOL, "If set, ignores any pixels which are exactly zero in either image. Defaut = True.");
04469 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)");
04470 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)");
04471 return d;
04472 }
04473
04474 string get_desc() const
04475 {
04476 return "use least square method to normalize";
04477 }
04478
04479 static const string NAME;
04480 };
04481
04484 class RotationalAverageProcessor:public Processor
04485 {
04486 public:
04487 void process_inplace(EMData * image);
04488
04489 string get_name() const
04490 {
04491 return NAME;
04492 }
04493
04494 static Processor *NEW()
04495 {
04496 return new RotationalAverageProcessor();
04497 }
04498
04499 string get_desc() const
04500 {
04501 return "Makes image circularly/spherically symmetric.";
04502 }
04503
04504 static const string NAME;
04505 };
04506
04509 class RotationalSubstractProcessor:public Processor
04510 {
04511 public:
04512 virtual void process_inplace(EMData * image);
04513
04514 virtual string get_name() const
04515 {
04516 return NAME;
04517 }
04518
04519 static Processor *NEW()
04520 {
04521 return new RotationalSubstractProcessor();
04522 }
04523
04524 virtual string get_desc() const
04525 {
04526 return "subtracts circularly/spherically symmetric part of an image.";
04527 }
04528
04529 static const string NAME;
04530 };
04531
04537 class TransposeProcessor:public Processor
04538 {
04539 public:
04540
04545 virtual void process_inplace(EMData * image);
04546
04551 virtual EMData* process(const EMData * const image);
04552
04553 virtual string get_name() const
04554 {
04555 return NAME;
04556 }
04557
04558 static Processor *NEW()
04559 {
04560 return new TransposeProcessor();
04561 }
04562
04563 virtual TypeDict get_param_types() const
04564 {
04565 TypeDict d;
04566 return d;
04567 }
04568
04569 virtual string get_desc() const
04570 {
04571 return "Get the transpose of an image. Works for 2D only";
04572 }
04573
04574 static const string NAME;
04575 };
04576
04577
04581 class FlipProcessor:public Processor
04582 {
04583 public:
04584 virtual void process_inplace(EMData * image);
04585
04586 virtual string get_name() const
04587 {
04588 return NAME;
04589 }
04590
04591 static Processor *NEW()
04592 {
04593 return new FlipProcessor();
04594 }
04595
04596 virtual TypeDict get_param_types() const
04597 {
04598 TypeDict d;
04599 d.put("axis", EMObject::STRING, "'x', 'y', or 'z' axis.");
04600 return d;
04601 }
04602
04603 virtual string get_desc() const
04604 {
04605 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.";
04606 }
04607
04608 static const string NAME;
04609 };
04610
04611
04612
04613
04614
04615
04616
04617
04618
04619
04620
04621
04622
04623
04624
04625
04626
04627
04628
04629
04630
04631
04632
04633
04634
04635
04636
04637
04638
04639
04644 class AddNoiseProcessor:public Processor
04645 {
04646 public:
04647 virtual void process_inplace(EMData * image);
04648
04649 virtual string get_name() const
04650 {
04651 return NAME;
04652 }
04653
04654 static Processor *NEW()
04655 {
04656 return new AddNoiseProcessor();
04657 }
04658
04659 virtual TypeDict get_param_types() const
04660 {
04661 TypeDict d;
04662 d.put("noise", EMObject::FLOAT, "noise factor used to generate Gaussian distribution random noise");
04663 d.put("seed", EMObject::INT, "seed for random number generator");
04664 return d;
04665 }
04666
04667 virtual string get_desc() const
04668 {
04669 return "add noise to an image, image multiply by noise then add a random value";
04670 }
04671
04672 static const string NAME;
04673
04674 protected:
04675 virtual float get_sigma(EMData *)
04676 {
04677 return 1.0;
04678 }
04679 };
04680
04683 class AddSigmaNoiseProcessor:public AddNoiseProcessor
04684 {
04685 public:
04686 virtual string get_name() const
04687 {
04688 return NAME;
04689 }
04690
04691 static Processor *NEW()
04692 {
04693 return new AddSigmaNoiseProcessor();
04694 }
04695
04696 virtual string get_desc() const
04697 {
04698 return "add sigma noise.";
04699 }
04700
04701 static const string NAME;
04702
04703 protected:
04704 float get_sigma(EMData * image);
04705 };
04706
04715 class AddRandomNoiseProcessor:public Processor
04716 {
04717 public:
04718 virtual void process_inplace(EMData * image);
04719
04720 virtual string get_name() const
04721 {
04722 return NAME;
04723 }
04724
04725 static Processor *NEW()
04726 {
04727 return new AddRandomNoiseProcessor();
04728 }
04729
04730 virtual TypeDict get_param_types() const
04731 {
04732 TypeDict d;
04733 d.put("n", EMObject::INT);
04734 d.put("x0", EMObject::FLOAT);
04735 d.put("dx", EMObject::FLOAT);
04736 d.put("y", EMObject::FLOATARRAY);
04737 d.put("interpolation", EMObject::INT);
04738 d.put("seed", EMObject::INT, "seed for random number generator");
04739 return d;
04740 }
04741
04742 virtual string get_desc() const
04743 {
04744 return "add spectral noise to a complex image.";
04745 }
04746
04747 static const string NAME;
04748 };
04749
04755 class FourierToCornerProcessor:public Processor
04756 {
04757 public:
04763 virtual void process_inplace(EMData * image);
04764
04765 virtual string get_name() const
04766 {
04767 return NAME;
04768 }
04769
04770 static Processor *NEW()
04771 {
04772 return new FourierToCornerProcessor();
04773 }
04774
04775 virtual string get_desc() const
04776 {
04777 return "Undoes the xform.fourierorigin.tocenter processor";
04778 }
04779
04780 static const string NAME;
04781 };
04782
04783
04795 class FourierToCenterProcessor:public Processor
04796 {
04797 public:
04803 virtual void process_inplace(EMData * image);
04804
04805 virtual string get_name() const
04806 {
04807 return NAME;
04808 }
04809
04810 static Processor *NEW()
04811 {
04812 return new FourierToCenterProcessor();
04813 }
04814
04815 virtual string get_desc() const
04816 {
04817 return "Translates the origin in Fourier space from the corner to the center in y and z - works in 2D and 3D";
04818 }
04819
04820 static const string NAME;
04821 };
04822
04832 class Phase180Processor:public Processor
04833 {
04834 protected:
04847 void swap_corners_180(EMData * image);
04848
04860 void swap_central_slices_180(EMData * image);
04861
04868 void fourier_phaseshift180(EMData * image);
04869
04870 };
04871
04881 class PhaseToCenterProcessor:public Phase180Processor
04882 {
04883 public:
04884 virtual void process_inplace(EMData * image);
04885
04886 virtual string get_name() const
04887 {
04888 return NAME;
04889 }
04890
04891 static Processor *NEW()
04892 {
04893 return new PhaseToCenterProcessor();
04894 }
04895
04896 virtual string get_desc() const
04897 {
04898 return "Undoes the effect of the xform.phaseorigin.tocorner processor";
04899 }
04900
04901 static const string NAME;
04902 };
04903
04911 class PhaseToCornerProcessor:public Phase180Processor
04912 {
04913 public:
04914 virtual void process_inplace(EMData * image);
04915
04916 virtual string get_name() const
04917 {
04918 return NAME;
04919 }
04920
04921 static Processor *NEW()
04922 {
04923 return new PhaseToCornerProcessor();
04924 }
04925
04926 virtual string get_desc() const
04927 {
04928 return "Translates a centered image to the corner in a forward fashion";
04929 }
04930
04931 static const string NAME;
04932 };
04933
04938 class AutoMask2DProcessor:public Processor
04939 {
04940 public:
04941 virtual void process_inplace(EMData * image);
04942
04943 virtual string get_name() const
04944 {
04945 return NAME;
04946 }
04947
04948 static Processor *NEW()
04949 {
04950 return new AutoMask2DProcessor();
04951 }
04952
04953 virtual TypeDict get_param_types() const
04954 {
04955 TypeDict d;
04956 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
04957 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
04958 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
04959 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
04960 d.put("nshells", EMObject::INT, "The number of dilation operations");
04961 d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
04962 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
04963 d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
04964 return d;
04965 }
04966
04967 virtual string get_desc() const
04968 {
04969 return "2D version of mask.auto3d";
04970 }
04971
04972 static const string NAME;
04973 };
04974
04975
04982 class AutoMaskAsymUnit:public Processor
04983 {
04984 public:
04985 virtual void process_inplace(EMData * image);
04986
04987 virtual string get_name() const
04988 {
04989 return NAME;
04990 }
04991
04992 static Processor *NEW()
04993 {
04994 return new AutoMaskAsymUnit();
04995 }
04996
04997 virtual TypeDict get_param_types() const
04998 {
04999 TypeDict d;
05000 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.");
05001 d.put("sym", EMObject::STRING, "The symmetry, for example, d7");
05002 return d;
05003 }
05004
05005 virtual string get_desc() const
05006 {
05007 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.";
05008 }
05009
05010 static const string NAME;
05011 };
05012
05017 class AutoMask3DProcessor:public Processor
05018 {
05019 public:
05020 virtual void process_inplace(EMData * image);
05021
05022 virtual string get_name() const
05023 {
05024 return NAME;
05025 }
05026
05027 static Processor *NEW()
05028 {
05029 return new AutoMask3DProcessor();
05030 }
05031
05032 virtual TypeDict get_param_types() const
05033 {
05034 TypeDict d;
05035 d.put("threshold1", EMObject::FLOAT);
05036 d.put("threshold2", EMObject::FLOAT);
05037 return d;
05038 }
05039
05040 virtual string get_desc() const
05041 {
05042 return "Tries to mask out only interesting density";
05043 }
05044
05045 static void search_nearby(float *dat, float *dat2, int nx, int ny, int nz, float thr);
05046 static void fill_nearby(float *dat2, int nx, int ny, int nz);
05047
05048 static const string NAME;
05049 };
05050
05058 class AutoMask3D2Processor:public Processor
05059 {
05060 public:
05061 virtual void process_inplace(EMData * image);
05062
05063 virtual string get_name() const
05064 {
05065 return NAME;
05066 }
05067
05068 static Processor *NEW()
05069 {
05070 return new AutoMask3D2Processor();
05071 }
05072
05073 virtual string get_desc() const
05074 {
05075 return "This will mask a 3-D volume using a 'flood filling' approach. It begins with a seed generated either as a sphere with \
05076 specified 'radius' or with the 'nmaxseed' highest values. It then includes any mass connected to the seed with value higher than 'threshold'.\
05077 Next, the mask is expanded by 'nshells'+'nshellsgauss'/2 voxels. Finally a gaussian low-pass filter is applied with a width of 'nshellsgauss'.";
05078 }
05079
05080 virtual TypeDict get_param_types() const
05081 {
05082 TypeDict d;
05083 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
05084 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
05085 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
05086 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
05087 d.put("nshells", EMObject::INT, "Number of 1-voxel shells to expand the mask by.");
05088 d.put("nshellsgauss", EMObject::INT, "Width in voxels of a Gaussian decay at the edge of the mask.");
05089 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
05090 d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
05091 return d;
05092 }
05093
05094 static const string NAME;
05095 };
05096
05100 class AddMaskShellProcessor:public Processor
05101 {
05102 public:
05103 virtual void process_inplace(EMData * image);
05104
05105 virtual string get_name() const
05106 {
05107 return NAME;
05108 }
05109
05110 virtual string get_desc() const
05111 {
05112 return "Add additional shells/rings to an existing 1/0 mask image";
05113 }
05114
05115 static Processor *NEW()
05116 {
05117 return new AddMaskShellProcessor();
05118 }
05119
05120 virtual TypeDict get_param_types() const
05121 {
05122 TypeDict d;
05123 d.put("nshells", EMObject::INT, "number of shells to add");
05124 return d;
05125 }
05126
05127 static const string NAME;
05128 };
05129
05134 class PhaseToMassCenterProcessor:public Processor
05135 {
05136 public:
05137 virtual void process_inplace(EMData * image);
05138
05139 virtual string get_name() const
05140 {
05141 return NAME;
05142 }
05143
05144 static Processor *NEW()
05145 {
05146 return new PhaseToMassCenterProcessor();
05147 }
05148
05149 virtual string get_desc() const
05150 {
05151 return "centers the image the center of mass, which is calculated using Fourier phases, ignores old dx, dy.";
05152 }
05153
05154 virtual TypeDict get_param_types() const
05155 {
05156 TypeDict d;
05157 d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05158 return d;
05159 }
05160
05161 static const string NAME;
05162 };
05163
05168 class ToMassCenterProcessor:public Processor
05169 {
05170 public:
05171 virtual void process_inplace(EMData * image);
05172
05173 virtual string get_name() const
05174 {
05175 return NAME;
05176 }
05177
05178 static Processor *NEW()
05179 {
05180 return new ToMassCenterProcessor();
05181 }
05182
05183 virtual string get_desc() const
05184 {
05185 return "ToMassCenterProcessor centers image at center of mass, with a threshold. Only values higher than the threshold are considered.";
05186 }
05187
05188 virtual TypeDict get_param_types() const
05189 {
05190 TypeDict d;
05191 d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05192 d.put("threshold", EMObject::FLOAT, "Only values larger than the threshold are included in the center of mass computation. Default is 0.");
05193
05194 return d;
05195 }
05196
05197 static const string NAME;
05198 };
05199
05203 class ACFCenterProcessor:public Processor
05204 {
05205 public:
05206 virtual void process_inplace(EMData * image);
05207
05208 virtual string get_name() const
05209 {
05210 return NAME;
05211 }
05212
05213 static Processor *NEW()
05214 {
05215 return new ACFCenterProcessor();
05216 }
05217
05218 virtual string get_desc() const
05219 {
05220 return "Center image using self-convolution.";
05221 }
05222
05223 virtual TypeDict get_param_types() const
05224 {
05225 TypeDict d;
05226 return d;
05227 }
05228
05229 static const string NAME;
05230 };
05231
05236 class SNRProcessor:public Processor
05237 {
05238 public:
05239 virtual void process_inplace(EMData * image);
05240
05241 virtual string get_name() const
05242 {
05243 return NAME;
05244 }
05245
05246 static Processor *NEW()
05247 {
05248 return new SNRProcessor();
05249 }
05250
05251 virtual string get_desc() const
05252 {
05253 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.";
05254 }
05255
05256 virtual TypeDict get_param_types() const
05257 {
05258 TypeDict d;
05259 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");
05260 d.put("snrfile", EMObject::STRING, "structure factor file name");
05261 return d;
05262 }
05263
05264 static const string NAME;
05265 };
05266
05270 class FileFourierProcessor:public Processor
05271 {
05272 public:
05273 virtual void process_inplace(EMData * image);
05274
05275 virtual string get_name() const
05276 {
05277 return NAME;
05278 }
05279
05280 virtual string get_desc() const
05281 {
05282 return "A fourier processor specified in a 2 column text file.";
05283 }
05284
05285 static Processor *NEW()
05286 {
05287 return new FileFourierProcessor();
05288 }
05289
05290 virtual TypeDict get_param_types() const
05291 {
05292 TypeDict d;
05293 d.put("filename", EMObject::STRING, "file name for a 2 column text file which specified a radial function data array.");
05294 return d;
05295 }
05296
05297 static const string NAME;
05298 };
05299
05310 class SymSearchProcessor:public Processor
05311 {
05312 public:
05313 virtual void process_inplace(EMData * image);
05314
05315 virtual string get_name() const
05316 {
05317 return NAME;
05318 }
05319
05320 virtual string get_desc() const
05321 {
05322 return "Identifiy the best symmetry in the given symmetry list for each pixel and then apply the best symmetry to each pixel.";
05323 }
05324
05325 static Processor *NEW()
05326 {
05327 return new SymSearchProcessor();
05328 }
05329
05330 virtual TypeDict get_param_types() const
05331 {
05332 TypeDict d;
05333 d.put("sym", EMObject::STRINGARRAY, "the list of symmetries to search");
05334 d.put("thresh", EMObject::FLOAT, "the minimal level of symmetry to be accepted (0-1)");
05335 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");
05336 d.put("symlabel_map", EMObject::EMDATA, "the optional return map when output_symlabel=1");
05337 return d;
05338 }
05339
05340 static const string NAME;
05341 };
05342
05348 class StripeXYProcessor:public Processor
05349 {
05350 public:
05351 void process_inplace(EMData * image);
05352
05353 virtual string get_name() const
05354 {
05355 return NAME;
05356 }
05357
05358 static Processor *NEW()
05359 {
05360 return new StripeXYProcessor();
05361 }
05362
05363 virtual string get_desc() const
05364 {
05365 return "This processor will remove localized 'striping' along the x/y axes, caused by issues with CCD/CMOS readout. In theory this should be done by dark/gain correction, but in many cases, there are residual effects that this will help eliminate. This can produce high-pass filter-like effects, so generally large length values are suggested. Integration covers +-xlen/ylen. Y and X axes are corrected sequentially, not simultaneously, Y first";
05366 }
05367
05368 virtual TypeDict get_param_types() const
05369 {
05370 TypeDict d;
05371 d.put("xlen", EMObject::INT, "Integration 1/2 length on x axis in pixels. Default=10");
05372 d.put("ylen", EMObject::INT, "Integration 1/2 length on y axis in pixels. Default=10");
05373 return d;
05374 }
05375
05376 static const string NAME;
05377 };
05378
05379
05385 class LocalNormProcessor:public Processor
05386 {
05387 public:
05388 void process_inplace(EMData * image);
05389
05390 virtual string get_name() const
05391 {
05392 return NAME;
05393 }
05394
05395 static Processor *NEW()
05396 {
05397 return new LocalNormProcessor();
05398 }
05399
05400 virtual string get_desc() const
05401 {
05402 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.";
05403 }
05404
05405 virtual TypeDict get_param_types() const
05406 {
05407 TypeDict d;
05408 d.put("threshold", EMObject::FLOAT, "Only values above the threshold will be used to compute the normalization. Generally a good isosurface value.");
05409 d.put("radius", EMObject::FLOAT, "Fourier filter radius expressed in pixels in Fourier space. cutoff_pixels in filter.lowpass.gauss");
05410 d.put("apix", EMObject::FLOAT, "Angstroms per pixel");
05411 return d;
05412 }
05413
05414 static const string NAME;
05415 };
05416
05421 class IndexMaskFileProcessor:public Processor
05422 {
05423 public:
05424 virtual void process_inplace(EMData * image);
05425
05426 virtual string get_name() const
05427 {
05428 return NAME;
05429 }
05430
05431 static Processor *NEW()
05432 {
05433 return new IndexMaskFileProcessor();
05434 }
05435
05436 virtual TypeDict get_param_types() const
05437 {
05438 TypeDict d;
05439 d.put("filename", EMObject::STRING, "mask image file name");
05440 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");
05441 return d;
05442 }
05443
05444 virtual string get_desc() const
05445 {
05446 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.";
05447 }
05448
05449 static const string NAME;
05450 };
05451
05455 class CoordinateMaskFileProcessor:public Processor
05456 {
05457 public:
05458 virtual void process_inplace(EMData * image);
05459
05460 virtual string get_name() const
05461 {
05462 return NAME;
05463 }
05464
05465 static Processor *NEW()
05466 {
05467 return new CoordinateMaskFileProcessor();
05468 }
05469
05470 virtual string get_desc() const
05471 {
05472 return "Multiplies the image by the specified file using pixel coordinates instead of pixel indices. The images can be different size.";
05473 }
05474
05475 virtual TypeDict get_param_types() const
05476 {
05477 TypeDict d;
05478 d.put("filename", EMObject::STRING, "mask image file name");
05479 return d;
05480 }
05481
05482 static const string NAME;
05483 };
05484
05495 class PaintProcessor:public Processor
05496 {
05497 public:
05498 PaintProcessor():x(0), y(0), z(0),r1(0), v1(0.0), r2(0), v2(0.0)
05499 {
05500 }
05501
05502 virtual string get_name() const
05503 {
05504 return NAME;
05505 }
05506
05507 static Processor *NEW()
05508 {
05509 return new PaintProcessor();
05510 }
05511
05512 virtual string get_desc() const
05513 {
05514 return "Paints a circle with a decaying edge into the image. r<r1 -> v1, r1<r<r2 -> (v1,v2), r>r2 unchanged";
05515 }
05516
05517 virtual TypeDict get_param_types() const
05518 {
05519 TypeDict d;
05520 d.put("x", EMObject::INT, "x coordinate for Center of circle");
05521 d.put("y", EMObject::INT, "y coordinate for Center of circle");
05522 d.put("z", EMObject::INT, "z coordinate for Center of circle");
05523 d.put("r1", EMObject::INT, "Inner radius");
05524 d.put("v1", EMObject::FLOAT, "Inner value");
05525 d.put("r2", EMObject::INT, "Outter radius");
05526 d.put("v2", EMObject::FLOAT, "Outer Value");
05527 return d;
05528 }
05529
05530 virtual void set_params(const Dict & new_params)
05531 {
05532 params = new_params;
05533
05534 if (params.has_key("x")) x = params["x"];
05535 if (params.has_key("y")) y = params["y"];
05536 if (params.has_key("z")) z = params["z"];
05537 if (params.has_key("r1")) r1 = params["r1"];
05538 if (params.has_key("r2")) r2 = params["r2"];
05539 if (params.has_key("v1")) v1 = params["v1"];
05540 if (params.has_key("v2")) v2 = params["v2"];
05541 }
05542
05543 static const string NAME;
05544
05545 protected:
05546 virtual void process_inplace(EMData *image);
05547
05548 int x,y,z,r1;
05549 float v1;
05550 int r2;
05551 float v2;
05552
05553 };
05554
05555
05560 class DirectionalSumProcessor : public Processor
05561 {
05562 public:
05563 virtual string get_name() const
05564 {
05565 return NAME;
05566 }
05567
05568 static Processor *NEW()
05569 {
05570 return new DirectionalSumProcessor();
05571 }
05572
05576 virtual EMData* process(const EMData* const image);
05577
05581 virtual void process_inplace(EMData*) {
05582 throw InvalidCallException("The directional sum processor does not work inplace");
05583 }
05584
05585 virtual TypeDict get_param_types() const
05586 {
05587 TypeDict d;
05588 d.put("axis", EMObject::STRING,"The direction of the sum, either x,y or z. Returned axes are xy, xz or zy.");
05589 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)");
05590 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)");
05591 return d;
05592 }
05593
05594 string get_desc() const
05595 {
05596 return "Calculates the projection of the image along one of the axial directions, either x, y or z";
05597 }
05598
05599 static const string NAME;
05600 };
05601
05609 class WatershedProcessor:public Processor
05610 {
05611 public:
05612 virtual void process_inplace(EMData * image);
05613
05614 virtual string get_name() const
05615 {
05616 return NAME;
05617 }
05618
05619 static Processor *NEW()
05620 {
05621 return new WatershedProcessor();
05622 }
05623
05624 virtual string get_desc() const
05625 {
05626 return "Does a watershed";
05627 }
05628
05629 virtual TypeDict get_param_types() const
05630 {
05631 TypeDict d;
05632 d.put("xpoints", EMObject::FLOATARRAY,"x coordinates");
05633 d.put("ypoints", EMObject::FLOATARRAY,"y coordinates");
05634 d.put("zpoints", EMObject::FLOATARRAY,"z coordinates");
05635 d.put("minval", EMObject::FLOAT,"min value");
05636 return d;
05637 }
05638
05639 static const string NAME;
05640
05641 private:
05642 vector<Vec3i > watershed(EMData* mask, EMData* image, const float& threshold, const Vec3i& cordinate, const int mask_value);
05643 vector<Vec3i > find_region(EMData* mask,const vector<Vec3i >& coords, const int mask_value, vector<Vec3i >& region);
05644
05645 };
05646
05656 template<class Type>
05657 class BinaryOperateProcessor : public Processor{
05658 public:
05663 virtual void process_inplace(EMData * image) {
05664 if ( ! params.has_key("with") ) throw InvalidParameterException("You must supply the \"with\" parameter");
05665 EMData* with = params["with"];
05666
05667 if ( with->get_xsize() != image->get_xsize() || with->get_ysize() != image->get_ysize() || with->get_zsize() != image->get_zsize() )
05668 throw ImageDimensionException("The images you are operating on do not have the same dimensions");
05669
05670 float* image_data = image->get_data();
05671 float* with_data = with->get_data();
05672
05673 std::transform(image_data,image_data+image->get_size(),with_data,image_data,Type::binary_operate);
05674 image->update();
05675 }
05676
05677 virtual string get_name() const
05678 {
05679 return op.get_name();
05680 }
05681
05682 virtual string get_desc() const
05683 {
05684 return op.get_desc();
05685 }
05686
05687 static Processor *NEW()
05688 {
05689 return new BinaryOperateProcessor<Type>();
05690 }
05691
05692 virtual TypeDict get_param_types() const
05693 {
05694 TypeDict d;
05695 d.put("with", EMObject::EMDATA,"The second image");
05696 return d;
05697 }
05698
05699 static const string NAME;
05700 private:
05701 Type op;
05702 };
05703
05704 class MaxPixelOperator {
05705 public:
05706 string get_name() const
05707 {
05708 return NAME;
05709 }
05710
05711 string get_desc() const
05712 {
05713 return "Compares pixels in two images, returning an image with the maximum pixel value in each pixel location";
05714 }
05715
05716 static float binary_operate(const float& left, const float& right) {
05717 if (left > right) return left;
05718 return right;
05719 }
05720
05721 static const string NAME;
05722 };
05723
05724 class MinPixelOperator {
05725 public:
05726 string get_name() const
05727 {
05728 return NAME;
05729 }
05730
05731 string get_desc() const
05732 {
05733 return "Compares pixels in two images, returning an image with the minimum pixel value in each pixel location";
05734 }
05735
05736 static float binary_operate(const float& left, const float& right) {
05737 if (left < right) return left;
05738 return right;
05739 }
05740
05741 static const string NAME;
05742 };
05743
05747 class MatchSFProcessor:public FourierAnlProcessor
05748 {
05749 public:
05750
05751 virtual string get_name() const
05752 {
05753 return NAME;
05754 }
05755
05756 virtual string get_desc() const
05757 {
05758 return "Filters the image so its 1-D power spectrum matches a second image";
05759 }
05760
05761 static Processor *NEW()
05762 {
05763 return new MatchSFProcessor();
05764 }
05765
05766 virtual TypeDict get_param_types() const
05767 {
05768 TypeDict d;
05769 d.put("to", EMObject::EMDATA, "The image to match with. Make sure apix values are correct.");
05770 return d;
05771 }
05772
05773 static const string NAME;
05774
05775 protected:
05776 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05777 };
05778
05779
05784 class SetSFProcessor:public FourierAnlProcessor
05785 {
05786 public:
05787
05788 virtual string get_name() const
05789 {
05790 return NAME;
05791 }
05792
05793 virtual string get_desc() const
05794 {
05795 return "Filters the image so its 1-D power spectrum matches a supplied X-Y curve";
05796 }
05797
05798 static Processor *NEW()
05799 {
05800 return new SetSFProcessor();
05801 }
05802
05803 virtual TypeDict get_param_types() const
05804 {
05805 TypeDict d;
05806 d.put("strucfac", EMObject::XYDATA, "An XYData object contaning the curve to be imposed as a function of S");
05807 d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
05808 return d;
05809 }
05810
05811 static const string NAME;
05812
05813 protected:
05814 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05815 };
05816
05820 class SmartMaskProcessor:public Processor
05821 {
05822 public:
05823 virtual void process_inplace(EMData * image);
05824
05825 virtual string get_name() const
05826 {
05827 return NAME;
05828 }
05829
05830 static Processor *NEW()
05831 {
05832 return new SmartMaskProcessor();
05833 }
05834
05835 virtual string get_desc() const
05836 {
05837 return "Smart mask processor.";
05838 }
05839
05840 virtual TypeDict get_param_types() const
05841 {
05842 TypeDict d;
05843 d.put("mask", EMObject::FLOAT, "mask value");
05844 return d;
05845 }
05846
05847 static const string NAME;
05848 };
05849
05854 class IterBinMaskProcessor:public Processor
05855 {
05856 public:
05857 virtual void process_inplace(EMData * image);
05858
05859 virtual string get_name() const
05860 {
05861 return NAME;
05862 }
05863
05864 virtual string get_desc() const
05865 {
05866 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.";
05867 }
05868
05869 static Processor *NEW()
05870 {
05871 return new IterBinMaskProcessor();
05872 }
05873
05874 virtual TypeDict get_param_types() const
05875 {
05876 TypeDict d;
05877 d.put("val1", EMObject::FLOAT, "number of pixels to expand");
05878 d.put("val2", EMObject::FLOAT, "number of Gaussian pixels to expand, following the first expansion");
05879 return d;
05880 }
05881
05882 static const string NAME;
05883 };
05884
05887 class TestImageProcessor : public Processor
05888 {
05889 public:
05890 static string get_group_desc()
05891 {
05892 return "Base class for a group of 'processors' used to create test image.";
05893 }
05894
05895 protected:
05896 void preprocess(EMData * image);
05897 int nx, ny, nz;
05898 };
05899
05908 class TestImagePureGaussian : public TestImageProcessor
05909 {
05910 public:
05911 virtual void process_inplace(EMData * image);
05912
05913 virtual string get_name() const
05914 {
05915 return NAME;
05916 }
05917
05918 virtual string get_desc() const
05919 {
05920 return "Replace a source image as a strict Gaussian ";
05921 }
05922
05923 static Processor * NEW()
05924 {
05925 return new TestImagePureGaussian();
05926 }
05927
05928 virtual TypeDict get_param_types() const
05929 {
05930 TypeDict d;
05931 d.put("x_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on x direction");
05932 d.put("y_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on y direction");
05933 d.put("z_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on z direction");
05934 d.put("x_center", EMObject::FLOAT, "center for this Gaussian blob on x direction" );
05935 d.put("y_center", EMObject::FLOAT, "center for this Gaussian blob on y direction" );
05936 d.put("z_center", EMObject::FLOAT, "center for this Gaussian blob on z direction" );
05937 return d;
05938 }
05939
05940 static const string NAME;
05941 };
05942
05946 class TestImageFourierNoiseGaussian : public TestImageProcessor
05947 {
05948 public:
05949 virtual void process_inplace(EMData * image);
05950
05951 virtual string get_name() const
05952 {
05953 return NAME;
05954 }
05955
05956 virtual string get_desc() const
05957 {
05958 return "Replace a source image with pink Fourier noise, based on a Gaussian. Random phase.";
05959 }
05960
05961 static Processor * NEW()
05962 {
05963 return new TestImageFourierNoiseGaussian();
05964 }
05965
05966 virtual TypeDict get_param_types() const
05967 {
05968 TypeDict d;
05969 d.put("sigma", EMObject::FLOAT, "sigma value");
05970 return d;
05971 }
05972
05973 static const string NAME;
05974 };
05975
05980 class TestImageFourierNoiseProfile : public TestImageProcessor
05981 {
05982 public:
05983 virtual void process_inplace(EMData * image);
05984
05985 virtual string get_name() const
05986 {
05987 return NAME;
05988 }
05989
05990 virtual string get_desc() const
05991 {
05992 return "Replace a source image with Fourier noise using amplitude information that is stored in a profile.";
05993 }
05994
05995 static Processor * NEW()
05996 {
05997 return new TestImageFourierNoiseProfile();
05998 }
05999
06000 virtual TypeDict get_param_types() const
06001 {
06002 TypeDict d;
06003 d.put("profile", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
06004 return d;
06005 }
06006
06007 static const string NAME;
06008 };
06009
06010
06015 class CTFSNRWeightProcessor : public TestImageProcessor
06016 {
06017 public:
06018 virtual void process_inplace(EMData * image);
06019
06020 virtual string get_name() const
06021 {
06022 return NAME;
06023 }
06024
06025 virtual string get_desc() const
06026 {
06027 return "Weight the amplitudes of an image based on radial noise and snr curves ";
06028 }
06029
06030 static Processor * NEW()
06031 {
06032 return new CTFSNRWeightProcessor();
06033 }
06034
06035 virtual TypeDict get_param_types() const
06036 {
06037 TypeDict d;
06038 d.put("noise", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
06039 d.put("snr", EMObject::FLOATARRAY, "Squared amplitude divided by squared noise amplitude. As in, what is the EMAN2CTF.snr attribute");
06040 d.put("boost", EMObject::FLOAT, "Multiplicative signal boost");
06041 return d;
06042 }
06043
06044 static const string NAME;
06045 };
06046
06047
06048
06053 class TestImageLineWave : public TestImageProcessor
06054 {
06055 public:
06056 virtual void process_inplace(EMData * image);
06057
06058 virtual string get_name() const
06059 {
06060 return NAME;
06061 }
06062
06063 virtual string get_desc() const
06064 {
06065 return "Insert an oscillating sine wave into the pixel data";
06066 }
06067
06068 static Processor * NEW()
06069 {
06070 return new TestImageLineWave();
06071 }
06072
06073 virtual TypeDict get_param_types() const
06074 {
06075 TypeDict d;
06076 d.put("period", EMObject::FLOAT, "The period of the oscillating sine wave. Default 10.");
06077 return d;
06078 }
06079
06080 static const string NAME;
06081 };
06082
06083
06091 class TestTomoImage : public TestImageProcessor
06092 {
06093 public:
06097 virtual void process_inplace(EMData * image);
06098
06099 virtual string get_name() const
06100 {
06101 return NAME;
06102 }
06103
06104 virtual string get_desc() const
06105 {
06106 return "Make an image consisting various objects, useful for tomographic testing";
06107 }
06108
06109 static Processor * NEW()
06110 {
06111 return new TestTomoImage();
06112 }
06113
06114 static const string NAME;
06115
06116 private:
06117 void insert_solid_ellipse( EMData* image, const Region& region, const float& value, const Transform& t3d = Transform() );
06118 void insert_hollow_ellipse( EMData* image, const Region& region, const float& value, const int& radius, const Transform& t3d = Transform() );
06119 void insert_rectangle( EMData* image, const Region& region, const float& value, const Transform& t3d = Transform() );
06120 };
06121
06129 class TestImageGradient : public TestImageProcessor
06130 {
06131 public:
06132 virtual void process_inplace(EMData * image);
06133
06134 virtual string get_name() const
06135 {
06136 return NAME;
06137 }
06138
06139 virtual string get_desc() const
06140 {
06141 return "Make a gradient image of the form y=mx+b, where x is any of the image axes.";
06142 }
06143
06144 static Processor * NEW()
06145 {
06146 return new TestImageGradient();
06147 }
06148
06149 virtual TypeDict get_param_types() const
06150 {
06151 TypeDict d;
06152 d.put("axis", EMObject::STRING, "The axis the will be used to determine pixel values. Must be x,y or z");
06153 d.put("m", EMObject::FLOAT, "m in the equation m*axis+b. Default is 1.0");
06154 d.put("b", EMObject::FLOAT, "b in the equation m*axis+b. Default is 0.0");
06155 return d;
06156 }
06157
06158 static const string NAME;
06159 };
06160
06168 class TestImageAxes : public TestImageProcessor
06169 {
06170 public:
06175 virtual void process_inplace(EMData * image);
06176
06177 virtual string get_name() const
06178 {
06179 return NAME;
06180 }
06181
06182 virtual string get_desc() const
06183 {
06184 return "Make an image consisting of a single cross";
06185 }
06186
06187 static Processor * NEW()
06188 {
06189 return new TestImageAxes();
06190 }
06191
06192 virtual TypeDict get_param_types() const
06193 {
06194 TypeDict d;
06195 d.put("int", EMObject::FLOAT, "radius of the lines emanating from the origin");
06196 d.put("fill", EMObject::FLOAT, "value to make non-zero pixels");
06197 return d;
06198 }
06199
06200 static const string NAME;
06201 };
06202
06208 class TestImageGaussian : public TestImageProcessor
06209 {
06210 public:
06211 virtual void process_inplace(EMData * image);
06212
06213 virtual string get_name() const
06214 {
06215 return NAME;
06216 }
06217
06218 virtual string get_desc() const
06219 {
06220 return "Replace a source image as a Gaussian Blob";
06221 }
06222
06223 static Processor * NEW()
06224 {
06225 return new TestImageGaussian();
06226 }
06227
06228 virtual TypeDict get_param_types() const
06229 {
06230 TypeDict d;
06231 d.put("sigma", EMObject::FLOAT, "sigma value for this Gaussian blob");
06232 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06233 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06234 return d;
06235 }
06236
06237 static const string NAME;
06238 };
06239
06242 class TestImageScurve : public TestImageProcessor
06243 {
06244 public:
06245 virtual void process_inplace(EMData * image);
06246
06247 virtual string get_name() const
06248 {
06249 return NAME;
06250 }
06251
06252 virtual string get_desc() const
06253 {
06254 return "Replace a source image with a lumpy S-curve used for alignment testing";
06255 }
06256
06257 static Processor * NEW()
06258 {
06259 return new TestImageScurve();
06260 }
06261
06262 virtual TypeDict get_param_types() const
06263 {
06264 TypeDict d;
06265 return d;
06266 }
06267
06268 static const string NAME;
06269 };
06270
06278 class TestImageSphericalWave : public TestImageProcessor
06279 {
06280 public:
06281 virtual void process_inplace(EMData * image);
06282
06283 virtual string get_name() const
06284 {
06285 return NAME;
06286 }
06287
06288 virtual string get_desc() const
06289 {
06290 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)";
06291 }
06292
06293 static Processor * NEW()
06294 {
06295 return new TestImageSphericalWave();
06296 }
06297
06298 virtual TypeDict get_param_types() const
06299 {
06300 TypeDict d;
06301 d.put("wavelength", EMObject::FLOAT, "cos(2*pi*r/wavelength+phase)");
06302 d.put("phase", EMObject::FLOAT, "in radians");
06303 d.put("x", EMObject::FLOAT, "center of the spherical wave");
06304 d.put("y", EMObject::FLOAT, "center of the spherical wave");
06305 d.put("z", EMObject::FLOAT, "center of the spherical wave");
06306 return d;
06307 }
06308
06309 static const string NAME;
06310 };
06311
06312
06321 class TestImageSinewave : public TestImageProcessor
06322 {
06323 public:
06324 virtual void process_inplace(EMData * image);
06325
06326 virtual string get_name() const
06327 {
06328 return NAME;
06329 }
06330
06331 virtual string get_desc() const
06332 {
06333 return "Replace a source image as a sine wave in specified wave length";
06334 }
06335
06336 static Processor * NEW()
06337 {
06338 return new TestImageSinewave();
06339 }
06340
06341 virtual TypeDict get_param_types() const
06342 {
06343 TypeDict d;
06344 d.put("wavelength", EMObject::FLOAT, "wavelength in equation sin(x*2*PI/wavelength - phase*180/PI)");
06345 d.put("axis", EMObject::STRING, "(optional) specify a major axis for asymmetric features, default x axis");
06346 d.put("phase", EMObject::FLOAT, "(optional) the phase in radians");
06347 d.put("az", EMObject::FLOAT, "(optional) angle in degree. for 2D image, this is the rotated angle of the image, \
06348 in 3D image, it's az for euler angle. default is zero");
06349 d.put("alt", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, alt for euler angle, default is zero");
06350 d.put("phi", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, phi for euler angle, default is zero");
06351 return d;
06352 }
06353
06354 static const string NAME;
06355 };
06356
06363 class TestImageSinewaveCircular : public TestImageProcessor
06364 {
06365 public:
06366 virtual void process_inplace(EMData * image);
06367
06368 virtual string get_name() const
06369 {
06370 return NAME;
06371 }
06372
06373 virtual string get_desc() const
06374 {
06375 return "Replace a source image as a circular sine wave in specified wave length";
06376 }
06377
06378 static Processor * NEW()
06379 {
06380 return new TestImageSinewaveCircular();
06381 }
06382
06383 virtual TypeDict get_param_types() const
06384 {
06385 TypeDict d;
06386 d.put("wavelength", EMObject::FLOAT, "(required)this value is the d in function |sin(x/d)|, unit: pixel");
06387 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06388 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06389 d.put("phase", EMObject::FLOAT, "(optional)phase for sine wave, default is 0");
06390 return d;
06391 }
06392
06393 static const string NAME;
06394 };
06395
06402 class TestImageSquarecube : public TestImageProcessor
06403 {
06404 public:
06405 virtual void process_inplace(EMData * image);
06406
06407 virtual string get_name() const
06408 {
06409 return NAME;
06410 }
06411
06412 virtual string get_desc() const
06413 {
06414 return "Replace a source image as a square or cube depends on 2D or 3D of the source image";
06415 }
06416
06417 static Processor * NEW()
06418 {
06419 return new TestImageSquarecube();
06420 }
06421
06422 virtual TypeDict get_param_types() const
06423 {
06424 TypeDict d;
06425 d.put("edge_length", EMObject::FLOAT, "edge length of the square or cube, unit: pixel");
06426 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06427 d.put("odd_edge", EMObject::FLOAT, "edge length for the asymmetric axis");
06428 d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank");
06429 return d;
06430 }
06431
06432 static const string NAME;
06433 };
06434
06442 class TestImageEllipse : public TestImageProcessor
06443 {
06444 public:
06445 virtual void process_inplace(EMData * image);
06446
06447 virtual string get_name() const
06448 {
06449 return NAME;
06450 }
06451
06452 virtual string get_desc() const
06453 {
06454 return "Insert an ellipse into the image.";
06455 }
06456
06457 static Processor * NEW()
06458 {
06459 return new TestImageEllipse();
06460 }
06461
06462 virtual TypeDict get_param_types() const
06463 {
06464 TypeDict d;
06465 d.put("a", EMObject::FLOAT, "equatorial radius along x axes (major semiaxes)");
06466 d.put("b", EMObject::FLOAT, "equatorial radius along y axes (minor semiaxes)");
06467 d.put("c", EMObject::FLOAT, "polar radius for ellipsoid (x^2/a^2+y^2/b^2+z^2/c^2=1)");
06468 d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06469 d.put("fill", EMObject::FLOAT, "value you want to fill in ellipse, default to 1.0");
06470 return d;
06471 }
06472
06473 static const string NAME;
06474 };
06475
06487 class TestImageHollowEllipse : public TestImageProcessor
06488 {
06489 public:
06490 virtual void process_inplace(EMData * image);
06491
06492 virtual string get_name() const
06493 {
06494 return NAME;
06495 }
06496
06497 virtual string get_desc() const
06498 {
06499 return "Insert a hollow ellipse into the image.";
06500 }
06501
06502 static Processor * NEW()
06503 {
06504 return new TestImageHollowEllipse();
06505 }
06506
06507 virtual TypeDict get_param_types() const
06508 {
06509 TypeDict d;
06510 d.put("xwidth", EMObject::FLOAT, "inner equatorial radii along x axes");
06511 d.put("ywidth", EMObject::FLOAT, "inner equatorial radii along y axes");
06512 d.put("zwidth", EMObject::FLOAT, "inner polar radius");
06513 d.put("a", EMObject::FLOAT, "outter equatorial radii along x axes");
06514 d.put("b", EMObject::FLOAT, "outter equatorial radii along y axes");
06515 d.put("c", EMObject::FLOAT, "outter polar radius");
06516 d.put("width",EMObject::FLOAT, "width - specify the width or specify each width explicitly - xwidth, ywidth, zwidth");
06517 d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06518 d.put("fill", EMObject::FLOAT, "value you want to fill in hollow ellipse, default to 1.0");
06519 return d;
06520 }
06521
06522 static const string NAME;
06523 };
06524
06531 class TestImageCirclesphere : public TestImageProcessor
06532 {
06533 public:
06534 virtual void process_inplace(EMData * image);
06535
06536 virtual string get_name() const
06537 {
06538 return NAME;
06539 }
06540
06541 virtual string get_desc() const
06542 {
06543 return "Replace a source image as a circle or sphere depends on 2D or 3D of the source image";
06544 }
06545
06546 static Processor * NEW()
06547 {
06548 return new TestImageCirclesphere();
06549 }
06550
06551 virtual TypeDict get_param_types() const
06552 {
06553 TypeDict d;
06554 d.put("radius", EMObject::FLOAT, "radius of circle or sphere, unit: pixel");
06555 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06556 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06557 d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank.");
06558 return d;
06559 }
06560
06561 static const string NAME;
06562 };
06563
06568 class TestImageNoiseUniformRand : public TestImageProcessor
06569 {
06570 public:
06571 virtual void process_inplace(EMData * image);
06572
06573 virtual string get_name() const
06574 {
06575 return NAME;
06576 }
06577
06578 virtual string get_desc() const
06579 {
06580 return "Replace a source image as a uniform random noise, random number generated from gsl_rng_mt19937, the pixel value is [0, 1)";
06581 }
06582
06583 static Processor * NEW()
06584 {
06585 return new TestImageNoiseUniformRand();
06586 }
06587
06588 virtual TypeDict get_param_types() const
06589 {
06590 TypeDict d;
06591 d.put("seed", EMObject::INT, "seed for random number generator");
06592 return d;
06593 }
06594
06595 static const string NAME;
06596 };
06597
06608 class TestImageNoiseGauss : public TestImageProcessor
06609 {
06610 public:
06611 virtual void process_inplace(EMData * image);
06612
06613 virtual string get_name() const
06614 {
06615 return NAME;
06616 }
06617
06618 virtual string get_desc() const
06619 {
06620 return "Replace a source image as a random noise, the random value is gaussian distributed";
06621 }
06622
06623 static Processor * NEW()
06624 {
06625 return new TestImageNoiseGauss();
06626 }
06627
06628 virtual TypeDict get_param_types() const
06629 {
06630 TypeDict d;
06631 d.put("sigma", EMObject::FLOAT, "sigma value of gausian distributed noise, default is 0.5");
06632 d.put("mean", EMObject::FLOAT, "mean value of gausian distributed noise, default is zero.");
06633 d.put("seed", EMObject::INT, "the seed for random number generator, default is not to reseed.");
06634
06635 return d;
06636 }
06637
06638 static const string NAME;
06639 };
06640
06645 class TestImageCylinder : public TestImageProcessor
06646 {
06647 public:
06648 virtual void process_inplace(EMData * image);
06649
06650 virtual string get_name() const
06651 {
06652 return NAME;
06653 }
06654
06655 virtual string get_desc() const
06656 {
06657 return "Replace a source image as a cylinder";
06658 }
06659
06660 static Processor * NEW()
06661 {
06662 return new TestImageCylinder();
06663 }
06664
06665 virtual TypeDict get_param_types() const
06666 {
06667 TypeDict d;
06668 d.put("radius", EMObject::FLOAT, "radius for the cylinder");
06669 d.put("height", EMObject::FLOAT, "height for the cylinder, by default it's the nz");
06670
06671 return d;
06672 }
06673
06674 static const string NAME;
06675 };
06676
06682 class CCDNormProcessor:public Processor
06683 {
06684 public:
06685 virtual void process_inplace(EMData * image);
06686
06687 virtual string get_name() const
06688 {
06689 return NAME;
06690 }
06691
06692 static Processor *NEW()
06693 {
06694 return new CCDNormProcessor();
06695 }
06696
06697 virtual string get_desc() const
06698 {
06699 return "normalize the 4 quadrants of a CCD image";
06700 }
06701
06702 virtual TypeDict get_param_types() const
06703 {
06704 TypeDict d;
06705 d.put("width", EMObject::INT, "number of pixels on either side of the seam to sample");
06706 return d;
06707 }
06708
06709 static const string NAME;
06710 };
06711
06719 class WaveletProcessor:public Processor
06720 {
06721 public:
06722 virtual void process_inplace(EMData * image);
06723
06724 virtual string get_name() const
06725 {
06726 return NAME;
06727 }
06728
06729 static Processor *NEW()
06730 {
06731 return new WaveletProcessor();
06732 }
06733
06734 virtual TypeDict get_param_types() const
06735 {
06736 TypeDict d;
06737 d.put("type", EMObject::STRING, "'daub', 'harr' or 'bspl'");
06738 d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06739 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)");
06740 return d;
06741 }
06742
06743 virtual string get_desc() const
06744 {
06745 return "Computes the DWT (discrete wavelet transform) of an image in one of 3 possible bases";
06746 }
06747
06748 static const string NAME;
06749 };
06750
06766 class TomoTiltEdgeMaskProcessor : public Processor
06767 {
06768 public:
06769 virtual void process_inplace(EMData* image);
06770
06771 virtual string get_name() const
06772 {
06773 return NAME;
06774 }
06775
06776 static Processor *NEW()
06777 {
06778 return new TomoTiltEdgeMaskProcessor();
06779 }
06780
06781 virtual TypeDict get_param_types() const
06782 {
06783 TypeDict d;
06784 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");
06785 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.");
06786 d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06787 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.");
06788 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)");
06789 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");
06790 return d;
06791 }
06792
06793 virtual string get_desc() const
06794 {
06795 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.";
06796 }
06797
06798 static const string NAME;
06799
06800 private:
06801 class GaussianFunctoid
06802 {
06803 public:
06804 GaussianFunctoid(const float sigma, const float mean = 0.0) : m_mean(mean), m_sigma_squared(sigma*sigma) {}
06805 ~GaussianFunctoid() {}
06806
06807 float operator()(const float distance )
06808 {
06809 return exp( -(distance-m_mean)*(distance-m_mean)/ (m_sigma_squared ));
06810 }
06811 private:
06812 float m_mean, m_sigma_squared;
06813 };
06814
06815 };
06816
06831 class TomoTiltAngleWeightProcessor : public Processor
06832 {
06833 public:
06834 virtual void process_inplace(EMData* image);
06835
06836 virtual string get_name() const
06837 {
06838 return NAME;
06839 }
06840
06841 static Processor *NEW()
06842 {
06843 return new TomoTiltAngleWeightProcessor();
06844 }
06845
06846 virtual TypeDict get_param_types() const
06847 {
06848 TypeDict d;
06849 d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06850 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");
06851 return d;
06852 }
06853
06854 virtual string get_desc() const
06855 {
06856 return "Weights the image by 1/cos(angle)";
06857 }
06858
06859 static const string NAME;
06860
06861 };
06862
06866 class FFTProcessor : public Processor
06867 {
06868 public:
06869 void process_inplace(EMData * image);
06870
06871 string get_name() const
06872 {
06873 return NAME;
06874 }
06875
06876 static Processor *NEW()
06877 {
06878 return new FFTProcessor();
06879 }
06880
06881 TypeDict get_param_types() const
06882 {
06883 TypeDict d;
06884 d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06885 return d;
06886 }
06887
06888 string get_desc() const
06889 {
06890 return "Computes the DFFT (Discrete Fast Fourier Transform) of an image";
06891 }
06892
06893 static const string NAME;
06894 };
06895
06900 class RadialProcessor : public Processor
06901 {
06902 public:
06903 void process_inplace(EMData * image);
06904
06905 string get_name() const
06906 {
06907 return NAME;
06908 }
06909
06910 static Processor *NEW()
06911 {
06912 return new RadialProcessor();
06913 }
06914
06915 TypeDict get_param_types() const
06916 {
06917 TypeDict d;
06918 d.put("table", EMObject::FLOATARRAY, "Radial array of floats, 1 float/pixel");
06919 return d;
06920 }
06921
06922 string get_desc() const
06923 {
06924 return "Multiply a real-space image by a radial function. 1 value / pixel, extending to corner. Missing values -> 0.";
06925 }
06926
06927 static const string NAME;
06928 };
06929
06936 class HistogramBin : public Processor
06937 {
06938 public:
06939 HistogramBin() : default_bins(1024) {}
06940
06941 void process_inplace(EMData * image);
06942
06943 string get_name() const
06944 {
06945 return NAME;
06946 }
06947
06948 static Processor *NEW()
06949 {
06950 return new HistogramBin();
06951 }
06952
06953 TypeDict get_param_types() const
06954 {
06955 TypeDict d;
06956 d.put("nbins", EMObject::INT, "The number of bins the pixel values will be compressed into");
06957 d.put("debug", EMObject::BOOL, "Outputs debugging information (number of pixels per bin)");
06958 return d;
06959 }
06960
06961 string get_desc() const
06962 {
06963 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";
06964 }
06965
06966 static const string NAME;
06967
06968 protected:
06969 int default_bins;
06970 };
06971
06972 class ModelHelixProcessor : public Processor
06973 {
06974 protected:
06975 float radprofile(float r, int type);
06976 };
06977
06978 class ModelEMCylinderProcessor : public ModelHelixProcessor
06979 {
06980 public:
06981 void process_inplace(EMData * in);
06982
06983 string get_name() const
06984 {
06985 return NAME;
06986 }
06987
06988 static Processor *NEW()
06989 {
06990 return new ModelEMCylinderProcessor();
06991 }
06992
06993 string get_desc() const
06994 {
06995 return "Adds a cylinder with a radial density profile similar to that of an alpha helix.";
06996 }
06997
06998 virtual TypeDict get_param_types() const
06999 {
07000 TypeDict d;
07001 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");
07002 d.put("length", EMObject::FLOAT, "cylinder length in angstroms, defaults to 3 turns (16.2 Angstroms)");
07003 d.put("x0", EMObject::INT, "x coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
07004 d.put("y0", EMObject::INT, "y coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
07005 d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
07006
07007 return d;
07008 }
07009
07010 static const string NAME;
07011 };
07012
07013 class ApplyPolynomialProfileToHelix : public ModelHelixProcessor
07014 {
07015 public:
07016 void process_inplace(EMData * in);
07017
07018 string get_name() const
07019 {
07020 return NAME;
07021 }
07022
07023 static Processor *NEW()
07024 {
07025 return new ApplyPolynomialProfileToHelix();
07026 }
07027
07028 string get_desc() const
07029 {
07030 return "Finds the CM of each z-axis slice and applies a polynomial radial profile about it.";
07031 }
07032 virtual TypeDict get_param_types() const
07033 {
07034 TypeDict d;
07035 d.put("length", EMObject::FLOAT, "Helix length in angstroms.");
07036 d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
07037 return d;
07038 }
07039
07040 static const string NAME;
07041 };
07042
07043 class BinarySkeletonizerProcessor : public Processor
07044 {
07045 public:
07046 virtual EMData* process(EMData * image);
07047 virtual void process_inplace(EMData * image);
07048
07049 virtual string get_name() const
07050 {
07051 return NAME;
07052
07053 }
07054 static Processor *NEW()
07055 {
07056 return new BinarySkeletonizerProcessor();
07057 }
07058 string get_desc() const
07059 {
07060 return "Creates a skeleton of the 3D image by considering whether density is above or below a threshold value.";
07061 }
07062 virtual TypeDict get_param_types() const
07063 {
07064 TypeDict d;
07065 d.put("threshold", EMObject::FLOAT, "Threshold value.");
07066 d.put("min_curve_width", EMObject::INT, "Minimum curve width.");
07067 d.put("min_surface_width", EMObject::INT, "Minimum surface width.");
07068 d.put("mark_surfaces", EMObject::BOOL, "Mark surfaces with a value of 2.0f, whereas curves are 1.0f.");
07069 return d;
07070 }
07071 static const string NAME;
07072 };
07073
07074 class ConvolutionKernelProcessor : public Processor
07075 {
07076 public:
07077 virtual EMData* process(const EMData* const image);
07078 virtual void process_inplace(EMData * image);
07079
07080 virtual string get_name() const
07081 {
07082 return NAME;
07083 }
07084 static Processor *NEW()
07085 {
07086 return new ConvolutionKernelProcessor();
07087 }
07088 string get_desc() const
07089 {
07090 return "Filters an image with a convolution kernel in real space.";
07091 }
07092 virtual TypeDict get_param_types() const
07093 {
07094 TypeDict d;
07095 d.put("kernel", EMObject::FLOATARRAY, "the convolution kernel");
07096 return d;
07097 }
07098 static const string NAME;
07099 };
07100
07101 class RotateInFSProcessor : public Processor
07102 {
07103 public:
07104
07105 virtual void process_inplace(EMData * image);
07106 virtual EMData* process(const EMData* const image);
07107
07108 virtual string get_name() const
07109 {
07110 return NAME;
07111 }
07112 static Processor *NEW()
07113 {
07114 return new RotateInFSProcessor( );
07115 }
07116 string get_desc() const
07117 {
07118 return "Rotates a Fourier object using a kernel.";
07119 }
07120 virtual TypeDict get_param_types() const
07121 {
07122 TypeDict d;
07123 d.put("transform", EMObject::TRANSFORM, "transform");
07124 d.put("interpCutoff", EMObject::FLOAT, "cutoff for interpolation");
07125
07126
07127 return d;
07128 }
07129 static const string NAME;
07130 };
07131
07132 #ifdef SPARX_USING_CUDA
07133
07134
07135
07136
07137
07138 class MPICUDA_kmeans {
07139 public:
07140 MPICUDA_kmeans();
07141 ~MPICUDA_kmeans();
07142 int setup(int extm, int extN, int extn, int extK, int extn_start);
07143 void append_flat_image(EMData* im, int pos);
07144 int init_mem(int numdev);
07145 void compute_im2();
07146 int random_ASG(long int rnd);
07147 vector<int> get_ASG();
07148 vector<int> get_asg();
07149 void compute_NC();
07150 vector<int> get_NC();
07151 void set_ASG(const vector <int>& ASG);
07152 void set_NC(const vector <int>& NC);
07153 int get_ct_im_mv();
07154 void set_T(float extT);
07155 float get_T();
07156 void compute_AVE();
07157 void set_AVE(EMData* im, int pos);
07158 vector<EMData*> get_AVE();
07159 int one_iter();
07160
07161
07162 int one_iter_SA();
07163 vector<float> compute_ji();
07164 vector<float> compute_criterion(const vector <float>& Ji);
07165 int shutdown();
07166 private:
07167
07168 int m;
07169 int N;
07170 int n;
07171 int K;
07172 int nb_part;
07173 int n_start;
07174 int size_im;
07175 int size_IM;
07176 int size_AVE;
07177 int size_dist;
07178 int BLOCK_SIZE;
07179 int NB;
07180 int ins_BLOCK;
07181 int ite;
07182 float T;
07183
07184 int ct_im_mv;
07185
07186 float* h_IM;
07187 float* h_im;
07188 float* h_AVE;
07189 float* h_dist;
07190 float* h_AVE2;
07191 float* h_im2;
07192 unsigned short int* h_ASG;
07193 unsigned short int* h_asg;
07194 unsigned int* h_NC;
07195 int* params;
07196 float ttt;
07197
07198 float* d_im;
07199 float* d_AVE;
07200 float* d_dist;
07201
07202 float compute_tt();
07203 };
07204
07205 #endif //EMAN2_USING_CUDA
07206
07207 #if 0
07208
07209 class XYZProcessor:public Processor
07210 {
07211 public:
07212 void process_inplace(EMData * image);
07213
07214 string get_name() const
07215 {
07216 return NAME;
07217 }
07218
07219 static Processor *NEW()
07220 {
07221 return new XYZProcessor();
07222 }
07223
07224 string get_desc() const
07225 {
07226 return "N/A";
07227 }
07228
07229 TypeDict get_param_types() const
07230 {
07231 TypeDict d;
07232 return d;
07233 }
07234
07235 static const string NAME;
07236 };
07237
07238
07239 #endif
07240
07241
07242 #if 0
07243
07244 class XYZProcessor:public Processor
07245 {
07246 public:
07247 void process_inplace(EMData * image);
07248
07249 string get_name() const
07250 {
07251 return NAME;
07252 }
07253
07254 static Processor *NEW()
07255 {
07256 return new XYZProcessor();
07257 }
07258
07259 string get_desc() const
07260 {
07261 return "N/A";
07262 }
07263
07264 TypeDict get_param_types() const
07265 {
07266 TypeDict d;
07267 return d;
07268 }
07269
07270 static const string NAME;
07271 };
07272
07273
07274 #endif
07275
07276
07277 int multi_processors(EMData * image, vector < string > processornames);
07278 void dump_processors();
07279 map<string, vector<string> > dump_processors_list();
07280 map<string, vector<string> > group_processors();
07281
07282 template <> Factory < Processor >::Factory();
07283 }
07284
07285 #endif //eman_filter_h__
07286
07287
07288