00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef eman_processor_h__
00037 #define eman_processor_h__ 1
00038
00039 #include "emobject.h"
00040 #include "util.h"
00041 #include "geometry.h"
00042 #include "transform.h"
00043 #include "emdata.h"
00044 #include "gorgon/skeletonizer.h"
00045
00046 #include <cfloat>
00047 #include <climits>
00048 #include <cstring>
00049
00050 using std::vector;
00051 using std::map;
00052 using std::string;
00053
00054 namespace EMAN
00055 {
00056 class EMData;
00057
00093 class Processor
00094 {
00095 public:
00096 virtual ~ Processor()
00097 {
00098 }
00099
00105 virtual void process_inplace(EMData *image) = 0;
00106
00113 virtual EMData* process(const EMData * const image);
00114
00118 virtual void process_list_inplace(vector < EMData * > & images)
00119 {
00120 for (size_t i = 0; i < images.size(); i++) {
00121 process_inplace(images[i]);
00122 }
00123 }
00124
00128 virtual string get_name() const = 0;
00129
00133 virtual Dict get_params() const
00134 {
00135 return params;
00136 }
00137
00141 virtual void set_params(const Dict & new_params)
00142 {
00143 params = new_params;
00144 }
00145
00152 virtual TypeDict get_param_types() const
00153 {
00154 return TypeDict();
00155 }
00156
00163 static string get_group_desc()
00164 {
00165 return "EMAN processors are in-place image processors. You may apply a processor to process a single image or process multiple images. Processor class is the base class for all processor. <br> \
00166 The basic design of EMAN Processors: <br>\
00167 1) Each Processor class defines an image-processinging algorithm. <br>\
00168 2) All the Processor classes in EMAN are managed by a Factory pattern. So each Processor class must define: <br> a) a unique name to idenfity itself in the factory. <br>b) a static method to register itself in the factory.<br>\
00169 3) Each Processor class defines its own parameter set.<br>\
00170 4) Each Processor class defines functions to return its documentation including parameter information, and processor description. These functions enable EMAN to generate processor manuals dynamically.";
00171 }
00172
00178 virtual string get_desc() const = 0;
00179
00186 enum fourier_filter_types {
00187 TOP_HAT_LOW_PASS,
00188 TOP_HAT_HIGH_PASS,
00189 TOP_HAT_BAND_PASS,
00190 TOP_HOMOMORPHIC,
00191 GAUSS_LOW_PASS,
00192 GAUSS_HIGH_PASS,
00193 GAUSS_BAND_PASS,
00194 GAUSS_INVERSE,
00195 GAUSS_HOMOMORPHIC,
00196 BUTTERWORTH_LOW_PASS,
00197 BUTTERWORTH_HIGH_PASS,
00198 BUTTERWORTH_HOMOMORPHIC,
00199 KAISER_I0,
00200 KAISER_SINH,
00201 KAISER_I0_INVERSE,
00202 KAISER_SINH_INVERSE,
00203 SHIFT,
00204 TANH_LOW_PASS,
00205 TANH_HIGH_PASS,
00206 TANH_HOMOMORPHIC,
00207 TANH_BAND_PASS,
00208 RADIAL_TABLE,
00209 CTF_,
00210 };
00211
00236 static void
00237 EMFourierFilterInPlace(EMData* fimage, Dict params) {
00238 bool doInPlace = true;
00239 EMFourierFilterFunc(fimage, params, doInPlace);
00240 }
00241
00267 static EMData*
00268 EMFourierFilter(EMData* fimage, Dict params) {
00269 bool doInPlace = false;
00270 return EMFourierFilterFunc(fimage, params, doInPlace);
00271 }
00272
00273 private:
00309 static EMData*
00310 EMFourierFilterFunc(EMData* fimage, Dict params, bool doInPlace=true);
00311
00312 protected:
00313 mutable Dict params;
00314 };
00315
00316 class ImageProcessor:public Processor
00317 {
00318 public:
00319 void process_inplace(EMData * image);
00320
00321 static string get_group_desc()
00322 {
00323 return "An Image Processor defines a way to create a processor image. The processor image is used to multiply the input-image in the fourier space. ImageFilter class is the base class. Each specific ImageFilter class must define function create_processor_image(). ";
00324 }
00325
00326 protected:
00327 virtual EMData * create_processor_image() const = 0;
00328 };
00329
00336 class FourierProcessor:public Processor
00337 {
00338 public:
00339 void process_inplace(EMData * image);
00340
00341 static string get_group_desc()
00342 {
00343 return "Fourier Filter processors are a group of processor in the frequency domain. Before using such processors on an image, the image must be transformed from real space to the fourier space. FourierProcessor class is the base class of fourier space processors. Each specific processor is either a lowpass filter processor, or a highpass filter processor, or neighter. The unit of lowpass and highpass parameters are in terms of Nyquist, valid range is [0,0.5]. ";
00344 }
00345
00346 TypeDict get_param_types() const
00347 {
00348 TypeDict d;
00349 d.put("cutoff_abs", EMObject::FLOAT, "Processor radius in terms of Nyquist (0-.5)");
00350 d.put("cutoff_pixels", EMObject::FLOAT, " Width in Fourier pixels (0 - size()/2)");
00351 d.put("cutoff_freq", EMObject::FLOAT, "Resolution in 1/A (0 - 1 / size*apix)");
00352 d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
00353 return d;
00354 }
00355
00356 protected:
00357 virtual void preprocess(EMData *) {}
00358 virtual void create_radial_func(vector < float >&radial_mask) const = 0;
00359 };
00360
00368 class FourierAnlProcessor:public Processor
00369 {
00370 public:
00371 void process_inplace(EMData * image);
00372
00373 static string get_group_desc()
00374 {
00375 return "Fourier Filter processors are a group of processor in the frequency domain. Before using such processors on an image, the image must be transformed from real space to the fourier space. FourierProcessor class is the base class of fourier space processors. Each specific processor is either a lowpass filter processor, or a highpass filter processor, or neighter. The unit of lowpass and highpass parameters are in terms of Nyquist, valid range is [0,0.5]. ";
00376 }
00377
00378 TypeDict get_param_types() const
00379 {
00380 TypeDict d;
00381 d.put("cutoff_abs", EMObject::FLOAT, "Processor radius in terms of Nyquist (0-.5)");
00382 d.put("cutoff_pixels", EMObject::FLOAT, " Width in Fourier pixels (0 - size()/2)");
00383 d.put("cutoff_freq", EMObject::FLOAT, "Resolution in 1/A (0 - 1 / size*apix)");
00384 d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
00385 return d;
00386 }
00387
00388 protected:
00389 virtual void preprocess(EMData *) {}
00390 virtual void create_radial_func(vector < float >&radial_mask,EMData *image) const = 0;
00391 };
00392
00395 class SNREvalProcessor:public Processor
00396 {
00397 public:
00398 string get_name() const
00399 {
00400 return NAME;
00401 }
00402
00403 void process_inplace(EMData * image);
00404
00405 void set_params(const Dict & new_params)
00406 {
00407 params = new_params;
00408
00409
00410
00411 }
00412
00413 TypeDict get_param_types() const
00414 {
00415 TypeDict d;
00416
00417
00418 return d;
00419 }
00420
00421 static Processor *NEW()
00422 {
00423 return new SNREvalProcessor();
00424 }
00425
00426 string get_desc() const
00427 {
00428 return "Evaluates the SNR of the particle using a masking method similar to that used in the CTF analysis process. The image is not changed. The resulting value is placed in the particle dictionary as eval_maskedsnr";
00429 }
00430
00431 static const string NAME;
00432
00433 protected:
00434 EMData *sum;
00435 int dosqrt;
00436 };
00437
00438
00443 class AmpweightFourierProcessor:public Processor
00444 {
00445 public:
00446 string get_name() const
00447 {
00448 return NAME;
00449 }
00450
00451 void process_inplace(EMData * image);
00452
00453 void set_params(const Dict & new_params)
00454 {
00455 params = new_params;
00456 sum = params["sum"];
00457 dosqrt = params["sqrt"];
00458
00459 }
00460
00461 TypeDict get_param_types() const
00462 {
00463 TypeDict d;
00464 d.put("sum", EMObject::EMDATA, "Adds the weights to sum for normalization");
00465 d.put("sqrt", EMObject::INT, "Weights using sqrt of the amplitude if set");
00466 return d;
00467 }
00468
00469 static Processor *NEW()
00470 {
00471 return new AmpweightFourierProcessor();
00472 }
00473
00474 string get_desc() const
00475 {
00476 return "Multiplies each Fourier pixel by its amplitude";
00477 }
00478
00479 static const string NAME;
00480
00481 protected:
00482 EMData *sum;
00483 int dosqrt;
00484 };
00491 class ConvolutionProcessor : public Processor
00492 {
00493 public:
00494 ConvolutionProcessor() {}
00495
00496 string get_name() const
00497 {
00498 return NAME;
00499 }
00500
00501 void process_inplace(EMData *image);
00502
00503 static Processor *NEW()
00504 {
00505 return new ConvolutionProcessor();
00506 }
00507
00508 string get_desc() const
00509 {
00510 return "Performs Fourier space convolution. Maintains the space that the image is in - i.e. if image is real, the result is real and vice versa.";
00511 }
00512
00513 TypeDict get_param_types() const
00514 {
00515 TypeDict d;
00516 d.put("with", EMObject::EMDATA, "The image that will convolute the other image");
00517 return d;
00518 }
00519
00520 static const string NAME;
00521 };
00522
00529 class XGradientProcessor : public Processor
00530 {
00531 public:
00532 XGradientProcessor() {}
00533
00534 string get_name() const
00535 {
00536 return NAME;
00537 }
00538
00539 void process_inplace(EMData *image);
00540
00541 static Processor *NEW()
00542 {
00543 return new XGradientProcessor();
00544 }
00545
00546 string get_desc() const
00547 {
00548 return "Determines the image gradient in the x direction";
00549 }
00550
00551 TypeDict get_param_types() const
00552 {
00553 TypeDict d;
00554 return d;
00555 }
00556
00557 static const string NAME;
00558 };
00559
00560 class YGradientProcessor : public Processor
00561 {
00562 public:
00563 YGradientProcessor() {}
00564
00565 string get_name() const
00566 {
00567 return NAME;
00568 }
00569
00570 void process_inplace(EMData *image);
00571
00572 static Processor *NEW()
00573 {
00574 return new YGradientProcessor();
00575 }
00576
00577 string get_desc() const
00578 {
00579 return "Determines the image gradient in the y direction";
00580 }
00581
00582
00583 TypeDict get_param_types() const
00584 {
00585 TypeDict d;
00586 return d;
00587 }
00588
00589 static const string NAME;
00590 };
00591
00592 class ZGradientProcessor : public Processor
00593 {
00594 public:
00595 ZGradientProcessor() {}
00596
00597 string get_name() const
00598 {
00599 return NAME;
00600 }
00601
00602 void process_inplace(EMData *image);
00603
00604 static Processor *NEW()
00605 {
00606 return new ZGradientProcessor();
00607 }
00608
00609 string get_desc() const
00610 {
00611 return "Determines the image gradient in the z direction";
00612 }
00613
00614 TypeDict get_param_types() const
00615 {
00616 TypeDict d;
00617 return d;
00618 }
00619
00620 static const string NAME;
00621 };
00622
00631 class Wiener2DAutoAreaProcessor:public Processor
00632 {
00633 public:
00634 string get_name() const
00635 {
00636 return NAME;
00637 }
00638
00639 virtual EMData* process(const EMData * const image);
00640
00641 void process_inplace(EMData *image);
00642
00643 void set_params(const Dict & new_params)
00644 {
00645 params = new_params;
00646 bgsize = params["size"];
00647
00648 }
00649
00650 TypeDict get_param_types() const
00651 {
00652 TypeDict d;
00653 d.put("size", EMObject::INT, "Size in pixels of the boxes to chop the image into");
00654 return d;
00655 }
00656
00657 static Processor *NEW()
00658 {
00659 return new Wiener2DAutoAreaProcessor();
00660 }
00661
00662 string get_desc() const
00663 {
00664 return "Automatically detrmines the background for the image then uses this to perform Wiener filters on overlapping subregions of the image, which are then combined using linear interpolation";
00665 }
00666
00667 static const string NAME;
00668
00669 protected:
00670 int bgsize;
00671 };
00672
00679 class DistanceSegmentProcessor:public Processor
00680 {
00681 public:
00682 string get_name() const
00683 {
00684 return NAME;
00685 }
00686
00687 virtual EMData* process(const EMData * const image);
00688 void process_inplace( EMData * image);
00689
00690 TypeDict get_param_types() const
00691 {
00692 TypeDict d ;
00693 d.put("thr",EMObject::FLOAT,"Optional : Isosurface threshold value. Pixels below this will not be segment centers (default = 0.9)");
00694 d.put("minsegsep",EMObject::FLOAT,"Required: Minimum segment separation in pixels. Segments too close will trigger a reseed");
00695 d.put("maxsegsep",EMObject::FLOAT,"Required: Maximum segment separation in pixels. Segments too close will trigger a reseed");
00696 d.put("verbose",EMObject::INT,"Be verbose while running");
00697 return d;
00698 }
00699
00700 static Processor *NEW()
00701 {
00702 return new DistanceSegmentProcessor();
00703 }
00704
00705 string get_desc() const
00706 {
00707 return "Segments a volume into pieces separated by distances in the specified range.";
00708 }
00709
00710 static const string NAME;
00711
00712 };
00713
00720 class KmeansSegmentProcessor:public Processor
00721 {
00722 public:
00723 string get_name() const
00724 {
00725 return NAME;
00726 }
00727
00728 virtual EMData* process(const EMData * const image);
00729 void process_inplace( EMData * image);
00730
00731 TypeDict get_param_types() const
00732 {
00733 TypeDict d ;
00734 d.put("nseg", EMObject::INT, "Number of segments to divide the image into. default=12" );
00735 d.put("thr",EMObject::FLOAT,"Isosurface threshold value. Pixels below this will not be segmented");
00736 d.put("ampweight",EMObject::INT,"If set, will weight centers by voxel amplitude. default = 1");
00737 d.put("maxsegsize",EMObject::FLOAT,"Maximum radial distance from segment center to member voxel. Default=10000");
00738 d.put("minsegsep",EMObject::FLOAT,"Minimum segment separation. Segments too close will trigger a reseed");
00739 d.put("maxiter",EMObject::FLOAT,"Maximum number of iterations to run before stopping. Default=100");
00740 d.put("maxvoxmove",EMObject::FLOAT,"Maximum number of voxels that can move before quitting. Default=25");
00741 d.put("verbose",EMObject::INT,"Be verbose while running");
00742 return d;
00743 }
00744
00745 static Processor *NEW()
00746 {
00747 return new KmeansSegmentProcessor();
00748 }
00749
00750 string get_desc() const
00751 {
00752 return "Performs K-means segmentation on a volume. Note that this method uses random seeds, and thus will return different results each time it is run. Returned map contains number of segment for each voxel (or 0 for unsegmented voxels). Segmentation centers are stored in 'segmentcenters' attribute, consisting of a list of 3n floats in x,y,z triples.";
00753 }
00754
00755 static const string NAME;
00756
00757 };
00758
00759
00766 class Wiener2DFourierProcessor:public Processor
00767 {
00768 public:
00769 string get_name() const
00770 {
00771 return NAME;
00772 }
00773
00774 virtual EMData* process(const EMData * const image);
00775
00776 void process_inplace(EMData *image);
00777
00778 void set_params(const Dict & new_params)
00779 {
00780 params = new_params;
00781 ctf = params["ctf"];
00782
00783 }
00784
00785 TypeDict get_param_types() const
00786 {
00787 TypeDict d;
00788 d.put("ctf", EMObject::EMDATA, "Ctf object to use for Wiener filter parameters");
00789 return d;
00790 }
00791
00792 static Processor *NEW()
00793 {
00794 return new Wiener2DFourierProcessor();
00795 }
00796
00797 string get_desc() const
00798 {
00799 return "Applies a 2-D Wiener filter to an image based on its Ctf parameters";
00800 }
00801
00802 static const string NAME;
00803
00804 protected:
00805 Ctf *ctf;
00806 };
00807
00808 class LinearRampFourierProcessor:public FourierProcessor
00809 {
00810 public:
00811 virtual string get_name() const
00812 {
00813 return NAME;
00814 }
00815
00816 virtual string get_desc() const
00817 {
00818 return "";
00819 }
00820
00821 static Processor *NEW()
00822 {
00823 return new LinearRampFourierProcessor();
00824 }
00825
00826 static const string NAME;
00827
00828 protected:
00829 virtual void create_radial_func(vector < float >&radial_mask) const ;
00830 };
00831
00834 class LowpassAutoBProcessor:public FourierAnlProcessor
00835 {
00836 public:
00837 string get_name() const
00838 {
00839 return NAME;
00840 }
00841
00842 static Processor *NEW()
00843 {
00844 return new LowpassAutoBProcessor();
00845 }
00846
00847 string get_desc() const
00848 {
00849 return "This processor sharpens a map based on the concept that the power spectrum should be roughly flat over the ~15 A-Nyquist resolution range, then combines this inverse B-factor with the specified low-pass Gaussian filter parameters to produce a single aggregate Gaussian filter.";
00850 }
00851
00852 static const string NAME;
00853
00854 virtual TypeDict get_param_types() const
00855 {
00856 TypeDict d = FourierAnlProcessor::get_param_types();
00857 d.put("bfactor", EMObject::FLOAT, "B-factor in terms of e^-(B s^2/4)");
00858 d.put("noisecutoff", EMObject::FLOAT, "Spatial frequency past which inverse-B will not be applied");
00859
00860 d.put("verbose", EMObject::INT, "Print information about the determined B-factor");
00861 return d;
00862 }
00863
00864 protected:
00865 virtual void preprocess(EMData * image) {
00866 if(params.has_key("apix")) {
00867 image->set_attr("apix_x", (float)params["apix"]);
00868 image->set_attr("apix_y", (float)params["apix"]);
00869 image->set_attr("apix_z", (float)params["apix"]);
00870 }
00871 float apix=(float)image->get_attr("apix_x");
00872
00873 const Dict dict = image->get_attr_dict();
00874 if (params.has_key("cutoff_abs")) {
00875 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00876 }
00877 else if( params.has_key("cutoff_freq") ) {
00878 float val = (float)params["cutoff_freq"] * apix;
00879 params["cutoff_abs"] = val;
00880 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00881 }
00882 else if( params.has_key("cutoff_pixels") ) {
00883 float val = 0.5f*(float)params["cutoff_pixels"] / (float)dict["nx"];
00884 params["cutoff_abs"] = val;
00885 params["bfactor"] = pow(apix/(float)params["cutoff_abs"],2.0f);
00886 }
00887 }
00888
00889 void create_radial_func(vector < float >&radial_mask,EMData *image) const;
00890 };
00891
00894 class HighpassAutoPeakProcessor:public FourierAnlProcessor
00895 {
00896 public:
00897 string get_name() const
00898 {
00899 return NAME;
00900 }
00901 static Processor *NEW()
00902 {
00903 return new HighpassAutoPeakProcessor();
00904 }
00905
00906 string get_desc() const
00907 {
00908 return "Attempts to automatically remove the low resolution peak present in virtually all cryoEM data.";
00909 }
00910
00911 static const string NAME;
00912
00913 protected:
00914 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
00915 virtual void preprocess(EMData * image);
00916 float highpass;
00917 };
00918
00923 class LinearRampProcessor:public FourierProcessor
00924 {
00925 public:
00926 LinearRampProcessor():intercept(0), slope(0)
00927 {
00928 }
00929
00930 string get_name() const
00931 {
00932 return NAME;
00933 }
00934 static Processor *NEW()
00935 {
00936 return new LinearRampProcessor();
00937 }
00938
00939 string get_desc() const
00940 {
00941 return "processor radial function: f(x) = slope * x + intercept;";
00942 }
00943
00944 void set_params(const Dict & new_params)
00945 {
00946 params = new_params;
00947 intercept = params["intercept"];
00948 slope = params["slope"];
00949 }
00950
00951 TypeDict get_param_types() const
00952 {
00953 TypeDict d;
00954 d.put("intercept", EMObject::FLOAT, "intercept in 'f(x) = slope * x + intercept'");
00955 d.put("slope", EMObject::FLOAT, "slope in 'f(x) = slope * x + intercept'");
00956 return d;
00957 }
00958
00959 static const string NAME;
00960
00961 protected:
00962 void create_radial_func(vector < float >&radial_mask) const;
00963
00964 private:
00965 float intercept;
00966 float slope;
00967 };
00968
00971 class RealPixelProcessor:public Processor
00972 {
00973 public:
00974 RealPixelProcessor():value(0), maxval(1), mean(0), sigma(0)
00975 {
00976 }
00977 void process_inplace(EMData * image);
00978
00979 virtual void set_params(const Dict & new_params)
00980 {
00981 params = new_params;
00982 if (params.size() == 1) {
00983 vector < EMObject > dict_values = params.values();
00984 value = dict_values[0];
00985 }
00986 }
00987
00988 static string get_group_desc()
00989 {
00990 return "The base class for real space processor working on individual pixels. The processor won't consider the pixel's coordinates and neighbors.";
00991 }
00992
00993 protected:
00994 virtual void process_pixel(float *x) const = 0;
00995 virtual void calc_locals(EMData *)
00996 {
00997 }
00998 virtual void normalize(EMData *) const
00999 {
01000 }
01001
01002 float value;
01003 float maxval;
01004 float mean;
01005 float sigma;
01006 };
01007
01010 class AbsoluateValueProcessor:public RealPixelProcessor
01011 {
01012 public:
01013 string get_name() const
01014 {
01015 return NAME;
01016 }
01017 static Processor *NEW()
01018 {
01019 return new AbsoluateValueProcessor();
01020 }
01021
01022 static const string NAME;
01023
01024 protected:
01025 void process_pixel(float *x) const
01026 {
01027 *x = fabs(*x);
01028 }
01029
01030 string get_desc() const
01031 {
01032 return "f(x) = |x|";
01033 }
01034 };
01035
01038 class FloorValueProcessor:public RealPixelProcessor
01039 {
01040 public:
01041 string get_name() const
01042 {
01043 return NAME;
01044 }
01045 static Processor *NEW()
01046 {
01047 return new FloorValueProcessor();
01048 }
01049
01050 static const string NAME;
01051
01052 protected:
01053 void process_pixel(float *x) const
01054 {
01055 *x = floor(*x);
01056 }
01057
01058 string get_desc() const
01059 {
01060 return "f(x) = floor(x)";
01061 }
01062 };
01063
01064
01067 class BooleanProcessor:public RealPixelProcessor
01068 {
01069 public:
01070 string get_name() const
01071 {
01072 return NAME;
01073 }
01074 static Processor *NEW()
01075 {
01076 return new BooleanProcessor();
01077 }
01078
01079 string get_desc() const
01080 {
01081 return "f(x) = 0 if x = 0; f(x) = 1 if x != 0;";
01082 }
01083
01084 static const string NAME;
01085
01086 protected:
01087 void process_pixel(float *x) const
01088 {
01089 if (*x != 0)
01090 {
01091 *x = 1.0;
01092 }
01093 }
01094 };
01095
01099 class InvertCarefullyProcessor:public RealPixelProcessor
01100 {
01101 public:
01102 string get_name() const
01103 {
01104 return NAME;
01105 }
01106 static Processor *NEW()
01107 {
01108 return new InvertCarefullyProcessor();
01109 }
01110
01111 void set_params(const Dict & new_params)
01112 {
01113 params = new_params;
01114 zero_to = params.set_default("zero_to",0.0f);
01115 }
01116
01117 TypeDict get_param_types() const
01118 {
01119 TypeDict d;
01120 d.put("zero_to", EMObject::FLOAT, "Inverted zero values are set to this value, default is 0.");
01121 return d;
01122 }
01123
01124 string get_desc() const
01125 {
01126 return "if f(x) != 0: f(x) = 1/f(x) else: f(x) = zero_to";
01127 }
01128
01129 static const string NAME;
01130
01131 protected:
01132 void process_pixel(float *x) const
01133 {
01134 if (*x == 0) *x = zero_to;
01135 else *x = 1/(*x);
01136 }
01137 private:
01138 float zero_to;
01139 };
01140
01144 class ValuePowProcessor:public RealPixelProcessor
01145 {
01146 public:
01147 string get_name() const
01148 {
01149 return NAME;
01150 }
01151 static Processor *NEW()
01152 {
01153 return new ValuePowProcessor();
01154 }
01155
01156 void set_params(const Dict & new_params)
01157 {
01158 params = new_params;
01159 pwr = params["pow"];
01160 }
01161
01162 TypeDict get_param_types() const
01163 {
01164 TypeDict d;
01165 d.put("pow", EMObject::FLOAT, "Each pixel is raised to this power");
01166 return d;
01167 }
01168
01169 string get_desc() const
01170 {
01171 return "f(x) = x ^ pow;";
01172 }
01173
01174 static const string NAME;
01175
01176 protected:
01177 void process_pixel(float *x) const
01178 {
01179 if (*x<0 && pwr!=(int)pwr) *x=0;
01180 else (*x) = pow(*x,pwr);
01181 }
01182 private:
01183 float pwr;
01184 };
01185
01188 class ValueSquaredProcessor:public RealPixelProcessor
01189 {
01190 public:
01191 string get_name() const
01192 {
01193 return NAME;
01194 }
01195 static Processor *NEW()
01196 {
01197 return new ValueSquaredProcessor();
01198 }
01199
01200
01201 string get_desc() const
01202 {
01203 return "f(x) = x * x;";
01204 }
01205
01206 static const string NAME;
01207
01208 protected:
01209 void process_pixel(float *x) const
01210 {
01211 (*x) *= (*x);
01212 }
01213 };
01214
01217 class ValueSqrtProcessor:public RealPixelProcessor
01218 {
01219 public:
01220 string get_name() const
01221 {
01222 return NAME;
01223 }
01224 static Processor *NEW()
01225 {
01226 return new ValueSqrtProcessor();
01227 }
01228
01229 string get_desc() const
01230 {
01231 return "f(x) = sqrt(x)";
01232 }
01233
01234 static const string NAME;
01235
01236 protected:
01237 void process_pixel(float *x) const
01238 {
01239 *x = sqrt(*x);
01240 }
01241 };
01242
01246 class ToZeroProcessor:public RealPixelProcessor
01247 {
01248 public:
01249 string get_name() const
01250 {
01251 return NAME;
01252 }
01253 static Processor *NEW()
01254 {
01255 return new ToZeroProcessor();
01256 }
01257 TypeDict get_param_types() const
01258 {
01259 TypeDict d;
01260 d.put("minval", EMObject::FLOAT, "Everything below this value is set to zero");
01261 return d;
01262 }
01263
01264 string get_desc() const
01265 {
01266 return "f(x) = x if x >= minval; f(x) = 0 if x < minval.";
01267 }
01268
01269 static const string NAME;
01270
01271 protected:
01272 inline void process_pixel(float *x) const
01273 {
01274 if (*x < value) {
01275 *x = 0;
01276 }
01277 }
01278 };
01279
01285 class Rotate180Processor:public Processor
01286 {
01287 public:
01288 string get_name() const
01289 {
01290 return NAME;
01291 }
01292 static Processor *NEW()
01293 {
01294 return new Rotate180Processor();
01295 }
01296
01300 void process_inplace(EMData* image);
01301
01302 string get_desc() const
01303 {
01304 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.";
01305 }
01306
01307 static const string NAME;
01308 };
01309
01316 class TransformProcessor:public Processor
01317 {
01318 public:
01319 virtual string get_name() const
01320 {
01321 return NAME;
01322 }
01323 static Processor *NEW()
01324 {
01325 return new TransformProcessor();
01326 }
01327
01332 virtual void process_inplace(EMData* image);
01333
01338 virtual EMData* process(const EMData* const image);
01339
01340 virtual TypeDict get_param_types() const
01341 {
01342 TypeDict d;
01343 d.put("transform", EMObject::TRANSFORM, "The Transform object that will be applied to the image" );
01344 return d;
01345 }
01346
01347 virtual string get_desc() const
01348 {
01349 return "The image is transformed using Transform parameter.";
01350 }
01351
01352 static const string NAME;
01353
01354 private:
01355 float* transform(const EMData* const image, const Transform& t) const;
01356
01357
01358
01359
01360 void assert_valid_aspect(const EMData* const image) const;
01361 };
01362
01370 class IntTranslateProcessor:public Processor
01371 {
01372 public:
01373 virtual string get_name() const
01374 {
01375 return NAME;
01376 }
01377
01378 static Processor *NEW()
01379 {
01380 return new IntTranslateProcessor();
01381 }
01382
01387 virtual void process_inplace(EMData* image);
01388
01393 virtual EMData* process(const EMData* const image);
01394
01395 virtual TypeDict get_param_types() const
01396 {
01397 TypeDict d;
01398 d.put("trans", EMObject::INTARRAY, "The displacement array, can be length 1-3" );
01399 return d;
01400 }
01401
01402 virtual string get_desc() const
01403 {
01404 return "The image is translated an integer amount";
01405 }
01406
01407 static const string NAME;
01408
01409 private:
01413 void assert_valid_aspect(const vector<int>& translation, const EMData* const image) const;
01414
01420 Region get_clip_region(vector<int>& translation, const EMData* const image) const;
01421 };
01422
01429 class SymAlignProcessor:public Processor
01430 {
01431 public:
01432 virtual string get_name() const
01433 {
01434 return NAME;
01435 }
01436
01437 static Processor *NEW()
01438 {
01439 return new SymAlignProcessor();
01440 }
01441
01442 virtual void process_inplace(EMData* image);
01443
01444 virtual EMData* process(const EMData* const image);
01445
01446 virtual TypeDict get_param_types() const
01447 {
01448 TypeDict d;
01449 d.put("sym", EMObject::STRING, "The symmetry under which to do the alignment, Default=c1" );
01450 d.put("delta", EMObject::FLOAT,"Angle the separates points on the sphere. This is exclusive of the \'n\' paramater. Default is 10");
01451 d.put("dphi", EMObject::FLOAT,"The angle increment in the phi direction. Default is 10");
01452 d.put("lphi", EMObject::FLOAT,"Lower bound for phi. Default it 0");
01453 d.put("uphi", EMObject::FLOAT,"Upper bound for phi. Default it 359.9");
01454 d.put("avger", EMObject::STRING, "The sort of averager to use, Default=mean" );
01455 return d;
01456 }
01457
01458 virtual string get_desc() const
01459 {
01460 return "The image is centered and rotated to the standard orientation for the specified symmetry";
01461 }
01462
01463 static const string NAME;
01464
01465 private:
01469 void assert_valid_aspect(const vector<int>& translation, const EMData* const image) const;
01470
01476 Region get_clip_region(vector<int>& translation, const EMData* const image) const;
01477 };
01478
01479
01486 class ScaleTransformProcessor:public Processor
01487 {
01488 public:
01489 virtual string get_name() const
01490 {
01491 return NAME;
01492 }
01493 static Processor *NEW()
01494 {
01495 return new ScaleTransformProcessor();
01496 }
01497
01502 virtual void process_inplace(EMData* image);
01503
01508 virtual EMData* process(const EMData* const image);
01509
01510 virtual TypeDict get_param_types() const
01511 {
01512 TypeDict d;
01513 d.put("scale", EMObject::FLOAT, "The amount by which to scale" );
01514 d.put("clip", EMObject::INT, "The length of each output dimension. Non sophisticated, output dimensions can't be different" );
01517 return d;
01518 }
01519
01520 virtual string get_desc() const
01521 {
01522 return "The image is scaled with the clip variable in mind, being sure to preserve as much pixel information as possible.";
01523 }
01524
01525 static const string NAME;
01526 };
01527
01534 class ClampingProcessor :public Processor
01535 {
01536 public:
01537 ClampingProcessor() : default_max(1.0), default_min(0.0) {}
01538
01539 string get_name() const
01540 {
01541 return NAME;
01542 }
01543 static Processor *NEW()
01544 {
01545 return new ClampingProcessor();
01546 }
01547
01548 void process_inplace(EMData *image);
01549
01550 TypeDict get_param_types() const
01551 {
01552 TypeDict d;
01553 d.put("minval", EMObject::FLOAT, "The pixel values that bounds the smallest pixel value in the output image" );
01554 d.put("maxval", EMObject::FLOAT, "The pixel values that bounds the largest pixel value in the output image" );
01555 d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01556 return d;
01557 }
01558
01559 string get_desc() const
01560 {
01561 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.";
01562 }
01563
01564 static const string NAME;
01565
01566 protected:
01567 float default_max, default_min;
01568 };
01569
01575 class NSigmaClampingProcessor : public ClampingProcessor
01576 {
01577 public:
01578 NSigmaClampingProcessor() : default_sigma(2.0) {}
01579
01580 string get_name() const
01581 {
01582 return NAME;
01583 }
01584
01585 static Processor *NEW()
01586 {
01587 return new NSigmaClampingProcessor();
01588 }
01589
01590 TypeDict get_param_types() const
01591 {
01592 TypeDict d;
01593 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" );
01594 d.put("tomean", EMObject::BOOL, "Replace outlying pixels values with the mean pixel value instead" );
01595 return d;
01596 }
01597
01598 void process_inplace(EMData *image);
01599
01600 string get_desc() const
01601 {
01602 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.";
01603 }
01604
01605 static const string NAME;
01606
01607 protected:
01608 float default_sigma;
01609 };
01610
01614 class ToMinvalProcessor:public Processor
01615 {
01616 public:
01617 string get_name() const
01618 {
01619 return NAME;
01620 }
01621 static Processor *NEW()
01622 {
01623 return new ToMinvalProcessor();
01624 }
01625
01626 void process_inplace(EMData *image);
01627
01628 TypeDict get_param_types() const
01629 {
01630 TypeDict d;
01631 d.put("minval", EMObject::FLOAT, "Everything below this value is set to this value");
01632 d.put("newval", EMObject::FLOAT, "If set, values below minval will be set to newval instead of minval ");
01633 return d;
01634 }
01635
01636 string get_desc() const
01637 {
01638 return "f(x) = x if x >= minval; f(x) = minval|newval if x < minval.";
01639 }
01640
01641 static const string NAME;
01642
01643 protected:
01644
01645 };
01646
01647
01648
01652 class CutToZeroProcessor:public RealPixelProcessor
01653 {
01654 public:
01655 string get_name() const
01656 {
01657 return NAME;
01658 }
01659 static Processor *NEW()
01660 {
01661 return new CutToZeroProcessor();
01662 }
01663 TypeDict get_param_types() const
01664 {
01665 TypeDict d;
01666 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" );
01667 return d;
01668 }
01669
01670 string get_desc() const
01671 {
01672 return "f(x) = x-minval if x >= minval; f(x) = 0 if x < minval.";
01673 }
01674
01675 static const string NAME;
01676
01677 protected:
01678 void process_pixel(float *x) const
01679 {
01680 *x = *x - value;
01681 if (*x < 0) {
01682 *x = 0;
01683 }
01684 }
01685 };
01686
01690 class BinarizeProcessor:public RealPixelProcessor
01691 {
01692 public:
01693 string get_name() const
01694 {
01695 return NAME;
01696 }
01697 static Processor *NEW()
01698 {
01699 return new BinarizeProcessor();
01700 }
01701 TypeDict get_param_types() const
01702 {
01703 TypeDict d;
01704 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" );
01705 return d;
01706 }
01707
01708 string get_desc() const
01709 {
01710 return "f(x) = 0 if x < value; f(x) = 1 if x >= value.";
01711 }
01712
01713 static const string NAME;
01714
01715 protected:
01716 void process_pixel(float *x) const
01717 {
01718 if (*x < value)
01719 {
01720 *x = 0;
01721 }
01722 else
01723 {
01724 *x = 1;
01725 }
01726 }
01727 };
01728
01736 class BinarizeFourierProcessor:public Processor
01737 {
01738 public:
01739 virtual string get_name() const
01740 {
01741 return NAME;
01742 }
01743 static Processor *NEW()
01744 {
01745 return new BinarizeFourierProcessor();
01746 }
01747
01752 virtual void process_inplace(EMData* image);
01753
01754 virtual TypeDict get_param_types() const
01755 {
01756 TypeDict d;
01757 d.put("value", EMObject::FLOAT, "The Fourier amplitude threshold cutoff" );
01758 return d;
01759 }
01760
01761 virtual string get_desc() const
01762 {
01763 return "f(k) = 0 + 0i if ||f(k)|| < value; f(k) = a + bi if ||f(k)|| >= value.";
01764 }
01765
01766 static const string NAME;
01767 };
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01813 class CollapseProcessor:public RealPixelProcessor
01814 {
01815 public:
01816 string get_name() const
01817 {
01818 return NAME;
01819 }
01820 static Processor *NEW()
01821 {
01822 return new CollapseProcessor();
01823 }
01824
01825 void set_params(const Dict & new_params)
01826 {
01827 params = new_params;
01828 range = params["range"];
01829 value = params["value"];
01830 }
01831
01832 TypeDict get_param_types() const
01833 {
01834 TypeDict d;
01835 d.put("range", EMObject::FLOAT, "The range about 'value' which will be collapsed to 'value'");
01836 d.put("value", EMObject::FLOAT, "The pixel value where the focus of the collapse operation is");
01837 return d;
01838 }
01839
01840 string get_desc() const
01841 {
01842 return "f(x): if v-r<x<v+r -> v; if x>v+r -> x-r; if x<v-r -> x+r";
01843 }
01844
01845 static const string NAME;
01846
01847 protected:
01848 void process_pixel(float *x) const
01849 {
01850 if (*x>value+range) *x-=range;
01851 else if (*x<value-range) *x+=range;
01852 else *x=value;
01853 }
01854 float range;
01855 };
01856
01861 class LinearXformProcessor:public RealPixelProcessor
01862 {
01863 public:
01864 LinearXformProcessor():shift(0), scale(0)
01865 {
01866 }
01867
01868 string get_name() const
01869 {
01870 return NAME;
01871 }
01872 static Processor *NEW()
01873 {
01874 return new LinearXformProcessor();
01875 }
01876
01877 void set_params(const Dict & new_params)
01878 {
01879 params = new_params;
01880 shift = params.get("shift");
01881 scale = params.get("scale");
01882 }
01883
01884 TypeDict get_param_types() const
01885 {
01886 TypeDict d;
01887 d.put("shift", EMObject::FLOAT, "The amount to shift pixel values by before scaling");
01888 d.put("scale", EMObject::FLOAT, "The scaling factor to be applied to pixel values");
01889 return d;
01890 }
01891
01892 string get_desc() const
01893 {
01894 return "linear transform processor: f(x) = x * scale + shift. This is equivalent to a regular contrast stretching operation";
01895 }
01896
01897 static const string NAME;
01898
01899 protected:
01900 void process_pixel(float *x) const
01901 {
01902 *x = (*x) * scale + shift;
01903 }
01904
01905 private:
01906 float shift;
01907 float scale;
01908 };
01909
01914 class ExpProcessor:public RealPixelProcessor
01915 {
01916 public:
01917 ExpProcessor():low(0), high(0)
01918 {
01919 }
01920
01921 string get_name() const
01922 {
01923 return NAME;
01924 }
01925
01926 static Processor *NEW()
01927 {
01928 return new ExpProcessor();
01929 }
01930
01931 void set_params(const Dict & new_params)
01932 {
01933 params = new_params;
01934 low = params.get("low");
01935 high = params.get("high");
01936 }
01937
01938 TypeDict get_param_types() const
01939 {
01940 TypeDict d;
01941 d.put("low", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
01942 d.put("high", EMObject::FLOAT, "Pixels are divided by (low - high) prior to the exponential operation");
01943 return d;
01944 }
01945
01946 string get_desc() const
01947 {
01948 return "f(x) = exp( x / low - high)";
01949 }
01950
01951 static const string NAME;
01952
01953 protected:
01957 void process_pixel(float *x) const
01958 {
01959 float v = *x / low - high;
01960 if (v > 40) {
01961 v = 40;
01962 }
01963 *x = exp(v);
01964 }
01965
01966 private:
01967 float low;
01968 float high;
01969 };
01970
01974 class FiniteProcessor:public RealPixelProcessor
01975 {
01976 public:
01977 FiniteProcessor():to(0)
01978 {
01979 }
01980
01981 string get_name() const
01982 {
01983 return NAME;
01984 }
01985
01986 static Processor *NEW()
01987 {
01988 return new FiniteProcessor();
01989 }
01990
01991 void set_params(const Dict & new_params)
01992 {
01993 if (new_params.has_key("to") )
01994 to = params["to"];
01995 }
01996
01997 TypeDict get_param_types() const
01998 {
01999 TypeDict d;
02000 d.put("to", EMObject::FLOAT, "Pixels which are not finite will be set to this value");
02001 return d;
02002 }
02003
02004 string get_desc() const
02005 {
02006 return "f(x) = f(x) if f(x) is finite | to if f(x) is not finite";
02007 }
02008
02009 static const string NAME;
02010
02011 protected:
02015 void process_pixel(float *x) const;
02016 private:
02017 float to;
02018 };
02019
02024 class RangeThresholdProcessor:public RealPixelProcessor
02025 {
02026 public:
02027 RangeThresholdProcessor():low(0), high(0)
02028 {
02029 }
02030
02031 string get_name() const
02032 {
02033 return NAME;
02034 }
02035 static Processor *NEW()
02036 {
02037 return new RangeThresholdProcessor();
02038 }
02039
02040 void set_params(const Dict & new_params)
02041 {
02042 params = new_params;
02043 low = params.get("low");
02044 high = params.get("high");
02045 }
02046
02047 TypeDict get_param_types() const
02048 {
02049 TypeDict d;
02050 d.put("low", EMObject::FLOAT, "The lower limit of the range that will be set to 1");
02051 d.put("high", EMObject::FLOAT, "The upper limit of the range that will be set to 1");
02052 return d;
02053 }
02054
02055 string get_desc() const
02056 {
02057 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";
02058 }
02059
02060 static const string NAME;
02061
02062 protected:
02063 void process_pixel(float *x) const
02064 {
02065 if (*x >= low && *x <= high) {
02066 *x = 1;
02067 }
02068 else {
02069 *x = 0;
02070 }
02071 }
02072 private:
02073 float low;
02074 float high;
02075
02076 };
02077
02082 class SigmaProcessor:public RealPixelProcessor
02083 {
02084 public:
02085 string get_name() const
02086 {
02087 return NAME;
02088 }
02089 static Processor *NEW()
02090 {
02091 return new SigmaProcessor();
02092 }
02093
02094 void set_params(const Dict & new_params)
02095 {
02096 params = new_params;
02097 value1 = params.get("value1");
02098 value2 = params.get("value2");
02099 }
02100
02101 TypeDict get_param_types() const
02102 {
02103 TypeDict d;
02104 d.put("value1", EMObject::FLOAT, "A number reflecting total standard deviations in the right direction");
02105 d.put("value2", EMObject::FLOAT, "A number reflecting total standard deviations in the left direction");
02106 return d;
02107 }
02108
02109 string get_desc() const
02110 {
02111 return "f(x) = mean if x<(mean-v2*sigma) or x>(mean+v1*sigma); else f(x) = x;";
02112 }
02113
02114 static const string NAME;
02115
02116 protected:
02117 void process_pixel(float *x) const
02118 {
02119 if (*x < (mean - value2 * sigma) || *x > (mean + value1 * sigma))
02120 {
02121 *x = mean;
02122 }
02123 }
02124
02125 private:
02126 float value1;
02127 float value2;
02128 };
02129
02132 class LogProcessor:public RealPixelProcessor
02133 {
02134 public:
02135 string get_name() const
02136 {
02137 return NAME;
02138 }
02139 static Processor *NEW()
02140 {
02141 return new LogProcessor();
02142 }
02143
02144 string get_desc() const
02145 {
02146 return "f(x) = log10(x) if x > 0; else f(x) = 0;";
02147 }
02148
02149 static const string NAME;
02150
02151 protected:
02152 void process_pixel(float *x) const
02153 {
02154 if (*x > 0)
02155 {
02156 *x = log10(*x);
02157 }
02158 else
02159 {
02160 *x = 0;
02161 }
02162 }
02163 };
02164
02167 class CoordinateProcessor:public Processor
02168 {
02169 public:
02170 CoordinateProcessor():nx(0), ny(0), nz(0), mean(0), sigma(0), maxval(0), is_complex(false)
02171 {
02172 }
02173 void process_inplace(EMData * image);
02174
02175 static string get_group_desc()
02176 {
02177 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().";
02178 }
02179
02180 protected:
02181 virtual void process_pixel(float *pixel, int xi, int yi, int zi) const = 0;
02182 virtual void calc_locals(EMData *)
02183 {
02184 }
02185 virtual bool is_valid() const
02186 {
02187 return true;
02188 }
02189
02190 int nx;
02191 int ny;
02192 int nz;
02193 float mean;
02194 float sigma;
02195 float maxval;
02196
02197 bool is_complex;
02198 };
02199
02207 class CircularMaskProcessor:public CoordinateProcessor
02208 {
02209 public:
02210 CircularMaskProcessor():inner_radius(0), outer_radius(0), inner_radius_square(0),
02211 outer_radius_square(0), dx(0), dy(0), dz(0), xc(0), yc(0), zc(0)
02212 {
02213 }
02214
02215 void set_params(const Dict & new_params)
02216 {
02217 params = new_params;
02218
02219 if (params.has_key("inner_radius")) {
02220 inner_radius = params["inner_radius"];
02221 inner_radius_square = inner_radius * inner_radius;
02222 }
02223 else {
02224 inner_radius = -1;
02225 inner_radius_square = -1;
02226 }
02227
02228 if (params.has_key("outer_radius")) {
02229 outer_radius = params["outer_radius"];
02230 outer_radius_square = outer_radius * outer_radius;
02231 }
02232 else {
02233 outer_radius = INT_MAX;
02234 outer_radius_square = INT_MAX;
02235 }
02236
02237 if (params.has_key("xc")) xc = params["xc"];
02238 if (params.has_key("yc")) yc = params["yc"];
02239 if (params.has_key("zc")) zc = params["zc"];
02240 if (params.has_key("dx")) dx = params["dx"];
02241 if (params.has_key("dy")) dy = params["dy"];
02242 if (params.has_key("dz")) dz = params["dz"];
02243 }
02244
02245 string get_desc() const
02246 {
02247 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().";
02248 }
02249
02250 TypeDict get_param_types() const
02251 {
02252 TypeDict d;
02253
02254 d.put("inner_radius", EMObject::INT, "inner mask radius. optional");
02255 d.put("outer_radius", EMObject::INT, "outer mask radius. Negative value -> box radius + outer_radius +1");
02256
02257 d.put("dx", EMObject::FLOAT,
02258 "Modify mask center by dx relative to the default center nx/2");
02259 d.put("dy", EMObject::FLOAT,
02260 "Modify mask center by dy relative to the default center ny/2");
02261 d.put("dz", EMObject::FLOAT,
02262 "Modify mask center by dz relative to the default center nz/2");
02263
02264 return d;
02265 }
02266 protected:
02267 void calc_locals(EMData * image);
02268
02269 bool is_valid() const
02270 {
02271 return (!is_complex);
02272 }
02273
02274 void process_pixel(float *pixel, int xi, int yi, int zi) const
02275 {
02276 float dist = (xi - xc) * (xi - xc) + (yi - yc) * (yi - yc) + (zi - zc) * (zi - zc);
02277 process_dist_pixel(pixel, dist);
02278 }
02279
02280 virtual void process_dist_pixel(float *pixel, float dist) const = 0;
02281
02282 int inner_radius;
02283 int outer_radius;
02284 int inner_radius_square;
02285 int outer_radius_square;
02286 float dx, dy, dz;
02287 float xc, yc, zc;
02288 };
02289
02293 class MaskSharpProcessor:public CircularMaskProcessor
02294 {
02295 public:
02296 MaskSharpProcessor():value(0)
02297 {
02298 }
02299
02300 string get_name() const
02301 {
02302 return NAME;
02303 }
02304 static Processor *NEW()
02305 {
02306 return new MaskSharpProcessor();
02307 }
02308
02309 void set_params(const Dict & new_params)
02310 {
02311 CircularMaskProcessor::set_params(new_params);
02312 value = params.set_default("value",0.0f);
02313 }
02314
02315 TypeDict get_param_types() const
02316 {
02317 TypeDict d = CircularMaskProcessor::get_param_types();
02318 d.put("value", EMObject::FLOAT, "step cutoff to this value. Default is 0.");
02319 return d;
02320 }
02321
02322 string get_desc() const
02323 {
02324 return "step cutoff to a user-given value in both inner and outer circles.";
02325 }
02326
02327 static const string NAME;
02328
02329 protected:
02330 void process_dist_pixel(float *pixel, float dist) const
02331 {
02332 if (dist >= outer_radius_square || dist < inner_radius_square)
02333 {
02334 *pixel = value;
02335 }
02336 }
02337
02338 float value;
02339 };
02340
02341
02345 class MaskEdgeMeanProcessor:public CircularMaskProcessor
02346 {
02347 public:
02348 string get_name() const
02349 {
02350 return NAME;
02351 }
02352 static Processor *NEW()
02353 {
02354 return new MaskEdgeMeanProcessor();
02355 }
02356
02357 void set_params(const Dict & new_params)
02358 {
02359 CircularMaskProcessor::set_params(new_params);
02360 ring_width = params["ring_width"];
02361 if (ring_width == 0) {
02362 ring_width = 1;
02363 }
02364 }
02365
02366 TypeDict get_param_types() const
02367 {
02368 TypeDict d = CircularMaskProcessor::get_param_types();
02369 d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02370 return d;
02371 }
02372
02373 string get_desc() const
02374 {
02375 return "A step cutoff to the the mean value in a ring centered on the outer radius";
02376 }
02377
02378 static const string NAME;
02379
02380 protected:
02381 void calc_locals(EMData * image);
02382
02383
02384 void process_dist_pixel(float *pixel, float dist) const
02385 {
02386 if (dist >= outer_radius_square || dist < inner_radius_square){
02387 *pixel = ring_avg;
02388 }
02389 }
02390
02391 private:
02392 int ring_width;
02393 float ring_avg;
02394 };
02395
02398 class MaskNoiseProcessor:public CircularMaskProcessor
02399 {
02400 public:
02401 string get_name() const
02402 {
02403 return NAME;
02404 }
02405 static Processor *NEW()
02406 {
02407 return new MaskNoiseProcessor();
02408 }
02409
02410 string get_desc() const
02411 {
02412 return "fills masked region";
02413 }
02414
02415 static const string NAME;
02416
02417 protected:
02418 void process_dist_pixel(float *pixel, float dist) const
02419 {
02420 if (dist >= outer_radius_square || dist < inner_radius_square)
02421 {
02422 *pixel = Util::get_gauss_rand(mean, sigma);
02423 }
02424 }
02425 };
02426
02429 class MaskGaussProcessor:public CircularMaskProcessor
02430 {
02431 public:
02432 string get_name() const
02433 {
02434 return NAME;
02435 }
02436 static Processor *NEW()
02437 {
02438 return new MaskGaussProcessor();
02439 }
02440
02441 void set_params(const Dict & new_params)
02442 {
02443 CircularMaskProcessor::set_params(new_params);
02444 exponent = params["exponent"];
02445 if (exponent <= 0.0) {
02446 exponent = 2.0;
02447 }
02448 }
02449
02450 TypeDict get_param_types() const
02451 {
02452 TypeDict d = CircularMaskProcessor::get_param_types();
02453 d.put("exponent", EMObject::FLOAT, "The exponent, f in e^-Bs^f. default 2.0, producing a Gaussian");
02454 return d;
02455 }
02456
02457 string get_desc() const
02458 {
02459 return "a gaussian falloff to zero, radius is the 1/e of the width. If inner_radius>0, then \
02460 outer radius specifies width of Gaussian starting at inner_radius rather than total radius.";
02461 }
02462
02463 static const string NAME;
02464
02465 protected:
02466 float exponent;
02467 void process_dist_pixel(float *pixel, float dist) const
02468 {
02469 if (inner_radius_square>0) {
02470 if (dist>inner_radius_square) {
02471 if (exponent==2.0f) (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,2.0f) / outer_radius_square);
02472 else (*pixel) *= exp(-pow(sqrt(dist)-inner_radius,exponent) / pow((float)outer_radius_square,exponent/2.0f));
02473 }
02474 }
02475 else {
02476 if (exponent==2.0f) (*pixel) *= exp(-dist / outer_radius_square);
02477 else (*pixel) *= exp(-pow(dist,exponent/2.0f) / pow((float)outer_radius_square,exponent/2.0f));
02478 }
02479 }
02480 };
02481
02488 class MaskGaussNonuniformProcessor:public CoordinateProcessor
02489 {
02490 public:
02491 MaskGaussNonuniformProcessor():radius_x(0), radius_y(0), radius_z(0), gauss_width(0)
02492 {
02493 }
02494
02495 void set_params(const Dict & new_params)
02496 {
02497 params = new_params;
02498
02499 if (params.has_key("radius_x")) radius_x=params["radius_x"];
02500 else radius_x=5.0;
02501
02502 if (params.has_key("radius_y")) radius_y=params["radius_y"];
02503 else radius_y=5.0;
02504
02505 if (params.has_key("radius_z")) radius_z=params["radius_z"];
02506 else radius_z=5.0;
02507
02508 if (params.has_key("gauss_width")) gauss_width=params["gauss_width"];
02509 else gauss_width=0.05f;
02510 }
02511
02512 TypeDict get_param_types() const
02513 {
02514 TypeDict d;
02515
02516 d.put("radius_x", EMObject::INT, "x-axis radius");
02517 d.put("radius_y", EMObject::INT, "y-axis radius");
02518 d.put("radius_z", EMObject::INT, "z-axis radius");
02519 d.put("gauss_width", EMObject::FLOAT, "Gaussian falloff width, relative to each radius, default 0.05");
02520
02521 return d;
02522 }
02523
02524 string get_name() const
02525 {
02526 return NAME;
02527 }
02528 static Processor *NEW()
02529 {
02530 return new MaskGaussNonuniformProcessor();
02531 }
02532
02533 string get_desc() const
02534 {
02535 return "A Gaussian falloff to zero. Nonisotropic, specify inner radius for x,y,z and Gaussian falloff width. Falloff \
02536 width is also nonisotropic and relative to the radii, with 1 being equal to the radius on that axis.";
02537 }
02538
02539 static const string NAME;
02540
02541 protected:
02542 void process_pixel(float *pixel, int xi, int yi, int zi) const
02543 {
02544 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);
02545 if (dist>1.0) (*pixel)*=exp(-pow((sqrt(dist)-1.0f)/gauss_width,2.0f));
02546 }
02547
02548 float radius_x,radius_y,radius_z,gauss_width;
02549 };
02550
02555 class MaskGaussInvProcessor:public CircularMaskProcessor
02556 {
02557 public:
02558 TypeDict get_param_types() const
02559 {
02560 TypeDict d = CircularMaskProcessor::get_param_types();
02561 d.put("gauss_width", EMObject::FLOAT, "Used to calculate the constant factor - gauss_width / (ny*ny)" );
02562 d.put("ring_width", EMObject::INT, "The width of the mask ring.");
02563 return d;
02564 }
02565
02566 string get_name() const
02567 {
02568 return NAME;
02569 }
02570
02571 static Processor *NEW()
02572 {
02573 return new MaskGaussInvProcessor();
02574 }
02575
02576 string get_desc() const
02577 {
02578 return "f(x) = f(x) / exp(-radius*radius * gauss_width / (ny*ny))";
02579 }
02580
02581 static const string NAME;
02582
02583 protected:
02584 void calc_locals(EMData *)
02585 {
02586 float gauss_width = params["gauss_width"];
02587 slice_value = gauss_width / (ny * ny);
02588 }
02589
02590 void process_dist_pixel(float *pixel, float dist) const
02591 {
02592 (*pixel) /= exp(-dist * slice_value);
02593 }
02594 private:
02595 float slice_value;
02596 };
02597
02598
02603 class LinearPyramidProcessor:public Processor
02604 {
02605 public:
02606 string get_name() const
02607 {
02608 return NAME;
02609 }
02610
02611 void process_inplace(EMData *image);
02612
02613 static Processor *NEW()
02614 {
02615 return new LinearPyramidProcessor();
02616 }
02617
02618 string get_desc() const
02619 {
02620 return "Multiplies image by a 'linear pyramid', 1-(|x-xsize/2|*|y-ysize/2|*4/(xsize*ysize))";
02621 }
02622
02623 static const string NAME;
02624 };
02625
02626
02629 class MakeRadiusSquaredProcessor:public CircularMaskProcessor
02630 {
02631 public:
02632 string get_name() const
02633 {
02634 return NAME;
02635 }
02636 static Processor *NEW()
02637 {
02638 return new MakeRadiusSquaredProcessor();
02639 }
02640
02641 string get_desc() const
02642 {
02643 return "overwrites input, f(x) = radius * radius";
02644 }
02645
02646 static const string NAME;
02647
02648 protected:
02649 void process_dist_pixel(float *pixel, float dist) const
02650 {
02651 *pixel = dist;
02652 }
02653 };
02654
02657 class MakeRadiusProcessor:public CircularMaskProcessor
02658 {
02659 public:
02660 string get_name() const
02661 {
02662 return NAME;
02663 }
02664 static Processor *NEW()
02665 {
02666 return new MakeRadiusProcessor();
02667 }
02668
02669 string get_desc() const
02670 {
02671 return "overwrites input, f(x) = radius;";
02672 }
02673
02674 static const string NAME;
02675
02676 protected:
02677 void process_dist_pixel(float *pixel, float dist) const
02678 {
02679 *pixel = sqrt(dist);
02680 }
02681 };
02682
02685 class ComplexPixelProcessor:public Processor
02686 {
02687 public:
02688 void process_inplace(EMData * image);
02689
02690 static string get_group_desc()
02691 {
02692 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.";
02693 }
02694
02695 protected:
02696 virtual void process_pixel(float *x) const = 0;
02697 };
02698
02701 class ComplexNormPixel:public ComplexPixelProcessor
02702 {
02703 public:
02704 string get_name() const
02705 {
02706 return NAME;
02707 }
02708 static Processor *NEW()
02709 {
02710 return new ComplexNormPixel();
02711 }
02712
02713 string get_desc() const
02714 {
02715 return "Each Fourier pixel will be normalized. ie - amp=1, phase=unmodified. Useful for performing phase-residual-like computations with dot products.";
02716 }
02717
02718 static const string NAME;
02719
02720 protected:
02721 void process_pixel(float *x) const
02722 {
02723 *x=1.0;
02724 }
02725 };
02726
02730 class AreaProcessor:public Processor
02731 {
02732 public:
02733 AreaProcessor():areasize(0), kernel(0), nx(0), ny(0), nz(0)
02734 {
02735 }
02736
02737 void process_inplace(EMData * image);
02738
02739 void set_params(const Dict & new_params)
02740 {
02741 params = new_params;
02742 areasize = params["areasize"];
02743 }
02744
02745 TypeDict get_param_types() const
02746 {
02747 TypeDict d;
02748 d.put("areasize", EMObject::INT, "The width of the area to process (not radius)");
02749 return d;
02750 }
02751
02752 string get_desc() const
02753 {
02754 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().";
02755 }
02756
02757 protected:
02758 virtual void process_pixel(float *pixel, float, float, float, float *area_matrix) const
02759 {
02760 for (int i = 0; i < matrix_size; i++)
02761 {
02762 *pixel += area_matrix[i] * kernel[i];
02763 }
02764 }
02765
02766 virtual void create_kernel() const = 0;
02767
02768 int areasize;
02769 int matrix_size;
02770 float *kernel;
02771 int nx;
02772 int ny;
02773 int nz;
02774 };
02775
02778 class LaplacianProcessor:public AreaProcessor
02779 {
02780 public:
02781 string get_name() const
02782 {
02783 return NAME;
02784 }
02785 static Processor *NEW()
02786 {
02787 return new LaplacianProcessor();
02788 }
02789
02790 string get_desc() const
02791 {
02792 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).";
02793 }
02794
02795 static const string NAME;
02796
02797 protected:
02798 void create_kernel() const;
02799
02800 };
02801
02804 class ZeroConstantProcessor:public AreaProcessor
02805 {
02806 public:
02807 string get_name() const
02808 {
02809 return NAME;
02810 }
02811 static Processor *NEW()
02812 {
02813 return new ZeroConstantProcessor();
02814 }
02815
02816 string get_desc() const
02817 {
02818 return "Contraction of data, if any nearest neighbor is 0, value -> 0, generally used iteratively";
02819 }
02820
02821 static const string NAME;
02822
02823 protected:
02824 void process_pixel(float *pixel, float, float, float, float *matrix) const
02825 {
02826 if (*pixel != 0)
02827 {
02828 if (*pixel == matrix[1] || *pixel == matrix[3] || *pixel == matrix[5] ||
02829 *pixel == matrix[7] || matrix[1] == 0 || matrix[3] == 0 ||
02830 matrix[5] == 0 || matrix[7] == 0) {
02831 *pixel = 0;
02832 }
02833 }
02834 }
02835
02836 void create_kernel() const
02837 {
02838 }
02839 };
02840
02849 class BoxStatProcessor:public Processor
02850 {
02851 public:
02852 void process_inplace(EMData * image);
02853
02854 static string get_group_desc()
02855 {
02856 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).";
02857 }
02858
02859 TypeDict get_param_types() const
02860 {
02861 TypeDict d;
02862 d.put("radius", EMObject::INT, "The radius of the search box, default is 1 which results in a 3x3 box (3 = 2xradius + 1)");
02863 return d;
02864 }
02865
02866 protected:
02867 virtual void process_pixel(float *pixel, const float *array, int n) const = 0;
02868 };
02869
02870
02873 class BoxMedianProcessor:public BoxStatProcessor
02874 {
02875 public:
02876 string get_name() const
02877 {
02878 return NAME;
02879 }
02880 static Processor *NEW()
02881 {
02882 return new BoxMedianProcessor();
02883 }
02884
02885 string get_desc() const
02886 {
02887 return "A processor for noise reduction. pixel = median of values surrounding pixel.";
02888 }
02889
02890 static const string NAME;
02891
02892 protected:
02893 void process_pixel(float *pixel, const float *array, int n) const
02894 {
02895 float *data = new float[n];
02896 memcpy(data, array, sizeof(float) * n);
02897
02898 for (int i = 0; i <= n / 2; i++)
02899 {
02900 for (int j = i + 1; j < n; j++)
02901 {
02902 if (data[i] < data[j]) {
02903 float t = data[i];
02904 data[i] = data[j];
02905 data[j] = t;
02906 }
02907 }
02908 }
02909
02910 if (n % 2 != 0)
02911 {
02912 *pixel = data[n / 2];
02913 }
02914 else {
02915 *pixel = (data[n / 2] + data[n / 2 - 1]) / 2;
02916 }
02917 if( data )
02918 {
02919 delete[]data;
02920 data = 0;
02921 }
02922 }
02923 };
02924
02927 class BoxSigmaProcessor:public BoxStatProcessor
02928 {
02929 public:
02930 string get_name() const
02931 {
02932 return NAME;
02933 }
02934 static Processor *NEW()
02935 {
02936 return new BoxSigmaProcessor();
02937 }
02938
02939 string get_desc() const
02940 {
02941 return "pixel = standard deviation of values surrounding pixel.";
02942 }
02943
02944 static const string NAME;
02945
02946 protected:
02947 void process_pixel(float *pixel, const float *data, int n) const
02948 {
02949 float sum = 0;
02950 float square_sum = 0;
02951 for (int i = 0; i < n; i++)
02952 {
02953 sum += data[i];
02954 square_sum += data[i] * data[i];
02955 }
02956
02957 float mean = sum / n;
02958 *pixel = sqrt(square_sum / n - mean * mean);
02959 }
02960 };
02961
02964 class BoxMaxProcessor:public BoxStatProcessor
02965 {
02966 public:
02967 string get_name() const
02968 {
02969 return NAME;
02970 }
02971 static Processor *NEW()
02972 {
02973 return new BoxMaxProcessor();
02974 }
02975
02976 string get_desc() const
02977 {
02978 return "peak processor: pixel = max of values surrounding pixel.";
02979 }
02980
02981 static const string NAME;
02982
02983 protected:
02984 void process_pixel(float *pixel, const float *data, int n) const
02985 {
02986 float maxval = -FLT_MAX;
02987 for (int i = 0; i < n; i++)
02988 {
02989 if (data[i] > maxval) {
02990 maxval = data[i];
02991 }
02992 }
02993 *pixel = maxval;
02994 }
02995 };
02996
02999 class MinusPeakProcessor:public BoxStatProcessor
03000 {
03001 public:
03002 string get_name() const
03003 {
03004 return NAME;
03005 }
03006 static Processor *NEW()
03007 {
03008 return new MinusPeakProcessor();
03009 }
03010
03011 string get_desc() const
03012 {
03013 return "peak processor: pixel = pixel - max of values surrounding pixel. This is a sort of positive peak-finding algorithm.";
03014 }
03015
03016 static const string NAME;
03017
03018 protected:
03019 void process_pixel(float *pixel, const float *data, int n) const
03020 {
03021 float maxval = -FLT_MAX;
03022 for (int i = 0; i < n; i++)
03023 {
03024 if (data[i] > maxval) {
03025 maxval = data[i];
03026 }
03027 }
03028 *pixel -= maxval;
03029 }
03030 };
03031
03035 class PeakOnlyProcessor:public BoxStatProcessor
03036 {
03037 public:
03038 string get_name() const
03039 {
03040 return NAME;
03041 }
03042 static Processor *NEW()
03043 {
03044 return new PeakOnlyProcessor();
03045 }
03046 void set_params(const Dict & new_params)
03047 {
03048 params = new_params;
03049 npeaks = params["npeaks"];
03050 if (npeaks == 0) {
03051 npeaks = 1;
03052 }
03053 }
03054
03055 TypeDict get_param_types() const
03056 {
03057 TypeDict d;
03058 d.put("npeaks", EMObject::INT, "the number of surrounding peaks allow to >= pixel values");
03059 return d;
03060 }
03061
03062 string get_desc() const
03063 {
03064 return "peak processor -> if npeaks or more surrounding values >= value, value->0";
03065 }
03066
03067 static const string NAME;
03068
03069 protected:
03070 void process_pixel(float *pixel, const float *data, int n) const
03071 {
03072 int r = 0;
03073
03074 for (int i = 0; i < n; i++)
03075 {
03076 if (data[i] >= *pixel) {
03077 r++;
03078 }
03079 }
03080
03081 if (r > npeaks)
03082 {
03083 *pixel = 0;
03084 }
03085 }
03086 private:
03087 int npeaks;
03088 };
03089
03094 class DiffBlockProcessor:public Processor
03095 {
03096 public:
03097 void process_inplace(EMData * image);
03098
03099 string get_name() const
03100 {
03101 return NAME;
03102 }
03103 static Processor *NEW()
03104 {
03105 return new DiffBlockProcessor();
03106 }
03107
03108 string get_desc() const
03109 {
03110 return "averages over cal_half_width, then sets the value in a local block";
03111 }
03112
03113 TypeDict get_param_types() const
03114 {
03115 TypeDict d;
03116 d.put("cal_half_width", EMObject::FLOAT, "cal_half_width is dx/dy for calculating an average");
03117 d.put("fill_half_width", EMObject::FLOAT, "fill_half_width is dx/dy for fill/step");
03118 return d;
03119 }
03120
03121 static const string NAME;
03122 };
03123
03128 class CutoffBlockProcessor:public Processor
03129 {
03130 public:
03131 void process_inplace(EMData * image);
03132
03133 string get_name() const
03134 {
03135 return NAME;
03136 }
03137 static Processor *NEW()
03138 {
03139 return new CutoffBlockProcessor();
03140 }
03141
03142 TypeDict get_param_types() const
03143 {
03144 TypeDict d;
03145 d.put("value1", EMObject::FLOAT, "val1 is dx/dy");
03146 d.put("value2", EMObject::FLOAT, "val2 is lowpass freq cutoff in pixels");
03147 return d;
03148 }
03149
03150 string get_desc() const
03151 {
03152 return "Block processor, val1 is dx/dy, val2 is lp freq cutoff in pixels. Mystery processor.";
03153 }
03154
03155 static const string NAME;
03156 };
03157
03163 class BooleanShrinkProcessor
03164 {
03165 protected:
03173 template<class LogicOp>
03174 EMData* process(const EMData *const image, Dict& params);
03175
03182 template<class LogicOp>
03183 void process_inplace(EMData * image, Dict& params);
03184
03185 };
03186
03195 class MaxShrinkProcessor:public BooleanShrinkProcessor, public Processor
03196 {
03197 public:
03204 virtual EMData* process(const EMData *const image)
03205 {
03206 return BooleanShrinkProcessor::process<GreaterThan>(image, params);
03207 }
03208
03209
03210 virtual void process_inplace(EMData * image)
03211 {
03212 BooleanShrinkProcessor::process_inplace<GreaterThan>(image, params);
03213 }
03214
03215 string get_desc() const
03216 {
03217 return "Shrink an image by a given amount (default 2), using the maximum value found in the pixel neighborhood.";
03218 }
03219
03220 string get_name() const
03221 {
03222 return NAME;
03223 }
03224 static Processor *NEW()
03225 {
03226 return new MaxShrinkProcessor();
03227 }
03228
03229 TypeDict get_param_types() const
03230 {
03231 TypeDict d;
03232 d.put("n", EMObject::INT, "The shrink factor");
03233 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03234 return d;
03235 }
03236
03237 static const string NAME;
03238
03239 private:
03240 struct GreaterThan
03241 {
03242 inline bool operator()(float left,float right) const { return left > right; }
03243 inline float get_start_val() { return -10000000; }
03244 };
03245 };
03246
03255 class MinShrinkProcessor:public BooleanShrinkProcessor, public Processor
03256 {
03257 public:
03264 virtual EMData* process(const EMData *const image)
03265 {
03266 return BooleanShrinkProcessor::process<LessThan>(image, params);
03267 }
03268
03269
03270 virtual void process_inplace(EMData * image)
03271 {
03272 BooleanShrinkProcessor::process_inplace<LessThan>(image, params);
03273 }
03274 string get_desc() const
03275 {
03276 return "Shrink an image by a given amount (default 2), using the minimum value found in the pixel neighborhood.";
03277 }
03278
03279 string get_name() const
03280 {
03281 return NAME;
03282 }
03283 static Processor *NEW()
03284 {
03285 return new MinShrinkProcessor();
03286 }
03287
03288 TypeDict get_param_types() const
03289 {
03290 TypeDict d;
03291 d.put("n", EMObject::INT, "The shrink factor");
03292 d.put("search", EMObject::INT, "The search area (cubic volume width, usually the same as shrink)");
03293 return d;
03294 }
03295
03296 static const string NAME;
03297
03298 private:
03299 struct LessThan
03300 {
03301 inline bool operator()(float left,float right) const { return left < right; }
03302 inline float get_start_val() { return 9999999999.0f; }
03303 };
03304 };
03305
03312 class MeanShrinkProcessor : public Processor
03313 {
03314 public:
03325 virtual EMData* process(const EMData *const image);
03326
03333 virtual void process_inplace(EMData * image);
03334
03335 string get_desc() const
03336 {
03337 return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
03338 }
03339
03340 virtual string get_name() const
03341 {
03342 return NAME;
03343 }
03344 static Processor *NEW()
03345 {
03346 return new MeanShrinkProcessor();
03347 }
03348
03349 virtual TypeDict get_param_types() const
03350 {
03351 TypeDict d;
03352 d.put("n", EMObject::FLOAT, "The shrink factor");
03353 return d;
03354 }
03355
03356 static const string NAME;
03357
03358 private:
03366 void accrue_mean(EMData* to, const EMData *const from, const int shrinkfactor);
03367
03374 void accrue_mean_one_p_five(EMData* to, const EMData * const from);
03375 };
03376
03377
03384 class MedianShrinkProcessor : public Processor
03385 {
03386 public:
03397 virtual EMData* process(const EMData *const image);
03398
03405 virtual void process_inplace(EMData * image);
03406
03407 string get_desc() const
03408 {
03409 return "Shrink an image by a given amount , using the median value found in the pixel neighborhood.";
03410 }
03411
03412 virtual string get_name() const
03413 {
03414 return NAME;
03415 }
03416 static Processor *NEW()
03417 {
03418 return new MedianShrinkProcessor();
03419 }
03420
03421 virtual TypeDict get_param_types() const
03422 {
03423 TypeDict d;
03424 d.put("n", EMObject::INT, "The shrink factor");
03425 return d;
03426 }
03427
03428 static const string NAME;
03429
03430 private:
03438 void accrue_median(EMData* to, const EMData* const from,const int shrink_factor);
03439 };
03440
03441
03450 class FFTResampleProcessor : public Processor
03451 {
03452 public:
03453 virtual EMData* process(const EMData *const image);
03454
03455 virtual void process_inplace(EMData * image);
03456
03457 string get_desc() const
03458 {
03459 return "Robust resampling of an image by clipping its Fourier transform.";
03460 }
03461
03462 string get_name() const
03463 {
03464 return NAME;
03465 }
03466 static Processor *NEW()
03467 {
03468 return new FFTResampleProcessor();
03469 }
03470
03471 TypeDict get_param_types() const
03472 {
03473 TypeDict d;
03474 d.put("n", EMObject::FLOAT, "The sample rate. Less than one enlarges the image, greater than one shrinks it.");
03475 return d;
03476 }
03477
03478 static const string NAME;
03479
03480 private:
03487 void fft_resample(EMData* to, const EMData *const from, const float& sample_rate);
03488
03489 };
03490
03493 class GradientRemoverProcessor:public Processor
03494 {
03495 public:
03496 void process_inplace(EMData * image);
03497
03498 string get_name() const
03499 {
03500 return NAME;
03501 }
03502 static Processor *NEW()
03503 {
03504 return new GradientRemoverProcessor();
03505 }
03506
03507 string get_desc() const
03508 {
03509 return "Gradient remover, does a rough plane fit to find linear gradients.";
03510 }
03511
03512 static const string NAME;
03513 };
03514
03523 class GradientPlaneRemoverProcessor:public Processor
03524 {
03525 public:
03526 void process_inplace(EMData * image);
03527
03528 string get_name() const
03529 {
03530 return NAME;
03531 }
03532 static Processor *NEW()
03533 {
03534 return new GradientPlaneRemoverProcessor();
03535 }
03536
03537 string get_desc() const
03538 {
03539 return "Remove gradient by least square plane fit";
03540 }
03541
03542 TypeDict get_param_types() const
03543 {
03544 TypeDict d;
03545 d.put("mask", EMObject::EMDATA, "mask object: nonzero pixel positions will be used to fit plane. default = 0");
03546 d.put("changeZero", EMObject::INT, "if zero pixels are modified when removing gradient. default = 0");
03547 d.put("planeParam", EMObject::FLOATARRAY, "fitted plane parameters output");
03548 return d;
03549 }
03550
03551 static const string NAME;
03552 };
03553
03554
03561 class FlattenBackgroundProcessor:public Processor
03562 {
03563 public:
03564 void process_inplace(EMData * image);
03565
03566 string get_name() const
03567 {
03568 return NAME;
03569 }
03570
03571 static Processor *NEW()
03572 {
03573 return new FlattenBackgroundProcessor();
03574 }
03575
03576 string get_desc() const
03577 {
03578 return "Flattens the background by subtracting the local mean";
03579 }
03580
03581 TypeDict get_param_types() const
03582 {
03583 TypeDict d;
03584 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");
03585 d.put("radius", EMObject::INT, "The radius of circle/sphere that defines the local neighborhood. Exclusive of the mask argument");
03586 return d;
03587 }
03588
03589 static const string NAME;
03590 };
03591
03592
03595 class RampProcessor:public Processor
03596 {
03597 public:
03598 void process_inplace(EMData * image);
03599
03600 string get_name() const
03601 {
03602 return NAME;
03603 }
03604 static Processor *NEW()
03605 {
03606 return new RampProcessor();
03607 }
03608
03609 string get_desc() const
03610 {
03611 return "Ramp processor -- Fits a least-squares plane "
03612 "to the picture, and subtracts the plane from "
03613 "the picture. A wedge-shaped overall density "
03614 "profile can thus be removed from the picture.";
03615 }
03616
03617 static const string NAME;
03618 };
03619
03622 class VerticalStripeProcessor:public Processor
03623 {
03624 public:
03625 void process_inplace(EMData * image);
03626
03627 string get_name() const
03628 {
03629 return NAME;
03630 }
03631
03632 static Processor *NEW()
03633 {
03634 return new VerticalStripeProcessor();
03635 }
03636
03637 string get_desc() const
03638 {
03639 return "Tries to fix images scanned on the zeiss for poor ccd normalization.";
03640 }
03641
03642 static const string NAME;
03643 };
03644
03647 class RealToFFTProcessor:public Processor
03648 {
03649 public:
03650 void process_inplace(EMData *image);
03651
03652 string get_name() const
03653 {
03654 return NAME;
03655 }
03656
03657 static Processor *NEW()
03658 {
03659 return new RealToFFTProcessor();
03660 }
03661
03662 string get_desc() const
03663 {
03664 return "This will replace the image with a full-circle 2D fft amplitude rendering. Note that this renders amplitude, when intensity is more common.";
03665 }
03666
03667 static const string NAME;
03668 };
03669
03670
03673 class SigmaZeroEdgeProcessor:public Processor
03674 {
03675 public:
03676 void process_inplace(EMData * image);
03677
03678 string get_name() const
03679 {
03680 return NAME;
03681 }
03682 static Processor *NEW()
03683 {
03684 return new SigmaZeroEdgeProcessor();
03685 }
03686
03687 string get_desc() const
03688 {
03689 return "Fill zeroes at edges with nearest horizontal/vertical value.";
03690 }
03691
03692 static const string NAME;
03693 };
03694
03700 class BeamstopProcessor:public Processor
03701 {
03702 public:
03703 void process_inplace(EMData * image);
03704
03705 string get_name() const
03706 {
03707 return NAME;
03708 }
03709
03710 static Processor *NEW()
03711 {
03712 return new BeamstopProcessor();
03713 }
03714
03715 string get_desc() const
03716 {
03717 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.";
03718 }
03719
03720 TypeDict get_param_types() const
03721 {
03722 TypeDict d;
03723 d.put("value1", EMObject::FLOAT, "sig multiplier");
03724 d.put("value2", EMObject::FLOAT, "x of center");
03725 d.put("value3", EMObject::FLOAT, "y of center");
03726 return d;
03727 }
03728
03729 static const string NAME;
03730 };
03731
03734 class MeanZeroEdgeProcessor:public Processor
03735 {
03736 public:
03737 void process_inplace(EMData * image);
03738
03739 string get_name() const
03740 {
03741 return NAME;
03742 }
03743
03744 static Processor *NEW()
03745 {
03746 return new MeanZeroEdgeProcessor();
03747 }
03748
03749 string get_desc() const
03750 {
03751 return "Fill zeroes at edges with nearest horizontal/vertical value damped towards Mean2.";
03752 }
03753
03754 static const string NAME;
03755 };
03756
03757
03760 class AverageXProcessor:public Processor
03761 {
03762 public:
03763 void process_inplace(EMData * image);
03764
03765 string get_name() const
03766 {
03767 return NAME;
03768 }
03769
03770 static Processor *NEW()
03771 {
03772 return new AverageXProcessor();
03773 }
03774
03775 string get_desc() const
03776 {
03777 return "Average along Y and replace with average";
03778 }
03779
03780 static const string NAME;
03781 };
03782
03786 class DecayEdgeProcessor:public Processor
03787 {
03788 public:
03789 void process_inplace(EMData * image);
03790 string get_name() const
03791 {
03792 return NAME;
03793 }
03794
03795 static Processor *NEW()
03796 {
03797 return new DecayEdgeProcessor();
03798 }
03799
03800 string get_desc() const
03801 {
03802 return "Decay edges of image to zero";
03803 }
03804
03805 TypeDict get_param_types() const
03806 {
03807 TypeDict d;
03808 d.put("width", EMObject::INT, "Width of the decay region around the edge of the image in pixels");
03809 return d;
03810 }
03811
03812 static const string NAME;
03813 };
03814
03821 class ZeroEdgeRowProcessor:public Processor
03822 {
03823 public:
03824 void process_inplace(EMData * image);
03825 string get_name() const
03826 {
03827 return NAME;
03828 }
03829
03830 static Processor *NEW()
03831 {
03832 return new ZeroEdgeRowProcessor();
03833 }
03834
03835 string get_desc() const
03836 {
03837 return "zero edges of image on top and bottom, and on left and right.";
03838 }
03839
03840 TypeDict get_param_types() const
03841 {
03842 TypeDict d;
03843 d.put("x0", EMObject::INT, "The number of columns to zero from left");
03844 d.put("x1", EMObject::INT, "The number of columns to zero from right");
03845 d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
03846 d.put("y1", EMObject::INT, "The number of rows to zero from the top");
03847 return d;
03848 }
03849
03850 static const string NAME;
03851 };
03852
03861 class ZeroEdgePlaneProcessor:public Processor
03862 {
03863 public:
03864 void process_inplace(EMData * image);
03865 string get_name() const
03866 {
03867 return NAME;
03868 }
03869
03870 static Processor *NEW()
03871 {
03872 return new ZeroEdgePlaneProcessor();
03873 }
03874
03875 string get_desc() const
03876 {
03877 return "zero edges of volume on all sides";
03878 }
03879
03880 TypeDict get_param_types() const
03881 {
03882 TypeDict d;
03883 d.put("x0", EMObject::INT, "The number of columns to zero from left");
03884 d.put("x1", EMObject::INT, "The number of columns to zero from right");
03885 d.put("y0", EMObject::INT, "The number of rows to zero from the bottom");
03886 d.put("y1", EMObject::INT, "The number of rows to zero from the top");
03887 d.put("z0", EMObject::INT, "The number of slices to zero from the bottom");
03888 d.put("z1", EMObject::INT, "The number of slices to zero from the top");
03889 return d;
03890 }
03891
03892 static const string NAME;
03893 };
03894
03895
03902 class BilateralProcessor:public Processor
03903 {
03904 public:
03905 void process_inplace(EMData * image);
03906 string get_name() const
03907 {
03908 return NAME;
03909 }
03910
03911 string get_desc() const
03912 {
03913 return "Bilateral processing on 2D or 3D volume data. Bilateral processing does non-linear weighted averaging processing within a certain window. ";
03914 }
03915
03916 static Processor *NEW()
03917 {
03918 return new BilateralProcessor();
03919 }
03920
03921 TypeDict get_param_types() const
03922 {
03923 TypeDict d;
03924 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.");
03925 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.");
03926 d.put("niter", EMObject::INT, "how many times to apply this processing on your data.");
03927 d.put("half_width", EMObject::INT, "processing window size = (2 * half_widthh + 1) ^ 3.");
03928 return d;
03929 }
03930
03931 static const string NAME;
03932 };
03933
03936 class NormalizeProcessor:public Processor
03937 {
03938 public:
03939 void process_inplace(EMData * image);
03940
03941 static string get_group_desc()
03942 {
03943 return "Base class for normalization processors. Each specific normalization processor needs to define how to calculate mean and how to calculate sigma.";
03944 }
03945
03946 protected:
03947 virtual float calc_sigma(EMData * image) const;
03948 virtual float calc_mean(EMData * image) const = 0;
03949 };
03950
03953 class NormalizeUnitProcessor:public NormalizeProcessor
03954 {
03955 public:
03956 string get_name() const
03957 {
03958 return NAME;
03959 }
03960
03961 static Processor *NEW()
03962 {
03963 return new NormalizeUnitProcessor();
03964 }
03965
03966 string get_desc() const
03967 {
03968 return "Normalize an image so its vector length is 1.0.";
03969 }
03970
03971 static const string NAME;
03972
03973 protected:
03974 float calc_sigma(EMData * image) const;
03975 float calc_mean(EMData * image) const;
03976 };
03977
03978 inline float NormalizeUnitProcessor::calc_mean(EMData *) const { return 0; }
03979
03982 class NormalizeUnitSumProcessor:public NormalizeProcessor
03983 {
03984 public:
03985 string get_name() const
03986 {
03987 return NAME;
03988 }
03989
03990 static Processor *NEW()
03991 {
03992 return new NormalizeUnitSumProcessor();
03993 }
03994
03995 string get_desc() const
03996 {
03997 return "Normalize an image so its elements sum to 1.0 (fails if mean=0)";
03998 }
03999
04000 static const string NAME;
04001
04002 protected:
04003 float calc_sigma(EMData * image) const;
04004 float calc_mean(EMData * image) const;
04005 };
04006
04007 inline float NormalizeUnitSumProcessor::calc_mean(EMData *) const { return 0; }
04008
04009
04012 class NormalizeStdProcessor:public NormalizeProcessor
04013 {
04014 public:
04015 string get_name() const
04016 {
04017 return NAME;
04018 }
04019
04020 static Processor *NEW()
04021 {
04022 return new NormalizeStdProcessor();
04023 }
04024
04025 string get_desc() const
04026 {
04027 return "do a standard normalization on an image.";
04028 }
04029
04030 static const string NAME;
04031
04032 protected:
04033 float calc_mean(EMData * image) const;
04034 };
04035
04040 class NormalizeMaskProcessor:public NormalizeProcessor
04041 {
04042 public:
04043 string get_name() const
04044 {
04045 return NAME;
04046 }
04047
04048 string get_desc() const
04049 {
04050 return "Uses a 1/0 mask defining a region to use for the zero-normalization.if no_sigma is 1, standard deviation not modified.";
04051 }
04052
04053 static Processor *NEW()
04054 {
04055 return new NormalizeMaskProcessor();
04056 }
04057
04058 TypeDict get_param_types() const
04059 {
04060 TypeDict d;
04061 d.put("mask", EMObject::EMDATA, "the 1/0 mask defining a region to use for the zero-normalization");
04062 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");
04063 return d;
04064 }
04065
04066 static const string NAME;
04067
04068 protected:
04069 float calc_sigma(EMData * image) const;
04070 float calc_mean(EMData * image) const;
04071 };
04072
04078 class NormalizeRampNormVar: public Processor
04079 {
04080 public:
04081 string get_name() const
04082 {
04083 return NAME;
04084 }
04085
04086 static Processor *NEW()
04087 {
04088 return new NormalizeRampNormVar();
04089 }
04090
04091 string get_desc() const
04092 {
04093 return "First call filter.ramp on the image, then make the mean 0 and norm 1";
04094 }
04095
04096 void process_inplace(EMData * image);
04097
04098 static const string NAME;
04099 };
04100
04109 class NormalizeByMassProcessor: public Processor
04110 {
04111 public:
04112 string get_name() const
04113 {
04114 return NAME;
04115 }
04116
04117 static Processor *NEW()
04118 {
04119 return new NormalizeByMassProcessor();
04120 }
04121
04122 string get_desc() const
04123 {
04124 return "Normalize the mass of the image assuming a density of 1.35 g/ml (0.81 Da/A^3) (3D only)";
04125 }
04126
04127 TypeDict get_param_types() const
04128 {
04129 TypeDict d;
04130 d.put("apix", EMObject::FLOAT,"Angstrom per pixel of the image. If not set will use the apix_x attribute of the image");
04131 d.put("mass", EMObject::FLOAT,"The approximate mass of protein/structure in kilodaltons");
04132 d.put("thr", EMObject::FLOAT,"The isosurface threshold which encapsulates the structure");
04133 return d;
04134 }
04135
04136 void process_inplace(EMData * image);
04137
04138 static const string NAME;
04139 };
04140
04141
04144 class NormalizeEdgeMeanProcessor:public NormalizeProcessor
04145 {
04146 public:
04147 string get_name() const
04148 {
04149 return NAME;
04150 }
04151
04152 static Processor *NEW()
04153 {
04154 return new NormalizeEdgeMeanProcessor();
04155 }
04156
04157 string get_desc() const
04158 {
04159 return "normalizes an image, mean value equals to edge mean.";
04160 }
04161
04162 static const string NAME;
04163
04164 protected:
04165 float calc_mean(EMData * image) const;
04166 };
04167
04170 class NormalizeCircleMeanProcessor:public NormalizeProcessor
04171 {
04172 public:
04173 string get_name() const
04174 {
04175 return NAME;
04176 }
04177
04178 static Processor *NEW()
04179 {
04180 return new NormalizeCircleMeanProcessor();
04181 }
04182
04183 string get_desc() const
04184 {
04185 return "normalizes an image, mean value equals to mean of 2 pixel circular border.";
04186 }
04187
04188 static const string NAME;
04189
04190 protected:
04191 float calc_mean(EMData * image) const;
04192 };
04193
04196 class NormalizeLREdgeMeanProcessor:public NormalizeProcessor
04197 {
04198 public:
04199 string get_name() const
04200 {
04201 return NAME;
04202 }
04203
04204 static Processor *NEW()
04205 {
04206 return new NormalizeLREdgeMeanProcessor();
04207 }
04208
04209 string get_desc() const
04210 {
04211 return "normalizes an image, uses 2 pixels on left and right edge";
04212 }
04213
04214 static const string NAME;
04215
04216 protected:
04217 float calc_mean(EMData * image) const;
04218 };
04219
04222 class NormalizeMaxMinProcessor:public NormalizeProcessor
04223 {
04224 public:
04225 string get_name() const
04226 {
04227 return NAME;
04228 }
04229
04230 static Processor *NEW()
04231 {
04232 return new NormalizeMaxMinProcessor();
04233 }
04234
04235 string get_desc() const
04236 {
04237 return "normalizes an image. mean -> (maxval-minval)/2; std dev = (maxval+minval)/2;";
04238 }
04239
04240 static const string NAME;
04241
04242 protected:
04243 float calc_sigma(EMData * image) const;
04244 float calc_mean(EMData * image) const;
04245 };
04246
04249 class NormalizeRowProcessor:public Processor
04250 {
04251 public:
04252 string get_name() const
04253 {
04254 return NAME;
04255 }
04256
04257 static Processor *NEW()
04258 {
04259 return new NormalizeRowProcessor();
04260 }
04261
04262 string get_desc() const
04263 {
04264 return "normalizes each row in the image individually";
04265 }
04266
04267 static const string NAME;
04268
04269 void process_inplace(EMData * image);
04270 };
04271
04277 class NormalizeToLeastSquareProcessor:public Processor
04278 {
04279 public:
04280 void process_inplace(EMData * image);
04281
04282 string get_name() const
04283 {
04284 return NAME;
04285 }
04286
04287 static Processor *NEW()
04288 {
04289 return new NormalizeToLeastSquareProcessor();
04290 }
04291
04292 TypeDict get_param_types() const
04293 {
04294 TypeDict d;
04295 d.put("to", EMObject::EMDATA, "reference image normalize to");
04296 d.put("ignore_zero", EMObject::BOOL, "If set, ignores any pixels which are exactly zero in either image. Defaut = True.");
04297 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)");
04298 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)");
04299 return d;
04300 }
04301
04302 string get_desc() const
04303 {
04304 return "use least square method to normalize";
04305 }
04306
04307 static const string NAME;
04308 };
04309
04312 class RotationalAverageProcessor:public Processor
04313 {
04314 public:
04315 void process_inplace(EMData * image);
04316
04317 string get_name() const
04318 {
04319 return NAME;
04320 }
04321
04322 static Processor *NEW()
04323 {
04324 return new RotationalAverageProcessor();
04325 }
04326
04327 string get_desc() const
04328 {
04329 return "Makes image circularly/spherically symmetric.";
04330 }
04331
04332 static const string NAME;
04333 };
04334
04337 class RotationalSubstractProcessor:public Processor
04338 {
04339 public:
04340 virtual void process_inplace(EMData * image);
04341
04342 virtual string get_name() const
04343 {
04344 return NAME;
04345 }
04346
04347 static Processor *NEW()
04348 {
04349 return new RotationalSubstractProcessor();
04350 }
04351
04352 virtual string get_desc() const
04353 {
04354 return "subtracts circularly/spherically symmetric part of an image.";
04355 }
04356
04357 static const string NAME;
04358 };
04359
04365 class TransposeProcessor:public Processor
04366 {
04367 public:
04368
04373 virtual void process_inplace(EMData * image);
04374
04379 virtual EMData* process(const EMData * const image);
04380
04381 virtual string get_name() const
04382 {
04383 return NAME;
04384 }
04385
04386 static Processor *NEW()
04387 {
04388 return new TransposeProcessor();
04389 }
04390
04391 virtual TypeDict get_param_types() const
04392 {
04393 TypeDict d;
04394 return d;
04395 }
04396
04397 virtual string get_desc() const
04398 {
04399 return "Get the transpose of an image. Works for 2D only";
04400 }
04401
04402 static const string NAME;
04403 };
04404
04405
04409 class FlipProcessor:public Processor
04410 {
04411 public:
04412 virtual void process_inplace(EMData * image);
04413
04414 virtual string get_name() const
04415 {
04416 return NAME;
04417 }
04418
04419 static Processor *NEW()
04420 {
04421 return new FlipProcessor();
04422 }
04423
04424 virtual TypeDict get_param_types() const
04425 {
04426 TypeDict d;
04427 d.put("axis", EMObject::STRING, "'x', 'y', or 'z' axis. 'x' means horizonal flip; 'y' means vertical flip;");
04428 return d;
04429 }
04430
04431 virtual string get_desc() const
04432 {
04433 return "flip an image around an axis.";
04434 }
04435
04436 static const string NAME;
04437 };
04438
04439
04440
04441
04442
04443
04444
04445
04446
04447
04448
04449
04450
04451
04452
04453
04454
04455
04456
04457
04458
04459
04460
04461
04462
04463
04464
04465
04466
04467
04472 class AddNoiseProcessor:public Processor
04473 {
04474 public:
04475 virtual void process_inplace(EMData * image);
04476
04477 virtual string get_name() const
04478 {
04479 return NAME;
04480 }
04481
04482 static Processor *NEW()
04483 {
04484 return new AddNoiseProcessor();
04485 }
04486
04487 virtual TypeDict get_param_types() const
04488 {
04489 TypeDict d;
04490 d.put("noise", EMObject::FLOAT, "noise factor used to generate Gaussian distribution random noise");
04491 d.put("seed", EMObject::INT, "seed for random number generator");
04492 return d;
04493 }
04494
04495 virtual string get_desc() const
04496 {
04497 return "add noise to an image, image multiply by noise then add a random value";
04498 }
04499
04500 static const string NAME;
04501
04502 protected:
04503 virtual float get_sigma(EMData *)
04504 {
04505 return 1.0;
04506 }
04507 };
04508
04511 class AddSigmaNoiseProcessor:public AddNoiseProcessor
04512 {
04513 public:
04514 virtual string get_name() const
04515 {
04516 return NAME;
04517 }
04518
04519 static Processor *NEW()
04520 {
04521 return new AddSigmaNoiseProcessor();
04522 }
04523
04524 virtual string get_desc() const
04525 {
04526 return "add sigma noise.";
04527 }
04528
04529 static const string NAME;
04530
04531 protected:
04532 float get_sigma(EMData * image);
04533 };
04534
04543 class AddRandomNoiseProcessor:public Processor
04544 {
04545 public:
04546 virtual void process_inplace(EMData * image);
04547
04548 virtual string get_name() const
04549 {
04550 return NAME;
04551 }
04552
04553 static Processor *NEW()
04554 {
04555 return new AddRandomNoiseProcessor();
04556 }
04557
04558 virtual TypeDict get_param_types() const
04559 {
04560 TypeDict d;
04561 d.put("n", EMObject::INT);
04562 d.put("x0", EMObject::FLOAT);
04563 d.put("dx", EMObject::FLOAT);
04564 d.put("y", EMObject::FLOATARRAY);
04565 d.put("interpolation", EMObject::INT);
04566 d.put("seed", EMObject::INT, "seed for random number generator");
04567 return d;
04568 }
04569
04570 virtual string get_desc() const
04571 {
04572 return "add spectral noise to a complex image.";
04573 }
04574
04575 static const string NAME;
04576 };
04577
04583 class FourierToCornerProcessor:public Processor
04584 {
04585 public:
04591 virtual void process_inplace(EMData * image);
04592
04593 virtual string get_name() const
04594 {
04595 return NAME;
04596 }
04597
04598 static Processor *NEW()
04599 {
04600 return new FourierToCornerProcessor();
04601 }
04602
04603 virtual string get_desc() const
04604 {
04605 return "Undoes the xform.fourierorigin.tocenter processor";
04606 }
04607
04608 static const string NAME;
04609 };
04610
04611
04623 class FourierToCenterProcessor:public Processor
04624 {
04625 public:
04631 virtual void process_inplace(EMData * image);
04632
04633 virtual string get_name() const
04634 {
04635 return NAME;
04636 }
04637
04638 static Processor *NEW()
04639 {
04640 return new FourierToCenterProcessor();
04641 }
04642
04643 virtual string get_desc() const
04644 {
04645 return "Translates the origin in Fourier space from the corner to the center in y and z - works in 2D and 3D";
04646 }
04647
04648 static const string NAME;
04649 };
04650
04660 class Phase180Processor:public Processor
04661 {
04662 protected:
04675 void swap_corners_180(EMData * image);
04676
04688 void swap_central_slices_180(EMData * image);
04689
04696 void fourier_phaseshift180(EMData * image);
04697
04698 };
04699
04709 class PhaseToCenterProcessor:public Phase180Processor
04710 {
04711 public:
04712 virtual void process_inplace(EMData * image);
04713
04714 virtual string get_name() const
04715 {
04716 return NAME;
04717 }
04718
04719 static Processor *NEW()
04720 {
04721 return new PhaseToCenterProcessor();
04722 }
04723
04724 virtual string get_desc() const
04725 {
04726 return "Undoes the effect of the xform.phaseorigin.tocorner processor";
04727 }
04728
04729 static const string NAME;
04730 };
04731
04739 class PhaseToCornerProcessor:public Phase180Processor
04740 {
04741 public:
04742 virtual void process_inplace(EMData * image);
04743
04744 virtual string get_name() const
04745 {
04746 return NAME;
04747 }
04748
04749 static Processor *NEW()
04750 {
04751 return new PhaseToCornerProcessor();
04752 }
04753
04754 virtual string get_desc() const
04755 {
04756 return "Translates a centered image to the corner in a forward fashion";
04757 }
04758
04759 static const string NAME;
04760 };
04761
04766 class AutoMask2DProcessor:public Processor
04767 {
04768 public:
04769 virtual void process_inplace(EMData * image);
04770
04771 virtual string get_name() const
04772 {
04773 return NAME;
04774 }
04775
04776 static Processor *NEW()
04777 {
04778 return new AutoMask2DProcessor();
04779 }
04780
04781 virtual TypeDict get_param_types() const
04782 {
04783 TypeDict d;
04784 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
04785 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
04786 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
04787 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
04788 d.put("nshells", EMObject::INT, "The number of dilation operations");
04789 d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
04790 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
04791 d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
04792 return d;
04793 }
04794
04795 virtual string get_desc() const
04796 {
04797 return "2D version of mask.auto3d";
04798 }
04799
04800 static const string NAME;
04801 };
04802
04803
04810 class AutoMaskAsymUnit:public Processor
04811 {
04812 public:
04813 virtual void process_inplace(EMData * image);
04814
04815 virtual string get_name() const
04816 {
04817 return NAME;
04818 }
04819
04820 static Processor *NEW()
04821 {
04822 return new AutoMaskAsymUnit();
04823 }
04824
04825 virtual TypeDict get_param_types() const
04826 {
04827 TypeDict d;
04828 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.");
04829 d.put("sym", EMObject::STRING, "The symmetry, for example, d7");
04830 return d;
04831 }
04832
04833 virtual string get_desc() const
04834 {
04835 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.";
04836 }
04837
04838 static const string NAME;
04839 };
04840
04845 class AutoMask3DProcessor:public Processor
04846 {
04847 public:
04848 virtual void process_inplace(EMData * image);
04849
04850 virtual string get_name() const
04851 {
04852 return NAME;
04853 }
04854
04855 static Processor *NEW()
04856 {
04857 return new AutoMask3DProcessor();
04858 }
04859
04860 virtual TypeDict get_param_types() const
04861 {
04862 TypeDict d;
04863 d.put("threshold1", EMObject::FLOAT);
04864 d.put("threshold2", EMObject::FLOAT);
04865 return d;
04866 }
04867
04868 virtual string get_desc() const
04869 {
04870 return "Tries to mask out only interesting density";
04871 }
04872
04873 static void search_nearby(float *dat, float *dat2, int nx, int ny, int nz, float thr);
04874 static void fill_nearby(float *dat2, int nx, int ny, int nz);
04875
04876 static const string NAME;
04877 };
04878
04886 class AutoMask3D2Processor:public Processor
04887 {
04888 public:
04889 virtual void process_inplace(EMData * image);
04890
04891 virtual string get_name() const
04892 {
04893 return NAME;
04894 }
04895
04896 static Processor *NEW()
04897 {
04898 return new AutoMask3D2Processor();
04899 }
04900
04901 virtual string get_desc() const
04902 {
04903 return "Tries to mask out only interesting density using something akin to a flood file approach.";
04904 }
04905
04906 virtual TypeDict get_param_types() const
04907 {
04908 TypeDict d;
04909 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
04910 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
04911 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
04912 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
04913 d.put("nshells", EMObject::INT, "The number of dilation operations");
04914 d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
04915 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
04916 d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
04917 return d;
04918 }
04919
04920 static const string NAME;
04921 };
04922
04926 class AddMaskShellProcessor:public Processor
04927 {
04928 public:
04929 virtual void process_inplace(EMData * image);
04930
04931 virtual string get_name() const
04932 {
04933 return NAME;
04934 }
04935
04936 virtual string get_desc() const
04937 {
04938 return "Add additional shells/rings to an existing 1/0 mask image";
04939 }
04940
04941 static Processor *NEW()
04942 {
04943 return new AddMaskShellProcessor();
04944 }
04945
04946 virtual TypeDict get_param_types() const
04947 {
04948 TypeDict d;
04949 d.put("nshells", EMObject::INT, "number of shells to add");
04950 return d;
04951 }
04952
04953 static const string NAME;
04954 };
04955
04960 class PhaseToMassCenterProcessor:public Processor
04961 {
04962 public:
04963 virtual void process_inplace(EMData * image);
04964
04965 virtual string get_name() const
04966 {
04967 return NAME;
04968 }
04969
04970 static Processor *NEW()
04971 {
04972 return new PhaseToMassCenterProcessor();
04973 }
04974
04975 virtual string get_desc() const
04976 {
04977 return "centers the image the center of mass, which is calculated using Fourier phases, ignores old dx, dy.";
04978 }
04979
04980 virtual TypeDict get_param_types() const
04981 {
04982 TypeDict d;
04983 d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
04984 return d;
04985 }
04986
04987 static const string NAME;
04988 };
04989
04994 class ToMassCenterProcessor:public Processor
04995 {
04996 public:
04997 virtual void process_inplace(EMData * image);
04998
04999 virtual string get_name() const
05000 {
05001 return NAME;
05002 }
05003
05004 static Processor *NEW()
05005 {
05006 return new ToMassCenterProcessor();
05007 }
05008
05009 virtual string get_desc() const
05010 {
05011 return "ToMassCenterProcessor centers image at center of mass, with a threshold. Only values higher than the threshold are considered.";
05012 }
05013
05014 virtual TypeDict get_param_types() const
05015 {
05016 TypeDict d;
05017 d.put("int_shift_only", EMObject::INT, "set to 1 only shift by integer, no interpolation");
05018 d.put("threshold", EMObject::FLOAT, "Only values larger than the threshold are included in the center of mass computation. Default is 0.");
05019
05020 return d;
05021 }
05022
05023 static const string NAME;
05024 };
05025
05029 class ACFCenterProcessor:public Processor
05030 {
05031 public:
05032 virtual void process_inplace(EMData * image);
05033
05034 virtual string get_name() const
05035 {
05036 return NAME;
05037 }
05038
05039 static Processor *NEW()
05040 {
05041 return new ACFCenterProcessor();
05042 }
05043
05044 virtual string get_desc() const
05045 {
05046 return "Center image using self-convolution.";
05047 }
05048
05049 virtual TypeDict get_param_types() const
05050 {
05051 TypeDict d;
05052 return d;
05053 }
05054
05055 static const string NAME;
05056 };
05057
05062 class SNRProcessor:public Processor
05063 {
05064 public:
05065 virtual void process_inplace(EMData * image);
05066
05067 virtual string get_name() const
05068 {
05069 return NAME;
05070 }
05071
05072 static Processor *NEW()
05073 {
05074 return new SNRProcessor();
05075 }
05076
05077 virtual string get_desc() const
05078 {
05079 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.";
05080 }
05081
05082 virtual TypeDict get_param_types() const
05083 {
05084 TypeDict d;
05085 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");
05086 d.put("snrfile", EMObject::STRING, "structure factor file name");
05087 return d;
05088 }
05089
05090 static const string NAME;
05091 };
05092
05096 class FileFourierProcessor:public Processor
05097 {
05098 public:
05099 virtual void process_inplace(EMData * image);
05100
05101 virtual string get_name() const
05102 {
05103 return NAME;
05104 }
05105
05106 virtual string get_desc() const
05107 {
05108 return "A fourier processor specified in a 2 column text file.";
05109 }
05110
05111 static Processor *NEW()
05112 {
05113 return new FileFourierProcessor();
05114 }
05115
05116 virtual TypeDict get_param_types() const
05117 {
05118 TypeDict d;
05119 d.put("filename", EMObject::STRING, "file name for a 2 column text file which specified a radial function data array.");
05120 return d;
05121 }
05122
05123 static const string NAME;
05124 };
05125
05136 class SymSearchProcessor:public Processor
05137 {
05138 public:
05139 virtual void process_inplace(EMData * image);
05140
05141 virtual string get_name() const
05142 {
05143 return NAME;
05144 }
05145
05146 virtual string get_desc() const
05147 {
05148 return "Identifiy the best symmetry in the given symmetry list for each pixel and then apply the best symmetry to each pixel.";
05149 }
05150
05151 static Processor *NEW()
05152 {
05153 return new SymSearchProcessor();
05154 }
05155
05156 virtual TypeDict get_param_types() const
05157 {
05158 TypeDict d;
05159 d.put("sym", EMObject::STRINGARRAY, "the list of symmetries to search");
05160 d.put("thresh", EMObject::FLOAT, "the minimal level of symmetry to be accepted (0-1)");
05161 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");
05162 d.put("symlabel_map", EMObject::EMDATA, "the optional return map when output_symlabel=1");
05163 return d;
05164 }
05165
05166 static const string NAME;
05167 };
05168
05174 class LocalNormProcessor:public Processor
05175 {
05176 public:
05177 void process_inplace(EMData * image);
05178
05179 virtual string get_name() const
05180 {
05181 return NAME;
05182 }
05183
05184 static Processor *NEW()
05185 {
05186 return new LocalNormProcessor();
05187 }
05188
05189 virtual string get_desc() const
05190 {
05191 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.";
05192 }
05193
05194 virtual TypeDict get_param_types() const
05195 {
05196 TypeDict d;
05197 d.put("threshold", EMObject::FLOAT, "an isosurface threshold at which all desired features are visible");
05198 d.put("radius", EMObject::FLOAT, "a normalization size similar to an lp= value");
05199 d.put("apix", EMObject::FLOAT, "Angstrom per pixel ratio");
05200 return d;
05201 }
05202
05203 static const string NAME;
05204 };
05205
05210 class IndexMaskFileProcessor:public Processor
05211 {
05212 public:
05213 virtual void process_inplace(EMData * image);
05214
05215 virtual string get_name() const
05216 {
05217 return NAME;
05218 }
05219
05220 static Processor *NEW()
05221 {
05222 return new IndexMaskFileProcessor();
05223 }
05224
05225 virtual TypeDict get_param_types() const
05226 {
05227 TypeDict d;
05228 d.put("filename", EMObject::STRING, "mask image file name");
05229 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");
05230 return d;
05231 }
05232
05233 virtual string get_desc() const
05234 {
05235 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.";
05236 }
05237
05238 static const string NAME;
05239 };
05240
05244 class CoordinateMaskFileProcessor:public Processor
05245 {
05246 public:
05247 virtual void process_inplace(EMData * image);
05248
05249 virtual string get_name() const
05250 {
05251 return NAME;
05252 }
05253
05254 static Processor *NEW()
05255 {
05256 return new CoordinateMaskFileProcessor();
05257 }
05258
05259 virtual string get_desc() const
05260 {
05261 return "Multiplies the image by the specified file using pixel coordinates instead of pixel indices. The images can be different size.";
05262 }
05263
05264 virtual TypeDict get_param_types() const
05265 {
05266 TypeDict d;
05267 d.put("filename", EMObject::STRING, "mask image file name");
05268 return d;
05269 }
05270
05271 static const string NAME;
05272 };
05273
05284 class PaintProcessor:public Processor
05285 {
05286 public:
05287 PaintProcessor():x(0), y(0), z(0),r1(0), v1(0.0), r2(0), v2(0.0)
05288 {
05289 }
05290
05291 virtual string get_name() const
05292 {
05293 return NAME;
05294 }
05295
05296 static Processor *NEW()
05297 {
05298 return new PaintProcessor();
05299 }
05300
05301 virtual string get_desc() const
05302 {
05303 return "Paints a circle with a decaying edge into the image. r<r1 -> v1, r1<r<r2 -> (v1,v2), r>r2 unchanged";
05304 }
05305
05306 virtual TypeDict get_param_types() const
05307 {
05308 TypeDict d;
05309 d.put("x", EMObject::INT, "x coordinate for Center of circle");
05310 d.put("y", EMObject::INT, "y coordinate for Center of circle");
05311 d.put("z", EMObject::INT, "z coordinate for Center of circle");
05312 d.put("r1", EMObject::INT, "Inner radius");
05313 d.put("v1", EMObject::FLOAT, "Inner value");
05314 d.put("r2", EMObject::INT, "Outter radius");
05315 d.put("v2", EMObject::FLOAT, "Outer Value");
05316 return d;
05317 }
05318
05319 virtual void set_params(const Dict & new_params)
05320 {
05321 params = new_params;
05322
05323 if (params.has_key("x")) x = params["x"];
05324 if (params.has_key("y")) y = params["y"];
05325 if (params.has_key("z")) z = params["z"];
05326 if (params.has_key("r1")) r1 = params["r1"];
05327 if (params.has_key("r2")) r2 = params["r2"];
05328 if (params.has_key("v1")) v1 = params["v1"];
05329 if (params.has_key("v2")) v2 = params["v2"];
05330 }
05331
05332 static const string NAME;
05333
05334 protected:
05335 virtual void process_inplace(EMData *image);
05336
05337 int x,y,z,r1;
05338 float v1;
05339 int r2;
05340 float v2;
05341
05342 };
05343
05344
05349 class DirectionalSumProcessor : public Processor
05350 {
05351 public:
05352 virtual string get_name() const
05353 {
05354 return NAME;
05355 }
05356
05357 static Processor *NEW()
05358 {
05359 return new DirectionalSumProcessor();
05360 }
05361
05365 virtual EMData* process(const EMData* const image);
05366
05370 virtual void process_inplace(EMData*) {
05371 throw InvalidCallException("The directional sum processor does not work inplace");
05372 }
05373
05374 virtual TypeDict get_param_types() const
05375 {
05376 TypeDict d;
05377 d.put("axis", EMObject::STRING,"The direction of the sum, either x,y or z. Returned axes are xy, xz or zy.");
05378 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)");
05379 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)");
05380 return d;
05381 }
05382
05383 string get_desc() const
05384 {
05385 return "Calculates the projection of the image along one of the axial directions, either x, y or z";
05386 }
05387
05388 static const string NAME;
05389 };
05390
05398 class WatershedProcessor:public Processor
05399 {
05400 public:
05401 virtual void process_inplace(EMData * image);
05402
05403 virtual string get_name() const
05404 {
05405 return NAME;
05406 }
05407
05408 static Processor *NEW()
05409 {
05410 return new WatershedProcessor();
05411 }
05412
05413 virtual string get_desc() const
05414 {
05415 return "Does a watershed";
05416 }
05417
05418 virtual TypeDict get_param_types() const
05419 {
05420 TypeDict d;
05421 d.put("xpoints", EMObject::FLOATARRAY,"x coordinates");
05422 d.put("ypoints", EMObject::FLOATARRAY,"y coordinates");
05423 d.put("zpoints", EMObject::FLOATARRAY,"z coordinates");
05424 d.put("minval", EMObject::FLOAT,"min value");
05425 return d;
05426 }
05427
05428 static const string NAME;
05429
05430 private:
05431 vector<Vec3i > watershed(EMData* mask, EMData* image, const float& threshold, const Vec3i& cordinate, const int mask_value);
05432 vector<Vec3i > find_region(EMData* mask,const vector<Vec3i >& coords, const int mask_value, vector<Vec3i >& region);
05433
05434 };
05435
05445 template<class Type>
05446 class BinaryOperateProcessor : public Processor{
05447 public:
05452 virtual void process_inplace(EMData * image) {
05453 if ( ! params.has_key("with") ) throw InvalidParameterException("You must supply the \"with\" parameter");
05454 EMData* with = params["with"];
05455
05456 if ( with->get_xsize() != image->get_xsize() || with->get_ysize() != image->get_ysize() || with->get_zsize() != image->get_zsize() )
05457 throw ImageDimensionException("The images you are operating on do not have the same dimensions");
05458
05459 float* image_data = image->get_data();
05460 float* with_data = with->get_data();
05461
05462 std::transform(image_data,image_data+image->get_size(),with_data,image_data,Type::binary_operate);
05463 image->update();
05464 }
05465
05466 virtual string get_name() const
05467 {
05468 return op.get_name();
05469 }
05470
05471 virtual string get_desc() const
05472 {
05473 return op.get_desc();
05474 }
05475
05476 static Processor *NEW()
05477 {
05478 return new BinaryOperateProcessor<Type>();
05479 }
05480
05481 virtual TypeDict get_param_types() const
05482 {
05483 TypeDict d;
05484 d.put("with", EMObject::EMDATA,"The second image");
05485 return d;
05486 }
05487
05488 static const string NAME;
05489 private:
05490 Type op;
05491 };
05492
05493 class MaxPixelOperator {
05494 public:
05495 string get_name() const
05496 {
05497 return NAME;
05498 }
05499
05500 string get_desc() const
05501 {
05502 return "Compares pixels in two images, returning an image with the maximum pixel value in each pixel location";
05503 }
05504
05505 static float binary_operate(const float& left, const float& right) {
05506 if (left > right) return left;
05507 return right;
05508 }
05509
05510 static const string NAME;
05511 };
05512
05513 class MinPixelOperator {
05514 public:
05515 string get_name() const
05516 {
05517 return NAME;
05518 }
05519
05520 string get_desc() const
05521 {
05522 return "Compares pixels in two images, returning an image with the minimum pixel value in each pixel location";
05523 }
05524
05525 static float binary_operate(const float& left, const float& right) {
05526 if (left < right) return left;
05527 return right;
05528 }
05529
05530 static const string NAME;
05531 };
05532
05536 class MatchSFProcessor:public FourierAnlProcessor
05537 {
05538 public:
05539
05540 virtual string get_name() const
05541 {
05542 return NAME;
05543 }
05544
05545 virtual string get_desc() const
05546 {
05547 return "Filters the image so its 1-D power spectrum matches a second image";
05548 }
05549
05550 static Processor *NEW()
05551 {
05552 return new MatchSFProcessor();
05553 }
05554
05555 virtual TypeDict get_param_types() const
05556 {
05557 TypeDict d;
05558 d.put("to", EMObject::EMDATA, "The image to match with. Make sure apix values are correct.");
05559 return d;
05560 }
05561
05562 static const string NAME;
05563
05564 protected:
05565 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05566 };
05567
05568
05573 class SetSFProcessor:public FourierAnlProcessor
05574 {
05575 public:
05576
05577 virtual string get_name() const
05578 {
05579 return NAME;
05580 }
05581
05582 virtual string get_desc() const
05583 {
05584 return "Filters the image so its 1-D power spectrum matches a supplied X-Y curve";
05585 }
05586
05587 static Processor *NEW()
05588 {
05589 return new SetSFProcessor();
05590 }
05591
05592 virtual TypeDict get_param_types() const
05593 {
05594 TypeDict d;
05595 d.put("strucfac", EMObject::XYDATA, "An XYData object contaning the curve to be imposed as a function of S");
05596 d.put("apix", EMObject::FLOAT, " Override A/pix in the image header (changes x,y and z)");
05597 return d;
05598 }
05599
05600 static const string NAME;
05601
05602 protected:
05603 void create_radial_func(vector < float >&radial_mask, EMData *image) const;
05604 };
05605
05609 class SmartMaskProcessor: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 SmartMaskProcessor();
05622 }
05623
05624 virtual string get_desc() const
05625 {
05626 return "Smart mask processor.";
05627 }
05628
05629 virtual TypeDict get_param_types() const
05630 {
05631 TypeDict d;
05632 d.put("mask", EMObject::FLOAT, "mask value");
05633 return d;
05634 }
05635
05636 static const string NAME;
05637 };
05638
05643 class IterBinMaskProcessor:public Processor
05644 {
05645 public:
05646 virtual void process_inplace(EMData * image);
05647
05648 virtual string get_name() const
05649 {
05650 return NAME;
05651 }
05652
05653 virtual string get_desc() const
05654 {
05655 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.";
05656 }
05657
05658 static Processor *NEW()
05659 {
05660 return new IterBinMaskProcessor();
05661 }
05662
05663 virtual TypeDict get_param_types() const
05664 {
05665 TypeDict d;
05666 d.put("val1", EMObject::FLOAT, "number of pixels to expand");
05667 d.put("val2", EMObject::FLOAT, "number of Gaussian pixels to expand, following the first expansion");
05668 return d;
05669 }
05670
05671 static const string NAME;
05672 };
05673
05676 class TestImageProcessor : public Processor
05677 {
05678 public:
05679 static string get_group_desc()
05680 {
05681 return "Base class for a group of 'processors' used to create test image.";
05682 }
05683
05684 protected:
05685 void preprocess(EMData * image);
05686 int nx, ny, nz;
05687 };
05688
05697 class TestImagePureGaussian : public TestImageProcessor
05698 {
05699 public:
05700 virtual void process_inplace(EMData * image);
05701
05702 virtual string get_name() const
05703 {
05704 return NAME;
05705 }
05706
05707 virtual string get_desc() const
05708 {
05709 return "Replace a source image as a strict Gaussian ";
05710 }
05711
05712 static Processor * NEW()
05713 {
05714 return new TestImagePureGaussian();
05715 }
05716
05717 virtual TypeDict get_param_types() const
05718 {
05719 TypeDict d;
05720 d.put("x_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on x direction");
05721 d.put("y_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on y direction");
05722 d.put("z_sigma", EMObject::FLOAT, "sigma value for this Gaussian blob on z direction");
05723 d.put("x_center", EMObject::FLOAT, "center for this Gaussian blob on x direction" );
05724 d.put("y_center", EMObject::FLOAT, "center for this Gaussian blob on y direction" );
05725 d.put("z_center", EMObject::FLOAT, "center for this Gaussian blob on z direction" );
05726 return d;
05727 }
05728
05729 static const string NAME;
05730 };
05731
05735 class TestImageFourierNoiseGaussian : public TestImageProcessor
05736 {
05737 public:
05738 virtual void process_inplace(EMData * image);
05739
05740 virtual string get_name() const
05741 {
05742 return NAME;
05743 }
05744
05745 virtual string get_desc() const
05746 {
05747 return "Replace a source image with pink Fourier noise, based on a Gaussian. Random phase.";
05748 }
05749
05750 static Processor * NEW()
05751 {
05752 return new TestImageFourierNoiseGaussian();
05753 }
05754
05755 virtual TypeDict get_param_types() const
05756 {
05757 TypeDict d;
05758 d.put("sigma", EMObject::FLOAT, "sigma value");
05759 return d;
05760 }
05761
05762 static const string NAME;
05763 };
05764
05769 class TestImageFourierNoiseProfile : public TestImageProcessor
05770 {
05771 public:
05772 virtual void process_inplace(EMData * image);
05773
05774 virtual string get_name() const
05775 {
05776 return NAME;
05777 }
05778
05779 virtual string get_desc() const
05780 {
05781 return "Replace a source image with Fourier noise using amplitude information that is stored in a profile.";
05782 }
05783
05784 static Processor * NEW()
05785 {
05786 return new TestImageFourierNoiseProfile();
05787 }
05788
05789 virtual TypeDict get_param_types() const
05790 {
05791 TypeDict d;
05792 d.put("profile", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
05793 return d;
05794 }
05795
05796 static const string NAME;
05797 };
05798
05799
05804 class CTFSNRWeightProcessor : public TestImageProcessor
05805 {
05806 public:
05807 virtual void process_inplace(EMData * image);
05808
05809 virtual string get_name() const
05810 {
05811 return NAME;
05812 }
05813
05814 virtual string get_desc() const
05815 {
05816 return "Weight the amplitudes of an image based on radial noise and snr curves ";
05817 }
05818
05819 static Processor * NEW()
05820 {
05821 return new CTFSNRWeightProcessor();
05822 }
05823
05824 virtual TypeDict get_param_types() const
05825 {
05826 TypeDict d;
05827 d.put("noise", EMObject::FLOATARRAY, "The noise profile, squared amplitude. As in, what is the EMAN2CTF.background attribute");
05828 d.put("snr", EMObject::FLOATARRAY, "Squared amplitude divided by squared noise amplitude. As in, what is the EMAN2CTF.snr attribute");
05829 d.put("boost", EMObject::FLOAT, "Multiplicative signal boost");
05830 return d;
05831 }
05832
05833 static const string NAME;
05834 };
05835
05836
05837
05842 class TestImageLineWave : public TestImageProcessor
05843 {
05844 public:
05845 virtual void process_inplace(EMData * image);
05846
05847 virtual string get_name() const
05848 {
05849 return NAME;
05850 }
05851
05852 virtual string get_desc() const
05853 {
05854 return "Insert an oscillating sine wave into the pixel data";
05855 }
05856
05857 static Processor * NEW()
05858 {
05859 return new TestImageLineWave();
05860 }
05861
05862 virtual TypeDict get_param_types() const
05863 {
05864 TypeDict d;
05865 d.put("period", EMObject::FLOAT, "The period of the oscillating sine wave. Default 10.");
05866 return d;
05867 }
05868
05869 static const string NAME;
05870 };
05871
05872
05880 class TestTomoImage : public TestImageProcessor
05881 {
05882 public:
05886 virtual void process_inplace(EMData * image);
05887
05888 virtual string get_name() const
05889 {
05890 return NAME;
05891 }
05892
05893 virtual string get_desc() const
05894 {
05895 return "Make an image consisting various objects, useful for tomographic testing";
05896 }
05897
05898 static Processor * NEW()
05899 {
05900 return new TestTomoImage();
05901 }
05902
05903 static const string NAME;
05904
05905 private:
05906 void insert_solid_ellipse( EMData* image, const Region& region, const float& value, const Transform& t3d = Transform() );
05907 void insert_hollow_ellipse( EMData* image, const Region& region, const float& value, const int& radius, const Transform& t3d = Transform() );
05908 void insert_rectangle( EMData* image, const Region& region, const float& value, const Transform& t3d = Transform() );
05909 };
05910
05918 class TestImageGradient : public TestImageProcessor
05919 {
05920 public:
05921 virtual void process_inplace(EMData * image);
05922
05923 virtual string get_name() const
05924 {
05925 return NAME;
05926 }
05927
05928 virtual string get_desc() const
05929 {
05930 return "Make a gradient image of the form y=mx+b, where x is any of the image axes.";
05931 }
05932
05933 static Processor * NEW()
05934 {
05935 return new TestImageGradient();
05936 }
05937
05938 virtual TypeDict get_param_types() const
05939 {
05940 TypeDict d;
05941 d.put("axis", EMObject::STRING, "The axis the will be used to determine pixel values. Must be x,y or z");
05942 d.put("m", EMObject::FLOAT, "m in the equation m*axis+b. Default is 1.0");
05943 d.put("b", EMObject::FLOAT, "b in the equation m*axis+b. Default is 0.0");
05944 return d;
05945 }
05946
05947 static const string NAME;
05948 };
05949
05957 class TestImageAxes : public TestImageProcessor
05958 {
05959 public:
05964 virtual void process_inplace(EMData * image);
05965
05966 virtual string get_name() const
05967 {
05968 return NAME;
05969 }
05970
05971 virtual string get_desc() const
05972 {
05973 return "Make an image consisting of a single cross";
05974 }
05975
05976 static Processor * NEW()
05977 {
05978 return new TestImageAxes();
05979 }
05980
05981 virtual TypeDict get_param_types() const
05982 {
05983 TypeDict d;
05984 d.put("int", EMObject::FLOAT, "radius of the lines emanating from the origin");
05985 d.put("fill", EMObject::FLOAT, "value to make non-zero pixels");
05986 return d;
05987 }
05988
05989 static const string NAME;
05990 };
05991
05997 class TestImageGaussian : public TestImageProcessor
05998 {
05999 public:
06000 virtual void process_inplace(EMData * image);
06001
06002 virtual string get_name() const
06003 {
06004 return NAME;
06005 }
06006
06007 virtual string get_desc() const
06008 {
06009 return "Replace a source image as a Gaussian Blob";
06010 }
06011
06012 static Processor * NEW()
06013 {
06014 return new TestImageGaussian();
06015 }
06016
06017 virtual TypeDict get_param_types() const
06018 {
06019 TypeDict d;
06020 d.put("sigma", EMObject::FLOAT, "sigma value for this Gaussian blob");
06021 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06022 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06023 return d;
06024 }
06025
06026 static const string NAME;
06027 };
06028
06031 class TestImageScurve : public TestImageProcessor
06032 {
06033 public:
06034 virtual void process_inplace(EMData * image);
06035
06036 virtual string get_name() const
06037 {
06038 return NAME;
06039 }
06040
06041 virtual string get_desc() const
06042 {
06043 return "Replace a source image with a lumpy S-curve used for alignment testing";
06044 }
06045
06046 static Processor * NEW()
06047 {
06048 return new TestImageScurve();
06049 }
06050
06051 virtual TypeDict get_param_types() const
06052 {
06053 TypeDict d;
06054 return d;
06055 }
06056
06057 static const string NAME;
06058 };
06059
06067 class TestImageSphericalWave : public TestImageProcessor
06068 {
06069 public:
06070 virtual void process_inplace(EMData * image);
06071
06072 virtual string get_name() const
06073 {
06074 return NAME;
06075 }
06076
06077 virtual string get_desc() const
06078 {
06079 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)";
06080 }
06081
06082 static Processor * NEW()
06083 {
06084 return new TestImageSphericalWave();
06085 }
06086
06087 virtual TypeDict get_param_types() const
06088 {
06089 TypeDict d;
06090 d.put("wavelength", EMObject::FLOAT, "cos(2*pi*r/wavelength+phase)");
06091 d.put("phase", EMObject::FLOAT, "in radians");
06092 d.put("x", EMObject::FLOAT, "center of the spherical wave");
06093 d.put("y", EMObject::FLOAT, "center of the spherical wave");
06094 d.put("z", EMObject::FLOAT, "center of the spherical wave");
06095 return d;
06096 }
06097
06098 static const string NAME;
06099 };
06100
06101
06110 class TestImageSinewave : public TestImageProcessor
06111 {
06112 public:
06113 virtual void process_inplace(EMData * image);
06114
06115 virtual string get_name() const
06116 {
06117 return NAME;
06118 }
06119
06120 virtual string get_desc() const
06121 {
06122 return "Replace a source image as a sine wave in specified wave length";
06123 }
06124
06125 static Processor * NEW()
06126 {
06127 return new TestImageSinewave();
06128 }
06129
06130 virtual TypeDict get_param_types() const
06131 {
06132 TypeDict d;
06133 d.put("wavelength", EMObject::FLOAT, "wavelength in equation sin(x*2*PI/wavelength - phase*180/PI)");
06134 d.put("axis", EMObject::STRING, "(optional) specify a major axis for asymmetric features, default x axis");
06135 d.put("phase", EMObject::FLOAT, "(optional) the phase in radians");
06136 d.put("az", EMObject::FLOAT, "(optional) angle in degree. for 2D image, this is the rotated angle of the image, \
06137 in 3D image, it's az for euler angle. default is zero");
06138 d.put("alt", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, alt for euler angle, default is zero");
06139 d.put("phi", EMObject::FLOAT, "(optional) angle in degree. only in 3D case, phi for euler angle, default is zero");
06140 return d;
06141 }
06142
06143 static const string NAME;
06144 };
06145
06152 class TestImageSinewaveCircular : public TestImageProcessor
06153 {
06154 public:
06155 virtual void process_inplace(EMData * image);
06156
06157 virtual string get_name() const
06158 {
06159 return NAME;
06160 }
06161
06162 virtual string get_desc() const
06163 {
06164 return "Replace a source image as a circular sine wave in specified wave length";
06165 }
06166
06167 static Processor * NEW()
06168 {
06169 return new TestImageSinewaveCircular();
06170 }
06171
06172 virtual TypeDict get_param_types() const
06173 {
06174 TypeDict d;
06175 d.put("wavelength", EMObject::FLOAT, "(required)this value is the d in function |sin(x/d)|, unit: pixel");
06176 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06177 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06178 d.put("phase", EMObject::FLOAT, "(optional)phase for sine wave, default is 0");
06179 return d;
06180 }
06181
06182 static const string NAME;
06183 };
06184
06191 class TestImageSquarecube : public TestImageProcessor
06192 {
06193 public:
06194 virtual void process_inplace(EMData * image);
06195
06196 virtual string get_name() const
06197 {
06198 return NAME;
06199 }
06200
06201 virtual string get_desc() const
06202 {
06203 return "Replace a source image as a square or cube depends on 2D or 3D of the source image";
06204 }
06205
06206 static Processor * NEW()
06207 {
06208 return new TestImageSquarecube();
06209 }
06210
06211 virtual TypeDict get_param_types() const
06212 {
06213 TypeDict d;
06214 d.put("edge_length", EMObject::FLOAT, "edge length of the square or cube, unit: pixel");
06215 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06216 d.put("odd_edge", EMObject::FLOAT, "edge length for the asymmetric axis");
06217 d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank");
06218 return d;
06219 }
06220
06221 static const string NAME;
06222 };
06223
06231 class TestImageEllipse : public TestImageProcessor
06232 {
06233 public:
06234 virtual void process_inplace(EMData * image);
06235
06236 virtual string get_name() const
06237 {
06238 return NAME;
06239 }
06240
06241 virtual string get_desc() const
06242 {
06243 return "Insert an ellipse into the image.";
06244 }
06245
06246 static Processor * NEW()
06247 {
06248 return new TestImageEllipse();
06249 }
06250
06251 virtual TypeDict get_param_types() const
06252 {
06253 TypeDict d;
06254 d.put("a", EMObject::FLOAT, "equatorial radius along x axes (major semiaxes)");
06255 d.put("b", EMObject::FLOAT, "equatorial radius along y axes (minor semiaxes)");
06256 d.put("c", EMObject::FLOAT, "polar radius for ellipsoid (x^2/a^2+y^2/b^2+z^2/c^2=1)");
06257 d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06258 d.put("fill", EMObject::FLOAT, "value you want to fill in ellipse, default to 1.0");
06259 return d;
06260 }
06261
06262 static const string NAME;
06263 };
06264
06276 class TestImageHollowEllipse : public TestImageProcessor
06277 {
06278 public:
06279 virtual void process_inplace(EMData * image);
06280
06281 virtual string get_name() const
06282 {
06283 return NAME;
06284 }
06285
06286 virtual string get_desc() const
06287 {
06288 return "Insert a hollow ellipse into the image.";
06289 }
06290
06291 static Processor * NEW()
06292 {
06293 return new TestImageHollowEllipse();
06294 }
06295
06296 virtual TypeDict get_param_types() const
06297 {
06298 TypeDict d;
06299 d.put("xwidth", EMObject::FLOAT, "inner equatorial radii along x axes");
06300 d.put("ywidth", EMObject::FLOAT, "inner equatorial radii along y axes");
06301 d.put("zwidth", EMObject::FLOAT, "inner polar radius");
06302 d.put("a", EMObject::FLOAT, "outter equatorial radii along x axes");
06303 d.put("b", EMObject::FLOAT, "outter equatorial radii along y axes");
06304 d.put("c", EMObject::FLOAT, "outter polar radius");
06305 d.put("width",EMObject::FLOAT, "width - specify the width or specify each width explicitly - xwidth, ywidth, zwidth");
06306 d.put("transform", EMObject::TRANSFORM, "Optionally transform the ellipse");
06307 d.put("fill", EMObject::FLOAT, "value you want to fill in hollow ellipse, default to 1.0");
06308 return d;
06309 }
06310
06311 static const string NAME;
06312 };
06313
06320 class TestImageCirclesphere : public TestImageProcessor
06321 {
06322 public:
06323 virtual void process_inplace(EMData * image);
06324
06325 virtual string get_name() const
06326 {
06327 return NAME;
06328 }
06329
06330 virtual string get_desc() const
06331 {
06332 return "Replace a source image as a circle or sphere depends on 2D or 3D of the source image";
06333 }
06334
06335 static Processor * NEW()
06336 {
06337 return new TestImageCirclesphere();
06338 }
06339
06340 virtual TypeDict get_param_types() const
06341 {
06342 TypeDict d;
06343 d.put("radius", EMObject::FLOAT, "radius of circle or sphere, unit: pixel");
06344 d.put("axis", EMObject::STRING, "specify a major axis for asymmetric features");
06345 d.put("c", EMObject::FLOAT, "distance between focus and the center of an ellipse");
06346 d.put("fill", EMObject::INT, "Flag indicating if image is filled, default filled, 1 for filled, 0 for blank.");
06347 return d;
06348 }
06349
06350 static const string NAME;
06351 };
06352
06357 class TestImageNoiseUniformRand : public TestImageProcessor
06358 {
06359 public:
06360 virtual void process_inplace(EMData * image);
06361
06362 virtual string get_name() const
06363 {
06364 return NAME;
06365 }
06366
06367 virtual string get_desc() const
06368 {
06369 return "Replace a source image as a uniform random noise, random number generated from gsl_rng_mt19937, the pixel value is [0, 1)";
06370 }
06371
06372 static Processor * NEW()
06373 {
06374 return new TestImageNoiseUniformRand();
06375 }
06376
06377 virtual TypeDict get_param_types() const
06378 {
06379 TypeDict d;
06380 d.put("seed", EMObject::INT, "seed for random number generator");
06381 return d;
06382 }
06383
06384 static const string NAME;
06385 };
06386
06397 class TestImageNoiseGauss : public TestImageProcessor
06398 {
06399 public:
06400 virtual void process_inplace(EMData * image);
06401
06402 virtual string get_name() const
06403 {
06404 return NAME;
06405 }
06406
06407 virtual string get_desc() const
06408 {
06409 return "Replace a source image as a random noise, the random value is gaussian distributed";
06410 }
06411
06412 static Processor * NEW()
06413 {
06414 return new TestImageNoiseGauss();
06415 }
06416
06417 virtual TypeDict get_param_types() const
06418 {
06419 TypeDict d;
06420 d.put("sigma", EMObject::FLOAT, "sigma value of gausian distributed noise, default is 0.5");
06421 d.put("mean", EMObject::FLOAT, "mean value of gausian distributed noise, default is zero.");
06422 d.put("seed", EMObject::INT, "the seed for random number generator, default is not to reseed.");
06423
06424 return d;
06425 }
06426
06427 static const string NAME;
06428 };
06429
06434 class TestImageCylinder : public TestImageProcessor
06435 {
06436 public:
06437 virtual void process_inplace(EMData * image);
06438
06439 virtual string get_name() const
06440 {
06441 return NAME;
06442 }
06443
06444 virtual string get_desc() const
06445 {
06446 return "Replace a source image as a cylinder";
06447 }
06448
06449 static Processor * NEW()
06450 {
06451 return new TestImageCylinder();
06452 }
06453
06454 virtual TypeDict get_param_types() const
06455 {
06456 TypeDict d;
06457 d.put("radius", EMObject::FLOAT, "radius for the cylinder");
06458 d.put("height", EMObject::FLOAT, "height for the cylinder, by default it's the nz");
06459
06460 return d;
06461 }
06462
06463 static const string NAME;
06464 };
06465
06471 class CCDNormProcessor:public Processor
06472 {
06473 public:
06474 virtual void process_inplace(EMData * image);
06475
06476 virtual string get_name() const
06477 {
06478 return NAME;
06479 }
06480
06481 static Processor *NEW()
06482 {
06483 return new CCDNormProcessor();
06484 }
06485
06486 virtual string get_desc() const
06487 {
06488 return "normalize the 4 quadrants of a CCD image";
06489 }
06490
06491 virtual TypeDict get_param_types() const
06492 {
06493 TypeDict d;
06494 d.put("width", EMObject::INT, "number of pixels on either side of the seam to sample");
06495 return d;
06496 }
06497
06498 static const string NAME;
06499 };
06500
06508 class WaveletProcessor:public Processor
06509 {
06510 public:
06511 virtual void process_inplace(EMData * image);
06512
06513 virtual string get_name() const
06514 {
06515 return NAME;
06516 }
06517
06518 static Processor *NEW()
06519 {
06520 return new WaveletProcessor();
06521 }
06522
06523 virtual TypeDict get_param_types() const
06524 {
06525 TypeDict d;
06526 d.put("type", EMObject::STRING, "'daub', 'harr' or 'bspl'");
06527 d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06528 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)");
06529 return d;
06530 }
06531
06532 virtual string get_desc() const
06533 {
06534 return "Computes the DWT (discrete wavelet transform) of an image in one of 3 possible bases";
06535 }
06536
06537 static const string NAME;
06538 };
06539
06555 class TomoTiltEdgeMaskProcessor : public Processor
06556 {
06557 public:
06558 virtual void process_inplace(EMData* image);
06559
06560 virtual string get_name() const
06561 {
06562 return NAME;
06563 }
06564
06565 static Processor *NEW()
06566 {
06567 return new TomoTiltEdgeMaskProcessor();
06568 }
06569
06570 virtual TypeDict get_param_types() const
06571 {
06572 TypeDict d;
06573 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");
06574 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.");
06575 d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06576 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.");
06577 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)");
06578 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");
06579 return d;
06580 }
06581
06582 virtual string get_desc() const
06583 {
06584 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.";
06585 }
06586
06587 static const string NAME;
06588
06589 private:
06590 class GaussianFunctoid
06591 {
06592 public:
06593 GaussianFunctoid(const float sigma, const float mean = 0.0) : m_mean(mean), m_sigma_squared(sigma*sigma) {}
06594 ~GaussianFunctoid() {}
06595
06596 float operator()(const float distance )
06597 {
06598 return exp( -(distance-m_mean)*(distance-m_mean)/ (m_sigma_squared ));
06599 }
06600 private:
06601 float m_mean, m_sigma_squared;
06602 };
06603
06604 };
06605
06620 class TomoTiltAngleWeightProcessor : public Processor
06621 {
06622 public:
06623 virtual void process_inplace(EMData* image);
06624
06625 virtual string get_name() const
06626 {
06627 return NAME;
06628 }
06629
06630 static Processor *NEW()
06631 {
06632 return new TomoTiltAngleWeightProcessor();
06633 }
06634
06635 virtual TypeDict get_param_types() const
06636 {
06637 TypeDict d;
06638 d.put("angle", EMObject::INT, "The angle that the image is, with respect to the zero tilt image");
06639 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");
06640 return d;
06641 }
06642
06643 virtual string get_desc() const
06644 {
06645 return "Weights the image by 1/cos(angle)";
06646 }
06647
06648 static const string NAME;
06649
06650 };
06651
06655 class FFTProcessor : public Processor
06656 {
06657 public:
06658 void process_inplace(EMData * image);
06659
06660 string get_name() const
06661 {
06662 return NAME;
06663 }
06664
06665 static Processor *NEW()
06666 {
06667 return new FFTProcessor();
06668 }
06669
06670 TypeDict get_param_types() const
06671 {
06672 TypeDict d;
06673 d.put("dir", EMObject::INT, "1 for forward transform, -1 for inverse transform");
06674 return d;
06675 }
06676
06677 string get_desc() const
06678 {
06679 return "Computes the DFFT (Discrete Fast Fourier Transform) of an image";
06680 }
06681
06682 static const string NAME;
06683 };
06684
06689 class RadialProcessor : public Processor
06690 {
06691 public:
06692 void process_inplace(EMData * image);
06693
06694 string get_name() const
06695 {
06696 return NAME;
06697 }
06698
06699 static Processor *NEW()
06700 {
06701 return new RadialProcessor();
06702 }
06703
06704 TypeDict get_param_types() const
06705 {
06706 TypeDict d;
06707 d.put("table", EMObject::FLOATARRAY, "Radial array of floats, 1 float/pixel");
06708 return d;
06709 }
06710
06711 string get_desc() const
06712 {
06713 return "Multiply a real-space image by a radial function. 1 value / pixel, extending to corner. Missing values -> 0.";
06714 }
06715
06716 static const string NAME;
06717 };
06718
06725 class HistogramBin : public Processor
06726 {
06727 public:
06728 HistogramBin() : default_bins(1024) {}
06729
06730 void process_inplace(EMData * image);
06731
06732 string get_name() const
06733 {
06734 return NAME;
06735 }
06736
06737 static Processor *NEW()
06738 {
06739 return new HistogramBin();
06740 }
06741
06742 TypeDict get_param_types() const
06743 {
06744 TypeDict d;
06745 d.put("nbins", EMObject::INT, "The number of bins the pixel values will be compressed into");
06746 d.put("debug", EMObject::BOOL, "Outputs debugging information (number of pixels per bin)");
06747 return d;
06748 }
06749
06750 string get_desc() const
06751 {
06752 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";
06753 }
06754
06755 static const string NAME;
06756
06757 protected:
06758 int default_bins;
06759 };
06760
06761 class ModelHelixProcessor : public Processor
06762 {
06763 protected:
06764 float radprofile(float r, int type);
06765 };
06766
06767 class ModelEMCylinderProcessor : public ModelHelixProcessor
06768 {
06769 public:
06770 void process_inplace(EMData * in);
06771
06772 string get_name() const
06773 {
06774 return NAME;
06775 }
06776
06777 static Processor *NEW()
06778 {
06779 return new ModelEMCylinderProcessor();
06780 }
06781
06782 string get_desc() const
06783 {
06784 return "Adds a cylinder with a radial density profile similar to that of an alpha helix.";
06785 }
06786
06787 virtual TypeDict get_param_types() const
06788 {
06789 TypeDict d;
06790 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");
06791 d.put("length", EMObject::FLOAT, "cylinder length in angstroms, defaults to 3 turns (16.2 Angstroms)");
06792 d.put("x0", EMObject::INT, "x coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06793 d.put("y0", EMObject::INT, "y coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06794 d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06795
06796 return d;
06797 }
06798
06799 static const string NAME;
06800 };
06801
06802 class ApplyPolynomialProfileToHelix : public ModelHelixProcessor
06803 {
06804 public:
06805 void process_inplace(EMData * in);
06806
06807 string get_name() const
06808 {
06809 return NAME;
06810 }
06811
06812 static Processor *NEW()
06813 {
06814 return new ApplyPolynomialProfileToHelix();
06815 }
06816
06817 string get_desc() const
06818 {
06819 return "Finds the CM of each z-axis slice and applies a polynomial radial profile about it.";
06820 }
06821 virtual TypeDict get_param_types() const
06822 {
06823 TypeDict d;
06824 d.put("length", EMObject::FLOAT, "Helix length in angstroms.");
06825 d.put("z0", EMObject::INT, "z coordinate in pixels for the midpoint of the cylinder's axis, defaults to center of map");
06826 return d;
06827 }
06828
06829 static const string NAME;
06830 };
06831
06832 class BinarySkeletonizerProcessor : public Processor
06833 {
06834 public:
06835 virtual EMData* process(EMData * image);
06836 virtual void process_inplace(EMData * image);
06837
06838 virtual string get_name() const
06839 {
06840 return NAME;
06841
06842 }
06843 static Processor *NEW()
06844 {
06845 return new BinarySkeletonizerProcessor();
06846 }
06847 string get_desc() const
06848 {
06849 return "Creates a skeleton of the 3D image by considering whether density is above or below a threshold value.";
06850 }
06851 virtual TypeDict get_param_types() const
06852 {
06853 TypeDict d;
06854 d.put("threshold", EMObject::FLOAT, "Threshold value.");
06855 d.put("min_curve_width", EMObject::INT, "Minimum curve width.");
06856 d.put("min_surface_width", EMObject::INT, "Minimum surface width.");
06857 d.put("mark_surfaces", EMObject::BOOL, "Mark surfaces with a value of 2.0f, whereas curves are 1.0f.");
06858 return d;
06859 }
06860 static const string NAME;
06861 };
06862
06863 #ifdef SPARX_USING_CUDA
06864
06865
06866
06867
06868
06869 class MPICUDA_kmeans {
06870 public:
06871 MPICUDA_kmeans();
06872 ~MPICUDA_kmeans();
06873 int setup(int extm, int extN, int extn, int extK, int extn_start);
06874 void append_flat_image(EMData* im, int pos);
06875 int init_mem(int numdev);
06876 void compute_im2();
06877 int random_ASG(long int rnd);
06878 vector<int> get_ASG();
06879 vector<int> get_asg();
06880 void compute_NC();
06881 vector<int> get_NC();
06882 void set_ASG(const vector <int>& ASG);
06883 void set_NC(const vector <int>& NC);
06884 int get_ct_im_mv();
06885 void set_T(float extT);
06886 float get_T();
06887 void compute_AVE();
06888 void set_AVE(EMData* im, int pos);
06889 vector<EMData*> get_AVE();
06890 int one_iter();
06891 int one_iter_SSE();
06892 int AVE_to_host();
06893 int one_iter_SA();
06894 vector<float> compute_ji();
06895 vector<float> compute_criterion(const vector <float>& Ji);
06896 int shutdown();
06897 private:
06898
06899 int m;
06900 int N;
06901 int n;
06902 int K;
06903 int nb_part;
06904 int n_start;
06905 int size_im;
06906 int size_IM;
06907 int size_AVE;
06908 int size_dist;
06909 int BLOCK_SIZE;
06910 int NB;
06911 int ins_BLOCK;
06912 int ite;
06913 float T;
06914
06915 int ct_im_mv;
06916
06917 float* h_IM;
06918 float* h_im;
06919 float* h_AVE;
06920 float* h_dist;
06921 float* h_AVE2;
06922 float* h_im2;
06923 unsigned short int* h_ASG;
06924 unsigned short int* h_asg;
06925 unsigned int* h_NC;
06926 int* params;
06927 float ttt;
06928
06929 float* d_im;
06930 float* d_AVE;
06931 float* d_dist;
06932 int init_dist();
06933 float compute_tt();
06934 };
06935
06936 #endif //EMAN2_USING_CUDA
06937
06938 #if 0
06939
06940 class XYZProcessor:public Processor
06941 {
06942 public:
06943 void process_inplace(EMData * image);
06944
06945 string get_name() const
06946 {
06947 return NAME;
06948 }
06949
06950 static Processor *NEW()
06951 {
06952 return new XYZProcessor();
06953 }
06954
06955 string get_desc() const
06956 {
06957 return "N/A";
06958 }
06959
06960 TypeDict get_param_types() const
06961 {
06962 TypeDict d;
06963 return d;
06964 }
06965
06966 static const string NAME;
06967 };
06968
06969
06970 #endif
06971
06972
06973 #if 0
06974
06975 class XYZProcessor:public Processor
06976 {
06977 public:
06978 void process_inplace(EMData * image);
06979
06980 string get_name() const
06981 {
06982 return NAME;
06983 }
06984
06985 static Processor *NEW()
06986 {
06987 return new XYZProcessor();
06988 }
06989
06990 string get_desc() const
06991 {
06992 return "N/A";
06993 }
06994
06995 TypeDict get_param_types() const
06996 {
06997 TypeDict d;
06998 return d;
06999 }
07000
07001 static const string NAME;
07002 };
07003
07004
07005 #endif
07006
07007
07008 int multi_processors(EMData * image, vector < string > processornames);
07009 void dump_processors();
07010 map<string, vector<string> > dump_processors_list();
07011 map<string, vector<string> > group_processors();
07012
07013 template <> Factory < Processor >::Factory();
07014 }
07015
07016 #endif //eman_filter_h__
07017
07018
07019