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 #include "processor.h"
00037 #include "sparx/processor_sparx.h"
00038 #include "plugins/processor_template.h"
00039 #include "ctf.h"
00040 #include "xydata.h"
00041 #include "emdata.h"
00042 #include "emassert.h"
00043 #include "randnum.h"
00044 #include "symmetry.h"
00045
00046 #include <gsl/gsl_randist.h>
00047 #include <gsl/gsl_statistics.h>
00048 #include <gsl/gsl_wavelet.h>
00049 #include <gsl/gsl_wavelet2d.h>
00050 #include <algorithm>
00051 #include <ctime>
00052
00053 #ifdef EMAN2_USING_CUDA
00054 #include "cuda/cuda_util.h"
00055 #include "cuda/cuda_processor.h"
00056 #endif // EMAN2_USING_CUDA
00057
00058 using namespace EMAN;
00059 using std::reverse;
00060
00061 const string SNREvalProcessor::NAME = "eval.maskedsnr";
00062 const string AmpweightFourierProcessor::NAME = "filter.ampweight";
00063 const string ConvolutionProcessor::NAME = "math.convolution";
00064 const string XGradientProcessor::NAME = "math.edge.xgradient";
00065 const string YGradientProcessor::NAME = "math.edge.ygradient";
00066 const string ZGradientProcessor::NAME = "math.edge.zgradient";
00067 const string Wiener2DAutoAreaProcessor::NAME = "filter.wiener2dauto";
00068 const string Wiener2DFourierProcessor::NAME = "filter.wiener2d";
00069 const string LinearRampFourierProcessor::NAME = "filter.linearfourier";
00070 const string LowpassSharpCutoffProcessor::NAME = "eman1.filter.lowpass.sharp";
00071 const string HighpassSharpCutoffProcessor::NAME = "eman1.filter.highpass.sharp";
00072 const string LowpassGaussProcessor::NAME = "eman1.filter.lowpass.gaussian";
00073 const string HighpassAutoPeakProcessor::NAME = "filter.highpass.autopeak";
00074 const string HighpassGaussProcessor::NAME = "eman1.filter.highpass.gaussian";
00075 const string LowpassTanhProcessor::NAME = "eman1.filter.lowpass.tanh";
00076 const string HighpassTanhProcessor::NAME = "eman1.filter.highpass.tanh";
00077 const string HighpassButterworthProcessor::NAME = "eman1.filter.highpass.butterworth";
00078 const string LinearRampProcessor::NAME = "eman1.filter.ramp";
00079 const string AbsoluateValueProcessor::NAME = "math.absvalue";
00080 const string BooleanProcessor::NAME = "threshold.notzero";
00081 const string KmeansSegmentProcessor::NAME = "segment.kmeans";
00082 const string DistanceSegmentProcessor::NAME = "segment.distance";
00083 const string InvertCarefullyProcessor::NAME = "math.invert.carefully";
00084 const string ValuePowProcessor::NAME = "math.pow";
00085 const string ValueSquaredProcessor::NAME = "math.squared";
00086 const string ValueSqrtProcessor::NAME = "math.sqrt";
00087 const string ToZeroProcessor::NAME = "threshold.belowtozero";
00088 const string Rotate180Processor::NAME = "math.rotate.180";
00089 const string TransformProcessor::NAME = "xform";
00090 const string IntTranslateProcessor::NAME = "math.translate.int";
00091 const string ScaleTransformProcessor::NAME = "xform.scale";
00092 const string ClampingProcessor::NAME = "threshold.clampminmax";
00093 const string NSigmaClampingProcessor::NAME = "threshold.clampminmax.nsigma";
00094 const string ToMinvalProcessor::NAME = "threshold.belowtominval";
00095 const string CutToZeroProcessor::NAME = "threshold.belowtozero_cut";
00096 const string BinarizeProcessor::NAME = "threshold.binary";
00097 const string BinarizeFourierProcessor::NAME = "threshold.binary.fourier";
00098 const string CollapseProcessor::NAME = "threshold.compress";
00099 const string LinearXformProcessor::NAME = "math.linear";
00100 const string ExpProcessor::NAME = "math.exp";
00101 const string FiniteProcessor::NAME = "math.finite";
00102 const string RangeThresholdProcessor::NAME = "threshold.binaryrange";
00103 const string SigmaProcessor::NAME = "math.sigma";
00104 const string LogProcessor::NAME = "math.log";
00105 const string MaskSharpProcessor::NAME = "mask.sharp";
00106 const string MaskEdgeMeanProcessor::NAME = "mask.ringmean";
00107 const string MaskNoiseProcessor::NAME = "mask.noise";
00108 const string MaskGaussProcessor::NAME = "mask.gaussian";
00109 const string MaskGaussNonuniformProcessor::NAME = "mask.gaussian.nonuniform";
00110 const string MaskGaussInvProcessor::NAME = "math.gausskernelfix";
00111 const string LinearPyramidProcessor::NAME = "math.linearpyramid";
00112 const string MakeRadiusSquaredProcessor::NAME = "math.toradiussqr";
00113 const string MakeRadiusProcessor::NAME = "math.toradius";
00114 const string ComplexNormPixel::NAME = "complex.normpixels";
00115 const string LaplacianProcessor::NAME = "math.laplacian";
00116 const string ZeroConstantProcessor::NAME = "mask.contract";
00117 const string BoxMedianProcessor::NAME = "eman1.filter.median";
00118 const string BoxSigmaProcessor::NAME = "math.localsigma";
00119 const string BoxMaxProcessor::NAME = "math.localmax";
00120 const string MinusPeakProcessor::NAME = "math.submax";
00121 const string PeakOnlyProcessor::NAME = "mask.onlypeaks";
00122 const string DiffBlockProcessor::NAME = "eman1.filter.blockrange";
00123 const string CutoffBlockProcessor::NAME = "eman1.filter.blockcutoff";
00124 const string MaxShrinkProcessor::NAME = "math.maxshrink";
00125 const string MinShrinkProcessor::NAME = "math.minshrink";
00126 const string MeanShrinkProcessor::NAME = "math.meanshrink";
00127 const string MedianShrinkProcessor::NAME = "math.medianshrink";
00128 const string FFTResampleProcessor::NAME = "math.fft.resample";
00129 const string GradientRemoverProcessor::NAME = "math.lineargradientfix";
00130 const string GradientPlaneRemoverProcessor::NAME = "filter.gradientPlaneRemover";
00131 const string FlattenBackgroundProcessor::NAME = "filter.flattenbackground";
00132 const string RampProcessor::NAME = "filter.ramp";
00133 const string VerticalStripeProcessor::NAME = "math.verticalstripefix";
00134 const string RealToFFTProcessor::NAME = "math.realtofft";
00135 const string SigmaZeroEdgeProcessor::NAME = "mask.zeroedgefill";
00136 const string BeamstopProcessor::NAME = "mask.beamstop";
00137 const string MeanZeroEdgeProcessor::NAME = "mask.dampedzeroedgefill";
00138 const string AverageXProcessor::NAME = "math.averageovery";
00139 const string DecayEdgeProcessor::NAME = "mask.decayedge2d";
00140 const string ZeroEdgeRowProcessor::NAME = "mask.zeroedge2d";
00141 const string ZeroEdgePlaneProcessor::NAME = "mask.zeroedge3d";
00142 const string BilateralProcessor::NAME = "bilateral";
00143 const string NormalizeUnitProcessor::NAME = "normalize.unitlen";
00144 const string NormalizeUnitSumProcessor::NAME = "normalize.unitsum";
00145 const string NormalizeStdProcessor::NAME = "normalize";
00146 const string NormalizeMaskProcessor::NAME = "normalize.mask";
00147 const string NormalizeRampNormVar::NAME = "normalize.ramp.normvar";
00148 const string NormalizeByMassProcessor::NAME = "normalize.bymass";
00149 const string NormalizeEdgeMeanProcessor::NAME = "normalize.edgemean";
00150 const string NormalizeCircleMeanProcessor::NAME = "normalize.circlemean";
00151 const string NormalizeLREdgeMeanProcessor::NAME = "normalize.lredge";
00152 const string NormalizeMaxMinProcessor::NAME = "normalize.maxmin";
00153 const string NormalizeRowProcessor::NAME = "normalize.rows";
00154 const string NormalizeToLeastSquareProcessor::NAME = "normalize.toimage";
00155 const string RotationalAverageProcessor::NAME = "math.rotationalaverage";
00156 const string RotationalSubstractProcessor::NAME = "math.rotationalsubtract";
00157 const string TransposeProcessor::NAME = "xform.transpose";
00158 const string FlipProcessor::NAME = "xform.flip";
00159 const string AddNoiseProcessor::NAME = "math.addnoise";
00160 const string AddSigmaNoiseProcessor::NAME = "math.addsignoise";
00161 const string AddRandomNoiseProcessor::NAME = "addspectralnoise";
00162 const string FourierToCornerProcessor::NAME = "xform.fourierorigin.tocorner";
00163 const string FourierToCenterProcessor::NAME = "xform.fourierorigin.tocenter";
00164 const string PhaseToCenterProcessor::NAME = "xform.phaseorigin.tocenter";
00165 const string PhaseToCornerProcessor::NAME = "xform.phaseorigin.tocorner";
00166 const string AutoMask2DProcessor::NAME = "mask.auto2d";
00167 const string AutoMaskAsymUnit::NAME = "mask.asymunit";
00168 const string AutoMask3DProcessor::NAME = "mask.auto3d.thresh";
00169 const string AutoMask3D2Processor::NAME = "mask.auto3d";
00170 const string AddMaskShellProcessor::NAME = "mask.addshells";
00171 const string PhaseToMassCenterProcessor::NAME = "xform.phasecenterofmass";
00172 const string ToMassCenterProcessor::NAME = "xform.centerofmass";
00173 const string ACFCenterProcessor::NAME = "xform.centeracf";
00174 const string SNRProcessor::NAME = "eman1.filter.snr";
00175 const string FileFourierProcessor::NAME = "eman1.filter.byfile";
00176 const string SymSearchProcessor::NAME = "misc.symsearch";
00177 const string LocalNormProcessor::NAME = "misc.localnorm";
00178 const string IndexMaskFileProcessor::NAME = "mask.fromfile";
00179 const string CoordinateMaskFileProcessor::NAME = "mask.fromfile.sizediff";
00180 const string PaintProcessor::NAME = "mask.paint";
00181 const string DirectionalSumProcessor::NAME = "misc.directional_sum";
00182 const string WatershedProcessor::NAME = "watershed";
00183 template<> const string BinaryOperateProcessor<MaxPixelOperator>::NAME = "operate.max";
00184 template<> const string BinaryOperateProcessor<MinPixelOperator>::NAME = "operate.min";
00185 const string MaxPixelOperator::NAME = "operate.max";
00186 const string MinPixelOperator::NAME = "operate.min";
00187 const string MatchSFProcessor::NAME = "filter.matchto";
00188 const string SetSFProcessor::NAME = "filter.setstrucfac";
00189 const string SmartMaskProcessor::NAME = "mask.smart";
00190 const string IterBinMaskProcessor::NAME = "mask.addshells.gauss";
00191 const string TestImagePureGaussian::NAME = "testimage.puregaussian";
00192 const string TestImageFourierNoiseGaussian::NAME = "testimage.noise.fourier.gaussian";
00193 const string TestImageFourierNoiseProfile::NAME = "testimage.noise.fourier.profile";
00194 const string CTFSNRWeightProcessor::NAME = "ctf.snr.weight";
00195 const string TestImageLineWave::NAME = "testimage.linewave";
00196 const string TestTomoImage::NAME = "testimage.tomo.objects";
00197 const string TestImageGradient::NAME = "testimage.gradient";
00198 const string TestImageAxes::NAME = "testimage.axes";
00199 const string TestImageGaussian::NAME = "testimage.gaussian";
00200 const string TestImageScurve::NAME = "testimage.scurve";
00201 const string TestImageSphericalWave::NAME = "testimage.sphericalwave";
00202 const string TestImageSinewave::NAME = "testimage.sinewave";
00203 const string TestImageSinewaveCircular::NAME = "testimage.sinewave.circular";
00204 const string TestImageSquarecube::NAME = "testimage.squarecube";
00205 const string TestImageEllipse::NAME = "testimage.ellipsoid";
00206 const string TestImageHollowEllipse::NAME = "testimage.ellipsoid.hollow";
00207 const string TestImageCirclesphere::NAME = "testimage.circlesphere";
00208 const string TestImageNoiseUniformRand::NAME = "testimage.noise.uniform.rand";
00209 const string TestImageNoiseGauss::NAME = "testimage.noise.gauss";
00210 const string TestImageCylinder::NAME = "testimage.cylinder";
00211 const string CCDNormProcessor::NAME = "filter.ccdnorm";
00212 const string WaveletProcessor::NAME = "basis.wavelet";
00213 const string TomoTiltEdgeMaskProcessor::NAME = "tomo.tiltedgemask";
00214 const string TomoTiltAngleWeightProcessor::NAME = "tomo.tiltangleweight";
00215 const string FFTProcessor::NAME = "basis.fft";
00216 const string RadialProcessor::NAME = "mask.radialprofile";
00217 const string HistogramBin::NAME = "histogram.bin";
00218 const string ModelEMCylinderProcessor::NAME = "math.model_em_cylinder";
00219 const string ApplyPolynomialProfileToHelix::NAME = "math.poly_radial_profile";
00220 const string BinarySkeletonizerProcessor::NAME="gorgon.binary_skel";
00221 const string MirrorProcessor::NAME = "mirror";
00222 const string NewLowpassTopHatProcessor::NAME = "filter.lowpass.tophat";
00223 const string NewHighpassTopHatProcessor::NAME = "filter.highpass.tophat";
00224 const string NewBandpassTopHatProcessor::NAME = "filter.bandpass.tophat";
00225 const string NewHomomorphicTopHatProcessor::NAME = "filter.homomorphic.tophat";
00226 const string NewLowpassGaussProcessor::NAME = "filter.lowpass.gauss";
00227 const string LowpassAutoBProcessor::NAME="filter.lowpass.autob";
00228 const string NewHighpassGaussProcessor::NAME = "filter.highpass.gauss";
00229 const string NewBandpassGaussProcessor::NAME = "filter.bandpass.gauss";
00230 const string NewHomomorphicGaussProcessor::NAME = "filter.homomorphic.gauss";
00231 const string NewInverseGaussProcessor::NAME = "filter.gaussinverse";
00232 const string SHIFTProcessor::NAME = "filter.shift";
00233 const string InverseKaiserI0Processor::NAME = "filter.kaiser_io_inverse";
00234 const string InverseKaiserSinhProcessor::NAME = "filter.kaisersinhinverse";
00235 const string NewRadialTableProcessor::NAME = "filter.radialtable";
00236 const string NewLowpassButterworthProcessor::NAME = "filter.lowpass.butterworth";
00237 const string NewHighpassButterworthProcessor::NAME = "filter.highpass.butterworth";
00238 const string NewHomomorphicButterworthProcessor::NAME = "filter.homomorphic.butterworth";
00239 const string NewLowpassTanhProcessor::NAME = "filter.lowpass.tanh";
00240 const string NewHighpassTanhProcessor::NAME = "filter.highpass.tanh";
00241 const string NewHomomorphicTanhProcessor::NAME = "filter.homomorphic.tanh";
00242 const string NewBandpassTanhProcessor::NAME = "filter.bandpass.tanh";
00243 const string CTF_Processor::NAME = "filter.CTF_";
00244
00245 #ifdef EMAN2_USING_CUDA
00246 const string CudaMultProcessor::NAME = "cuda.math.mult";
00247 const string CudaCorrelationProcessor::NAME = "cuda.correlate";
00248 #endif //EMAN2_USING_CUDA
00249
00250 #if 0
00251
00252 #endif //0
00253
00254
00255 template <> Factory < Processor >::Factory()
00256 {
00257 force_add< LowpassSharpCutoffProcessor >();
00258 force_add<HighpassSharpCutoffProcessor>();
00259 force_add<LowpassGaussProcessor>();
00260 force_add<HighpassGaussProcessor>();
00261 force_add<HighpassAutoPeakProcessor>();
00262 force_add<LinearRampFourierProcessor>();
00263
00264 force_add<LowpassTanhProcessor>();
00265 force_add<HighpassTanhProcessor>();
00266 force_add<HighpassButterworthProcessor>();
00267 force_add<AmpweightFourierProcessor>();
00268 force_add<Wiener2DFourierProcessor>();
00269 force_add<LowpassAutoBProcessor>();
00270
00271 force_add<LinearPyramidProcessor>();
00272 force_add<LinearRampProcessor>();
00273 force_add<AbsoluateValueProcessor>();
00274 force_add<BooleanProcessor>();
00275 force_add<KmeansSegmentProcessor>();
00276 force_add<DistanceSegmentProcessor>();
00277 force_add<ValuePowProcessor>();
00278 force_add<ValueSquaredProcessor>();
00279 force_add<ValueSqrtProcessor>();
00280 force_add<Rotate180Processor>();
00281 force_add<TransformProcessor>();
00282 force_add<ScaleTransformProcessor>();
00283 force_add<IntTranslateProcessor>();
00284 force_add<InvertCarefullyProcessor>();
00285
00286 force_add<ClampingProcessor>();
00287 force_add<NSigmaClampingProcessor>();
00288
00289 force_add<ToZeroProcessor>();
00290 force_add<ToMinvalProcessor>();
00291 force_add<CutToZeroProcessor>();
00292 force_add<BinarizeProcessor>();
00293 force_add<BinarizeFourierProcessor>();
00294 force_add<CollapseProcessor>();
00295 force_add<LinearXformProcessor>();
00296
00297 force_add<ExpProcessor>();
00298 force_add<RangeThresholdProcessor>();
00299 force_add<SigmaProcessor>();
00300 force_add<LogProcessor>();
00301 force_add<FiniteProcessor>();
00302
00303 force_add< BinaryOperateProcessor<MaxPixelOperator> >();
00304 force_add< BinaryOperateProcessor<MinPixelOperator> >();
00305
00306 force_add<PaintProcessor>();
00307 force_add<WatershedProcessor>();
00308 force_add<MaskSharpProcessor>();
00309 force_add<MaskEdgeMeanProcessor>();
00310 force_add<MaskNoiseProcessor>();
00311 force_add<MaskGaussProcessor>();
00312 force_add<MaskGaussNonuniformProcessor>();
00313 force_add<MaskGaussInvProcessor>();
00314
00315 force_add<MaxShrinkProcessor>();
00316 force_add<MinShrinkProcessor>();
00317 force_add<MeanShrinkProcessor>();
00318 force_add<MedianShrinkProcessor>();
00319 force_add<FFTResampleProcessor>();
00320
00321 force_add<MakeRadiusSquaredProcessor>();
00322 force_add<MakeRadiusProcessor>();
00323
00324 force_add<ComplexNormPixel>();
00325
00326 force_add<LaplacianProcessor>();
00327 force_add<ZeroConstantProcessor>();
00328
00329 force_add<BoxMedianProcessor>();
00330 force_add<BoxSigmaProcessor>();
00331 force_add<BoxMaxProcessor>();
00332
00333 force_add<MinusPeakProcessor>();
00334 force_add<PeakOnlyProcessor>();
00335 force_add<DiffBlockProcessor>();
00336
00337 force_add<CutoffBlockProcessor>();
00338 force_add<GradientRemoverProcessor>();
00339 force_add<GradientPlaneRemoverProcessor>();
00340 force_add<FlattenBackgroundProcessor>();
00341 force_add<VerticalStripeProcessor>();
00342 force_add<RealToFFTProcessor>();
00343 force_add<SigmaZeroEdgeProcessor>();
00344 force_add<RampProcessor>();
00345
00346 force_add<BeamstopProcessor>();
00347 force_add<MeanZeroEdgeProcessor>();
00348 force_add<AverageXProcessor>();
00349 force_add<DecayEdgeProcessor>();
00350 force_add<ZeroEdgeRowProcessor>();
00351 force_add<ZeroEdgePlaneProcessor>();
00352
00353 force_add<BilateralProcessor>();
00354
00355 force_add<ConvolutionProcessor>();
00356
00357 force_add<NormalizeStdProcessor>();
00358 force_add<NormalizeUnitProcessor>();
00359 force_add<NormalizeUnitSumProcessor>();
00360 force_add<NormalizeMaskProcessor>();
00361 force_add<NormalizeEdgeMeanProcessor>();
00362 force_add<NormalizeCircleMeanProcessor>();
00363 force_add<NormalizeLREdgeMeanProcessor>();
00364 force_add<NormalizeMaxMinProcessor>();
00365 force_add<NormalizeByMassProcessor>();
00366 force_add<NormalizeRowProcessor>();
00367 force_add<NormalizeRampNormVar>();
00368
00369 force_add<HistogramBin>();
00370
00371 force_add<NormalizeToLeastSquareProcessor>();
00372
00373 force_add<RotationalAverageProcessor>();
00374 force_add<RotationalSubstractProcessor>();
00375 force_add<FlipProcessor>();
00376 force_add<TransposeProcessor>();
00377 force_add<MirrorProcessor>();
00378
00379 force_add<AddNoiseProcessor>();
00380 force_add<AddSigmaNoiseProcessor>();
00381 force_add<AddRandomNoiseProcessor>();
00382
00383 force_add<PhaseToCenterProcessor>();
00384 force_add<PhaseToCornerProcessor>();
00385 force_add<FourierToCenterProcessor>();
00386 force_add<FourierToCornerProcessor>();
00387 force_add<AutoMask2DProcessor>();
00388 force_add<AutoMask3DProcessor>();
00389 force_add<AutoMask3D2Processor>();
00390 force_add<AddMaskShellProcessor>();
00391 force_add<AutoMaskAsymUnit>();
00392
00393 force_add<CTFSNRWeightProcessor>();
00394
00395 force_add<ToMassCenterProcessor>();
00396 force_add<PhaseToMassCenterProcessor>();
00397 force_add<ACFCenterProcessor>();
00398 force_add<SNRProcessor>();
00399
00400 force_add<XGradientProcessor>();
00401 force_add<YGradientProcessor>();
00402 force_add<ZGradientProcessor>();
00403
00404 force_add<FileFourierProcessor>();
00405
00406 force_add<SymSearchProcessor>();
00407 force_add<LocalNormProcessor>();
00408
00409 force_add<IndexMaskFileProcessor>();
00410 force_add<CoordinateMaskFileProcessor>();
00411 force_add<SetSFProcessor>();
00412 force_add<MatchSFProcessor>();
00413
00414 force_add<SmartMaskProcessor>();
00415 force_add<IterBinMaskProcessor>();
00416
00417 force_add<TestImageGaussian>();
00418 force_add<TestImagePureGaussian>();
00419 force_add<TestImageSinewave>();
00420 force_add<TestImageSphericalWave>();
00421 force_add<TestImageSinewaveCircular>();
00422 force_add<TestImageSquarecube>();
00423 force_add<TestImageCirclesphere>();
00424 force_add<TestImageAxes>();
00425 force_add<TestImageNoiseUniformRand>();
00426 force_add<TestImageNoiseGauss>();
00427 force_add<TestImageScurve>();
00428 force_add<TestImageCylinder>();
00429 force_add<TestImageGradient>();
00430 force_add<TestTomoImage>();
00431 force_add<TestImageLineWave>();
00432 force_add<TestImageEllipse>();
00433 force_add<TestImageHollowEllipse>();
00434 force_add<TestImageFourierNoiseGaussian>();
00435 force_add<TestImageFourierNoiseProfile>();
00436
00437 force_add<TomoTiltEdgeMaskProcessor>();
00438 force_add<TomoTiltAngleWeightProcessor>();
00439
00440 force_add<NewLowpassTopHatProcessor>();
00441 force_add<NewHighpassTopHatProcessor>();
00442 force_add<NewBandpassTopHatProcessor>();
00443 force_add<NewHomomorphicTopHatProcessor>();
00444 force_add<NewLowpassGaussProcessor>();
00445 force_add<NewHighpassGaussProcessor>();
00446 force_add<NewBandpassGaussProcessor>();
00447 force_add<NewHomomorphicGaussProcessor>();
00448 force_add<NewInverseGaussProcessor>();
00449 force_add<NewLowpassButterworthProcessor>();
00450 force_add<NewHighpassButterworthProcessor>();
00451 force_add<NewHomomorphicButterworthProcessor>();
00452 force_add<NewLowpassTanhProcessor>();
00453 force_add<NewHighpassTanhProcessor>();
00454 force_add<NewBandpassTanhProcessor>();
00455 force_add<NewHomomorphicTanhProcessor>();
00456 force_add<NewRadialTableProcessor>();
00457 force_add<InverseKaiserI0Processor>();
00458 force_add<InverseKaiserSinhProcessor>();
00459 force_add<CCDNormProcessor>();
00460 force_add<CTF_Processor>();
00461 force_add<SHIFTProcessor>();
00462
00463 force_add<WaveletProcessor>();
00464 force_add<FFTProcessor>();
00465 force_add<RadialProcessor>();
00466
00467 force_add<DirectionalSumProcessor>();
00468
00469
00470 force_add<ModelEMCylinderProcessor>();
00471 force_add<ApplyPolynomialProfileToHelix>();
00472 force_add<BinarySkeletonizerProcessor>();
00473
00474 #ifdef EMAN2_USING_CUDA
00475 force_add<CudaMultProcessor>();
00476 force_add<CudaCorrelationProcessor>();
00477 #endif // EMAN2_USING_CUDA
00478
00479
00480 }
00481
00482 void FiniteProcessor::process_pixel(float *x) const
00483 {
00484 if ( !Util::goodf(x) ) {
00485 *x = to;
00486 }
00487 }
00488
00489
00490 EMData* Processor::process(const EMData * const image)
00491 {
00492 EMData * result = image->copy();
00493 process_inplace(result);
00494 return result;
00495 }
00496
00497 void ImageProcessor::process_inplace(EMData * image)
00498 {
00499 if (!image) {
00500 LOGWARN("NULL image");
00501 return;
00502 }
00503
00504 EMData *processor_image = create_processor_image();
00505
00506 if (image->is_complex()) {
00507 (*image) *= *processor_image;
00508 }
00509 else {
00510 EMData *fft = image->do_fft();
00511 (*fft) *= (*processor_image);
00512 EMData *ift = fft->do_ift();
00513
00514 float *data = image->get_data();
00515 float *t = data;
00516 float *ift_data = ift->get_data();
00517
00518 data = ift_data;
00519 ift_data = t;
00520
00521 ift->update();
00522
00523 if( fft )
00524 {
00525 delete fft;
00526 fft = 0;
00527 }
00528
00529 if( ift )
00530 {
00531 delete ift;
00532 ift = 0;
00533 }
00534 }
00535
00536 image->update();
00537 }
00538
00539 #define FFTRADIALOVERSAMPLE 4
00540 void FourierProcessor::process_inplace(EMData * image)
00541 {
00542 if (!image) {
00543 LOGWARN("NULL Image");
00544 return;
00545 }
00546
00547 preprocess(image);
00548
00549 int array_size = FFTRADIALOVERSAMPLE * image->get_ysize();
00550 float step=0.5f/array_size;
00551
00552 vector < float >yarray(array_size);
00553
00554 create_radial_func(yarray);
00555
00556 if (image->is_complex()) {
00557 image->apply_radial_func(0, step, yarray);
00558 }
00559 else {
00560 EMData *fft = image->do_fft();
00561 fft->apply_radial_func(0, step, yarray);
00562 EMData *ift = fft->do_ift();
00563
00564 memcpy(image->get_data(),ift->get_data(),ift->get_xsize()*ift->get_ysize()*ift->get_zsize()*sizeof(float));
00565
00566
00567
00568 if( fft )
00569 {
00570 delete fft;
00571 fft = 0;
00572 }
00573
00574 if( ift )
00575 {
00576 delete ift;
00577 ift = 0;
00578 }
00579 }
00580
00581 image->update();
00582 }
00583
00584 void FourierAnlProcessor::process_inplace(EMData * image)
00585 {
00586 if (!image) {
00587 LOGWARN("NULL Image");
00588 return;
00589 }
00590
00591 preprocess(image);
00592
00593
00594
00595
00596
00597
00598
00599 if (image->is_complex()) {
00600 vector <float>yarray = image->calc_radial_dist(image->get_ysize()/2,0,1.0,1);
00601 create_radial_func(yarray,image);
00602 image->apply_radial_func(0, 0.5f/yarray.size(), yarray);
00603 }
00604 else {
00605 EMData *fft = image->do_fft();
00606 vector <float>yarray = fft->calc_radial_dist(fft->get_ysize()/2,0,1.0,1);
00607 create_radial_func(yarray,image);
00608 fft->apply_radial_func(0, 0.5f/yarray.size(), yarray,0);
00609 EMData *ift = fft->do_ift();
00610
00611 memcpy(image->get_data(),ift->get_data(),ift->get_xsize()*ift->get_ysize()*ift->get_zsize()*sizeof(float));
00612
00613
00614
00615 delete fft;
00616 delete ift;
00617
00618 }
00619
00620 image->update();
00621 }
00622
00623 void LowpassAutoBProcessor::create_radial_func(vector < float >&radial_mask,EMData *image) const{
00624 float apix=(float)image->get_attr("apix_x");
00625 int verbose=(int)params["verbose"];
00626
00627 float noisecutoff=(float)params.set_default("noisecutoff",0.0);
00628 if (apix<=0 || apix>7.0f) throw ImageFormatException("0 < apix_x < 7.0");
00629 float ds=1.0f/(apix*image->get_xsize());
00630 unsigned int start=(int)floor(1.0/(15.0*ds));
00631 unsigned int end=radial_mask.size()-2;
00632 if (noisecutoff>0) end=(int)floor(noisecutoff/ds);
00633 if (end>radial_mask.size()-2) {
00634 printf("WARNING: specified noisecutoff too close to Nyquist, reset !");
00635 end=radial_mask.size()-2;
00636 }
00637 if (end<start+2) {
00638 printf("WARNING: noise cutoff too close to 15 A ! Results will not be good...");
00639 start=end-5;
00640 }
00641
00642 FILE *out=NULL;
00643 if (verbose>2) out=fopen("fitplot.txt","w");
00644 int N=(radial_mask.size()-start-2);
00645 float *x=(float *)malloc(N*sizeof(float));
00646 float *y=(float *)malloc(N*sizeof(float));
00647 float *dy=(float *)malloc(N*sizeof(float));
00648 for (unsigned int i=start; i<radial_mask.size()-2; i++ ) {
00649 x[i-start]=ds*ds*i*i;
00650 if (radial_mask[i]>0) y[i-start]=log(radial_mask[i]);
00651 else if (i>start) y[i-start]=y[i-start-1];
00652 else y[i-start]=0.0;
00653 if (i<radial_mask.size()-3) dy[i-start]=y[i-start]-y[i-start-1];
00654 if (out) fprintf(out,"%f\t%f\n",x[i-start],y[i-start]);
00655 }
00656 if (out) fclose(out);
00657
00658 float slope=0,intercept=0;
00659 Util::calc_least_square_fit(end-start, x,y,&slope,&intercept,1);
00660
00661 if (verbose) printf("slope=%f intercept=%f\n",slope,intercept);
00662
00663 float B=(float)params["bfactor"]+slope*4.0f/2.0f;
00664 float B2=(float)params["bfactor"];
00665
00666 if (verbose) printf("User B = %1.2f Corrective B = %1.2f Total B=%1.3f\n",(float)params["bfactor"],slope*2.0,B);
00667
00668 float cutval=exp(-B*pow(end*ds,2.0f)/4.0f)/exp(-B2*pow(end*ds,2.0f)/4.0f);
00669 for (unsigned int i=0; i<radial_mask.size(); i++) {
00670 if (i<=end) radial_mask[i]=exp(-B*pow(i*ds,2.0f)/4.0f);
00671 else radial_mask[i]=cutval*exp(-B2*pow(i*ds,2.0f)/4.0f);
00672 }
00673 if (verbose>1) Util::save_data(0,ds,radial_mask,"filter.txt");
00674
00675 free(x);
00676 free(y);
00677 free(dy);
00678 }
00679
00680
00681
00682 void LowpassFourierProcessor::preprocess(EMData * image)
00683 {
00684 if(params.has_key("apix")) {
00685 image->set_attr("apix_x", (float)params["apix"]);
00686 image->set_attr("apix_y", (float)params["apix"]);
00687 image->set_attr("apix_z", (float)params["apix"]);
00688 }
00689
00690 const Dict dict = image->get_attr_dict();
00691
00692 if( params.has_key("cutoff_abs") ) {
00693 lowpass = params["cutoff_abs"];
00694 }
00695 else if( params.has_key("cutoff_freq") ) {
00696 lowpass = (float)params["cutoff_freq"] * (float)dict["apix_x"] * (float)dict["nx"] / 2.0f;
00697 }
00698 else if( params.has_key("cutoff_pixels") ) {
00699 lowpass = (float)params["cutoff_pixels"] / (float)dict["nx"];
00700 }
00701 }
00702
00703 void HighpassFourierProcessor::preprocess(EMData * image)
00704 {
00705 if(params.has_key("apix")) {
00706 image->set_attr("apix_x", (float)params["apix"]);
00707 image->set_attr("apix_y", (float)params["apix"]);
00708 image->set_attr("apix_z", (float)params["apix"]);
00709 }
00710
00711 const Dict dict = image->get_attr_dict();
00712
00713 if( params.has_key("cutoff_abs") ) {
00714 highpass = params["cutoff_abs"];
00715 }
00716 else if( params.has_key("cutoff_freq") ) {
00717 highpass = (float)params["cutoff_freq"] * (float)dict["apix_x"] * (float)dict["nx"] / 2.0f;
00718 }
00719 else if( params.has_key("cutoff_pixels") ) {
00720 highpass = (float)params["cutoff_pixels"] / (float)dict["nx"];
00721 }
00722 }
00723
00724 void SNREvalProcessor::process_inplace(EMData * image)
00725 {
00726 int ys=image->get_ysize();
00727
00728 EMData *mask1=new EMData(ys,ys,1);
00729 mask1->process_inplace("mask.gaussian",Dict("outer_radius", ys/2.0));
00730 EMData *mask2=mask1->copy();
00731 mask2->mult(-1.0f);
00732 mask2->add(1.0);
00733 mask2->process_inplace("mask.decayedge2d",Dict("width",4));
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754 }
00755
00756 void AmpweightFourierProcessor::process_inplace(EMData * image)
00757 {
00758 EMData *fft;
00759 float *fftd;
00760 int i,f=0;
00761
00762
00763
00764 if (!image) {
00765 LOGWARN("NULL Image");
00766 return;
00767 }
00768
00769 if (!image->is_complex()) {
00770 fft = image->do_fft();
00771 fftd = fft->get_data();
00772 f=1;
00773 }
00774 else {
00775 fft=image;
00776 fftd=image->get_data();
00777 }
00778 float *sumd = NULL;
00779 if (sum) sumd=sum->get_data();
00780
00781 int n = fft->get_xsize()*fft->get_ysize()*fft->get_zsize();
00782 for (i=0; i<n; i+=2) {
00783 float c;
00784 if (dosqrt) c=pow(fftd[i]*fftd[i]+fftd[i+1]*fftd[i+1],0.25f);
00785 #ifdef _WIN32
00786 else c = static_cast<float>(_hypot(fftd[i],fftd[i+1]));
00787 #else
00788 else c = static_cast<float>(hypot(fftd[i],fftd[i+1]));
00789 #endif //_WIN32
00790 if (c==0) c=1.0e-30f;
00791 fftd[i]*=c;
00792 fftd[i+1]*=c;
00793 if (sumd) { sumd[i]+=c; sumd[i+1]+=0; }
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806 }
00807
00808 if (f) {
00809 fft->update();
00810 EMData *ift=fft->do_ift();
00811 memcpy(image->get_data(),ift->get_data(),n*sizeof(float));
00812 delete fft;
00813 delete ift;
00814 }
00815
00816 sum->update();
00817 image->update();
00818
00819 }
00820
00821 void DistanceSegmentProcessor::process_inplace(EMData *image)
00822 {
00823 printf("Process inplace not implemented. Please use process.\n");
00824 return;
00825 }
00826
00827
00828 EMData *DistanceSegmentProcessor::process(const EMData * const image)
00829 {
00830 EMData * result = image->copy();
00831
00832 float thr = params.set_default("thr",0.9);
00833 float minsegsep = params.set_default("minsegsep",5.0f);
00834 float maxsegsep = params.set_default("maxsegsep",5.1f);
00835 int verbose = params.set_default("verbose",0);
00836
00837 vector<Pixel> pixels=image->calc_highest_locations(thr);
00838
00839 vector<float> centers(3);
00840 int nx=image->get_xsize();
00841 int ny=image->get_ysize();
00842 int nz=image->get_zsize();
00843
00844
00845
00846 centers[0]=pixels[0].x;
00847 centers[1]=pixels[0].y;
00848 centers[2]=pixels[0].z;
00849 pixels.erase(pixels.begin());
00850
00851
00852
00853 while (pixels.size()>0) {
00854
00855
00856
00857 for (unsigned int i=0; i<pixels.size(); i++) {
00858
00859 Pixel p=pixels[i];
00860
00861 for (unsigned int j=0; j<centers.size(); j+=3) {
00862 float d=Util::hypot3(centers[j]-p.x,centers[j+1]-p.y,centers[j+2]-p.z);
00863 if (d<minsegsep) {
00864 pixels.erase(pixels.begin()+i);
00865 i--;
00866 break;
00867 }
00868 }
00869 }
00870
00871 int found=0;
00872 for (unsigned int i=0; i<pixels.size() && found==0; i++) {
00873 Pixel p=pixels[i];
00874
00875
00876 for (unsigned int j=centers.size()-3; j>0; j-=3) {
00877 float d=Util::hypot3(centers[j]-p.x,centers[j+1]-p.y,centers[j+2]-p.z);
00878 if (d<maxsegsep) {
00879 centers.push_back(p.x);
00880 centers.push_back(p.y);
00881 centers.push_back(p.z);
00882 pixels.erase(pixels.begin()+i);
00883 found=1;
00884 break;
00885 }
00886 }
00887 }
00888
00889
00890 if (!found && pixels.size()) {
00891 if (verbose) printf("New chain\n");
00892 centers.push_back(pixels[0].x);
00893 centers.push_back(pixels[0].y);
00894 centers.push_back(pixels[0].z);
00895 pixels.erase(pixels.begin());
00896 }
00897
00898 if (verbose) printf("%d points found\n",(int)(centers.size()/3));
00899 }
00900
00901
00902 for (int z=0; z<nz; z++) {
00903 for (int y=0; y<ny; y++) {
00904 for (int x=0; x<nz; x++) {
00905 if (image->get_value_at(x,y,z)<thr) {
00906 result->set_value_at(x,y,z,-1.0);
00907 continue;
00908 }
00909 int bcls=-1;
00910 float bdist=(float)(nx+ny+nz);
00911 for (unsigned int c=0; c<centers.size()/3; c++) {
00912 float d=Util::hypot3(x-centers[c*3],y-centers[c*3+1],z-centers[c*3+2]);
00913 if (d<bdist) { bdist=d; bcls=c; }
00914 }
00915 result->set_value_at(x,y,z,(float)bcls);
00916 }
00917 }
00918 }
00919
00920 result->set_attr("segment_centers",centers);
00921
00922 return result;
00923 }
00924
00925
00926 EMData* KmeansSegmentProcessor::process(const EMData * const image)
00927 {
00928 EMData * result = image->copy();
00929
00930 int nseg = params.set_default("nseg",12);
00931 float thr = params.set_default("thr",-1.0e30f);
00932 int ampweight = params.set_default("ampweight",1);
00933 float maxsegsize = params.set_default("maxsegsize",10000.0f);
00934 float minsegsep = params.set_default("minsegsep",0.0f);
00935 int maxiter = params.set_default("maxiter",100);
00936 int maxvoxmove = params.set_default("maxvoxmove",25);
00937 int verbose = params.set_default("verbose",0);
00938
00939 vector<float> centers(nseg*3);
00940 vector<float> count(nseg);
00941 int nx=image->get_xsize();
00942 int ny=image->get_ysize();
00943 int nz=image->get_zsize();
00944
00945
00946
00947 for (int i=0; i<nseg*3; i+=3) {
00948 centers[i]= Util::get_frand(0.0f,(float)nx);
00949 centers[i+1]=Util::get_frand(0.0f,(float)ny);
00950 centers[i+2]=Util::get_frand(0.0f,(float)nz);
00951 }
00952
00953 for (int iter=0; iter<maxiter; iter++) {
00954
00955 size_t pixmov=0;
00956 for (int z=0; z<nz; z++) {
00957 for (int y=0; y<ny; y++) {
00958 for (int x=0; x<nz; x++) {
00959 if (image->get_value_at(x,y,z)<thr) {
00960 result->set_value_at(x,y,z,-1.0);
00961 continue;
00962 }
00963 int bcls=-1;
00964 float bdist=(float)(nx+ny+nz);
00965 for (int c=0; c<nseg; c++) {
00966 float d=Util::hypot3(x-centers[c*3],y-centers[c*3+1],z-centers[c*3+2]);
00967 if (d<bdist) { bdist=d; bcls=c; }
00968 }
00969 if ((int)result->get_value_at(x,y,z)!=bcls) pixmov++;
00970 if (bdist>maxsegsize) result->set_value_at(x,y,z,-1);
00971 else result->set_value_at(x,y,z,(float)bcls);
00972 }
00973 }
00974 }
00975
00976
00977 for (int i=0; i<nseg*3; i++) centers[i]=0;
00978 for (int i=0; i<nseg; i++) count[i]=0;
00979
00980
00981 for (int z=0; z<nz; z++) {
00982 for (int y=0; y<ny; y++) {
00983 for (int x=0; x<nz; x++) {
00984 int cls = (int)result->get_value_at(x,y,z);
00985 if (cls==-1) continue;
00986 float w=1.0;
00987 if (ampweight) w=image->get_value_at(x,y,z);
00988
00989 centers[cls*3]+=x*w;
00990 centers[cls*3+1]+=y*w;
00991 centers[cls*3+2]+=z*w;
00992 count[cls]+=w;
00993 }
00994 }
00995 }
00996
00997
00998 int nreseed=0;
00999 for (int c=0; c<nseg; c++) {
01000
01001 if (count[c]==0) {
01002 nreseed++;
01003 do {
01004 centers[c*3]= Util::get_frand(0.0f,(float)nx);
01005 centers[c*3+1]=Util::get_frand(0.0f,(float)ny);
01006 centers[c*3+2]=Util::get_frand(0.0f,(float)nz);
01007 } while (image->get_value_at((int)centers[c*3],(int)centers[c*3+1],(int)centers[c*3+2])<thr);
01008 }
01009
01010 else {
01011 centers[c*3]/=count[c];
01012 centers[c*3+1]/=count[c];
01013 centers[c*3+2]/=count[c];
01014 }
01015 }
01016
01017
01018 if (minsegsep>0) {
01019 for (int c1=0; c1<nseg-1; c1++) {
01020 for (int c2=c1+1; c2<nseg; c2++) {
01021 if (Util::hypot3(centers[c1*3]-centers[c2*3],centers[c1*3+1]-centers[c2*3+1],centers[c1*3+2]-centers[c2*3+2])<=minsegsep) {
01022 nreseed++;
01023 do {
01024 centers[c1*3]= Util::get_frand(0.0f,(float)nx);
01025 centers[c1*3+1]=Util::get_frand(0.0f,(float)ny);
01026 centers[c1*3+2]=Util::get_frand(0.0f,(float)nz);
01027 } while (image->get_value_at((int)centers[c1*3],(int)centers[c1*3+1],(int)centers[c1*3+2])<thr);
01028 }
01029 }
01030 }
01031 }
01032
01033
01034 if (verbose) printf("Iteration %3d: %6ld voxels moved, %3d classes reseeded\n",iter,pixmov,nreseed);
01035 if (nreseed==0 && pixmov<(size_t)maxvoxmove) break;
01036 }
01037
01038 result->set_attr("segment_centers",centers);
01039
01040 return result;
01041 }
01042
01043 void KmeansSegmentProcessor::process_inplace(EMData *image)
01044 {
01045 printf("Process inplace not implemented. Please use process.\n");
01046 return;
01047 }
01048
01049
01050 void LinearPyramidProcessor::process_inplace(EMData *image) {
01051
01052 if (image->get_zsize()!=1) { throw ImageDimensionException("Only 2-D images supported"); }
01053
01054 float *d=image->get_data();
01055 int nx=image->get_xsize();
01056 int ny=image->get_ysize();
01057
01058 for (int y=0; y<ny; y++) {
01059 for (int x=0; x<nx; x++) {
01060 int l=x+y*nx;
01061 d[l]*=1.0f-abs(x-nx/2)*abs(y-ny/2)*4.0f/(nx*ny);
01062 }
01063 }
01064 image->update();
01065 }
01066
01067 EMData * Wiener2DAutoAreaProcessor::process(const EMData * image)
01068 {
01069
01070 EMData *ret = 0;
01071 const EMData *fft;
01072 float *fftd;
01073 int f=0;
01074
01075 if (!image) {
01076 LOGWARN("NULL Image");
01077 return ret;
01078 }
01079 throw NullPointerException("Processor not yet implemented");
01080
01081 if (!image->is_complex()) {
01082 fft = image->do_fft();
01083 fftd = fft->get_data();
01084 f=1;
01085 }
01086 else {
01087 fft=image;
01088 fftd=image->get_data();
01089 }
01090
01091 return ret;
01092 }
01093
01094 void Wiener2DAutoAreaProcessor::process_inplace(EMData *image) {
01095 EMData *tmp=process(image);
01096 memcpy(image->get_data(),tmp->get_data(),image->get_xsize()*image->get_ysize()*image->get_zsize()*sizeof(float));
01097 delete tmp;
01098 image->update();
01099 return;
01100 }
01101
01102
01103 EMData * Wiener2DFourierProcessor::process(const EMData *in)
01104 {
01105 const EMData *in2 = 0;
01106 if (in->is_complex()) in2=in;
01107 else in=in->do_fft();
01108
01109 EMData *filt = in->copy_head();
01110 Ctf *ictf = ctf;
01111
01112 if (!ictf) ctf=(Ctf *)in->get_attr("ctf");
01113
01114 ictf->compute_2d_complex(filt,Ctf::CTF_WIENER_FILTER);
01115 filt->mult(*in2);
01116 EMData *ret=filt->do_ift();
01117
01118 delete filt;
01119 if (!in->is_complex()) delete in2;
01120
01121 if(!ictf && ctf) {delete ctf; ctf=0;}
01122 return(ret);
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151 return ret;
01152
01153 }
01154
01155 void Wiener2DFourierProcessor::process_inplace(EMData *image) {
01156 EMData *tmp=process(image);
01157 memcpy(image->get_data(),tmp->get_data(),image->get_xsize()*image->get_ysize()*image->get_zsize()*sizeof(float));
01158 delete tmp;
01159 image->update();
01160 return;
01161 }
01162
01163 void LinearRampFourierProcessor::create_radial_func(vector < float >&radial_mask) const
01164 {
01165 Assert(radial_mask.size() > 0);
01166 for (size_t i = 0; i < radial_mask.size(); i++) {
01167 radial_mask[i] = (float)i;
01168 }
01169 }
01170
01171 void LowpassSharpCutoffProcessor::create_radial_func(vector < float >&radial_mask) const
01172 {
01173 Assert(radial_mask.size() > 0);
01174 float x = 0.0f , step = 0.5f/radial_mask.size();
01175 #ifdef DEBUG
01176 printf("%d %f %f\n",(int)radial_mask.size(),lowpass,step);
01177 #endif
01178 for (size_t i = 0; i < radial_mask.size(); i++) {
01179 if (x <= lowpass) {
01180 radial_mask[i] = 1.0f;
01181 }
01182 else {
01183 radial_mask[i] = 0;
01184 }
01185 x += step;
01186 }
01187 }
01188
01189
01190 void HighpassSharpCutoffProcessor::create_radial_func(vector < float >&radial_mask) const
01191 {
01192 Assert(radial_mask.size() > 0);
01193 float x = 0.0f , step = 0.5f/radial_mask.size();
01194 for (size_t i = 0; i < radial_mask.size(); i++) {
01195 if (x >= highpass) {
01196 radial_mask[i] = 1.0f;
01197 }
01198 else {
01199 radial_mask[i] = 0;
01200 }
01201 x += step;
01202 }
01203 }
01204
01205
01206 void LowpassGaussProcessor::create_radial_func(vector < float >&radial_mask) const
01207 {
01208
01209
01210 float x = 0.0f , step = 0.5f/radial_mask.size();
01211 float sig = 1;
01212 if (lowpass > 0) {
01213 sig = -1;
01214 }
01215
01216 for (size_t i = 0; i < radial_mask.size(); i++) {
01217 radial_mask[i] = exp(sig * x * x / (lowpass * lowpass));
01218 x += step;
01219 }
01220
01221 }
01222
01223 void HighpassGaussProcessor::create_radial_func(vector < float >&radial_mask) const
01224 {
01225 Assert(radial_mask.size() > 0);
01226 float x = 0.0f , step = 0.5f/radial_mask.size();
01227 for (size_t i = 0; i < radial_mask.size(); i++) {
01228 radial_mask[i] = 1.0f - exp(-x * x / (highpass * highpass));
01229 x += step;
01230 }
01231 }
01232
01233 void HighpassAutoPeakProcessor::preprocess(EMData * image)
01234 {
01235 if(params.has_key("apix")) {
01236 image->set_attr("apix_x", (float)params["apix"]);
01237 image->set_attr("apix_y", (float)params["apix"]);
01238 image->set_attr("apix_z", (float)params["apix"]);
01239 }
01240
01241 const Dict dict = image->get_attr_dict();
01242
01243 if( params.has_key("cutoff_abs") ) {
01244 highpass = params["cutoff_abs"];
01245 }
01246 else if( params.has_key("cutoff_freq") ) {
01247 highpass = (float)params["cutoff_freq"] * (float)dict["apix_x"] * (float)dict["nx"] / 2.0f;
01248 }
01249 else if( params.has_key("cutoff_pixels") ) {
01250 highpass = (float)params["cutoff_pixels"] / (float)dict["nx"];
01251 }
01252 }
01253
01254 void HighpassAutoPeakProcessor::create_radial_func(vector < float >&radial_mask, EMData *image) const
01255 {
01256 unsigned int c;
01257
01258
01259 for (c=2; c<radial_mask.size(); c++) if (radial_mask[c-1]<=radial_mask[c]) break;
01260 if (c>highpass) c=(unsigned int)highpass;
01261
01262 radial_mask[0]=0.0;
01263
01264 for (unsigned int i=1; i<radial_mask.size(); i++) radial_mask[i]=(i<=c?0.0f:1.0f);
01265
01266 printf("%f %d\n",highpass,c);
01267
01268
01269 }
01270
01271
01272 void LowpassTanhProcessor::create_radial_func(vector < float >&radial_mask) const
01273 {
01274 Assert(radial_mask.size() > 0);
01275 float x = 0.0f , step = 0.5f/radial_mask.size();
01276 for (size_t i = 0; i < radial_mask.size(); i++) {
01277 radial_mask[i] = tanh((lowpass - x)*60.0f) / 2.0f + 0.5f;
01278 x += step;
01279 }
01280 }
01281
01282 void HighpassTanhProcessor::create_radial_func(vector < float >&radial_mask) const
01283 {
01284 Assert(radial_mask.size() > 0);
01285 float x = 0.0f , step = 0.5f/radial_mask.size();
01286 for (size_t i = 0; i < radial_mask.size(); i++) {
01287 radial_mask[i] = tanh(x - highpass) / 2.0f + 0.5f;
01288 x += step;
01289 }
01290 }
01291
01292
01293 void HighpassButterworthProcessor::create_radial_func(vector < float >&radial_mask) const
01294 {
01295 Assert(radial_mask.size() > 0);
01296 float x = 0.0f , step = 0.5f/radial_mask.size();
01297 for (size_t i = 0; i < radial_mask.size(); i++) {
01298 float t = highpass / 1.5f / (x + 0.001f);
01299 radial_mask[i] = 1.0f / (1.0f + t * t);
01300 x += step;
01301 }
01302 }
01303
01304
01305 void LinearRampProcessor::create_radial_func(vector < float >&radial_mask) const
01306 {
01307 Assert(radial_mask.size() > 0);
01308 float x = 0.0f , step = 0.5f/radial_mask.size();
01309 size_t size=radial_mask.size();
01310 for (size_t i = 0; i < size; i++) {
01311 radial_mask[i] = intercept + ((slope - intercept) * i) / (size - 1.0f);
01312 x += step;
01313 }
01314 }
01315
01316
01317 void RealPixelProcessor::process_inplace(EMData * image)
01318 {
01319 if (!image) {
01320 LOGWARN("NULL Image");
01321 return;
01322 }
01323
01324 maxval = image->get_attr("maximum");
01325 mean = image->get_attr("mean");
01326 sigma = image->get_attr("sigma");
01327
01328 calc_locals(image);
01329
01330 size_t size = (size_t)image->get_xsize() *
01331 (size_t)image->get_ysize() *
01332 (size_t)image->get_zsize();
01333 float *data = image->get_data();
01334
01335 for (size_t i = 0; i < size; i++) {
01336 process_pixel(&data[i]);
01337 }
01338 image->update();
01339 }
01340
01341 void CoordinateProcessor::process_inplace(EMData * image)
01342 {
01343 if (!image) {
01344 LOGWARN("NULL Image");
01345 return;
01346 }
01347
01348 maxval = image->get_attr("maximum");
01349 mean = image->get_attr("mean");
01350 sigma = image->get_attr("sigma");
01351 nx = image->get_xsize();
01352 ny = image->get_ysize();
01353 nz = image->get_zsize();
01354 is_complex = image->is_complex();
01355
01356 calc_locals(image);
01357
01358
01359 if (!is_valid()) {
01360 return;
01361 }
01362
01363 float *data = image->get_data();
01364 size_t i = 0;
01365
01366 for (int z = 0; z < nz; z++) {
01367 for (int y = 0; y < ny; y++) {
01368 for (int x = 0; x < nx; x++) {
01369 process_pixel(&data[i], x, y, z);
01370 ++i;
01371 }
01372 }
01373 }
01374 image->update();
01375 }
01376
01377 void PaintProcessor::process_inplace(EMData *image) {
01378 int nx=image->get_xsize();
01379 int ny=image->get_ysize();
01380 int nz=image->get_zsize();
01381
01382 if (nz==1) {
01383 float r;
01384 for (int j=(y<r2?0:y-r2); j<(y+r2>ny?ny:y+r2); j++) {
01385 for (int i=(x<r2?0:x-r2); i<(x+r2>nx?nx:x+r2); i++) {
01386 r=sqrt(float(Util::square(i-x)+Util::square(j-y)));
01387 if (r>r2 && r>r1) continue;
01388 if (r>r1) image->set_value_at(i,j,0,v2*(r-r1)/(r2-r1)+v1*(r2-r)/(r2-r1));
01389 else image->set_value_at(i,j,0,v1);
01390 }
01391 }
01392 }
01393 else {
01394 float r;
01395 for (int k=(z<r2?0:z-r2); k<(z+r2>nz?nz:z+r2); k++) {
01396 for (int j=(y<r2?0:y-r2); j<(y+r2>ny?ny:y+r2); j++) {
01397 for (int i=(x<r2?0:x-r2); i<(x+r2>nx?nx:x+r2); i++) {
01398 r=sqrt(float(Util::square(i-x)+Util::square(j-y)+Util::square(k-z)));
01399 if (r>r2 && r>r1) continue;
01400 if (r>r1) image->set_value_at(i,j,k,v2*(r-r1)/(r2-r1)+v1*(r2-r)/(r2-r1));
01401 else image->set_value_at(i,j,k,v1);
01402 }
01403 }
01404 }
01405 }
01406 image->update();
01407 }
01408
01409 void WatershedProcessor::process_inplace(EMData * image) {
01410 vector<float> xpoints = params["xpoints"];
01411 vector<float> ypoints = params["ypoints"];
01412 vector<float> zpoints = params["zpoints"];
01413
01414 vector<int> x(xpoints.begin(),xpoints.end());
01415 vector<int> y(ypoints.begin(),ypoints.end());
01416 vector<int> z(zpoints.begin(),zpoints.end());
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430 float minval = params["minval"];
01431
01432 EMData* mask = new EMData(*image);
01433 mask->to_zero();
01434
01435
01436 for(unsigned int i = 0; i < xpoints.size(); ++i) {
01437 try {
01438 mask->set_value_at(x[i],y[i],z[i], (float)(i+1));
01439 } catch (...) {
01440 continue;
01441 }
01442 }
01443 mask->write_image("seeds2.mrc");
01444
01445
01446
01447
01448
01449
01450
01451 while( true ) {
01452 bool cont= false;
01453 for(unsigned int j = 0; j < xpoints.size(); ++j)
01454 {
01455
01456 Vec3i coord(x[j],y[j],z[j]);
01457 vector<Vec3i> region;
01458 region.push_back(coord);
01459 vector<Vec3i> find_region_input = region;
01460 while (true) {
01461 vector<Vec3i> v = find_region(mask,find_region_input, j+1, region);
01462 if (v.size() == 0 ) break;
01463 else find_region_input = v;
01464 }
01465
01466 vector<Vec3i> tmp(region.begin(),region.end());
01467 region.clear();
01468 for(vector<Vec3i>::const_iterator it = tmp.begin(); it != tmp.end(); ++it ) {
01469 vector<Vec3i> tmp2 = watershed(mask, image, minval, *it, j+1);
01470 copy(tmp2.begin(),tmp2.end(),back_inserter(region));
01471 }
01472 if (region.size() != 0) cont = true;
01473 }
01474
01475 if (!cont) break;
01476 }
01477
01478
01479 memcpy(image->get_data(),mask->get_data(),sizeof(float)*image->get_size());
01480 image->update();
01481 }
01482
01483
01484 vector<Vec3i > WatershedProcessor::find_region(EMData* mask,const vector<Vec3i >& coords, const int mask_value, vector<Vec3i >& region)
01485 {
01486 static vector<Vec3i> two_six_connected;
01487 if (two_six_connected.size() == 0) {
01488 for(int i = -1; i <= 1; ++i) {
01489 for(int j = -1; j <= 1; ++j) {
01490 for(int k = -1; k <= 1; ++k) {
01491 if ( j != 0 || i != 0 || k != 0) {
01492 two_six_connected.push_back(Vec3i(i,j,k));
01493 }
01494 }
01495 }
01496 }
01497 }
01498
01499 vector<Vec3i> ret;
01500 for(vector<Vec3i>::const_iterator it = two_six_connected.begin(); it != two_six_connected.end(); ++it ) {
01501 for(vector<Vec3i>::const_iterator it2 = coords.begin(); it2 != coords.end(); ++it2 ) {
01502 if (mask->get_value_at((*it2)[0],(*it2)[1],(*it2)[2]) != mask_value) throw;
01503 Vec3i c = (*it)+(*it2);
01504
01505 if ( c[0] < 0 || c[0] >= mask->get_xsize()) continue;
01506 if ( c[1] < 0 || c[1] >= mask->get_ysize()) continue;
01507 if ( c[2] < 0 || c[2] >= mask->get_zsize()) continue;
01508
01509 if( mask->get_value_at(c[0],c[1],c[2]) == mask_value ) {
01510 if (find(ret.begin(),ret.end(),c) == ret.end()) {
01511 if (find(region.begin(),region.end(),c) == region.end()) {
01512 region.push_back(c);
01513 ret.push_back(c);
01514 }
01515 }
01516 }
01517 }
01518 }
01519 return ret;
01520 }
01521
01522 vector<Vec3i > WatershedProcessor::watershed(EMData* mask, EMData* image, const float& threshold, const Vec3i& coordinate, const int mask_value)
01523 {
01524 static vector<Vec3i> two_six_connected;
01525 if (two_six_connected.size() == 0) {
01526 for(int i = -1; i <= 1; ++i) {
01527 for(int j = -1; j <= 1; ++j) {
01528 for(int k = -1; k <= 1; ++k) {
01529 if ( j != 0 || i != 0 || k != 0) {
01530 two_six_connected.push_back(Vec3i(i,j,k));
01531 }
01532 }
01533 }
01534 }
01535 }
01536
01537 if (mask->get_value_at(coordinate[0],coordinate[1],coordinate[2]) != mask_value) throw;
01538
01539 vector<Vec3i> ret;
01540 for(vector<Vec3i>::const_iterator it = two_six_connected.begin(); it != two_six_connected.end(); ++it ) {
01541 Vec3i c = (*it)+coordinate;
01542
01543 if ( c[0] < 0 || c[0] >= image->get_xsize()) continue;
01544 if ( c[1] < 0 || c[1] >= image->get_ysize()) continue;
01545 if ( c[2] < 0 || c[2] >= image->get_zsize()) continue;
01546
01547
01548 if( image->get_value_at(c[0],c[1],c[2]) != 0 && (mask->get_value_at(c[0],c[1],c[2]) == 0 )) {
01549
01550 mask->set_value_at(c[0],c[1],c[2], (float)mask_value);
01551 ret.push_back(c);
01552 }
01553 }
01554 return ret;
01555 }
01556
01557
01558 void CircularMaskProcessor::calc_locals(EMData *)
01559 {
01560 xc = nx / 2.0f + dx;
01561 yc = ny / 2.0f + dy;
01562 zc = nz / 2.0f + dz;
01563
01564
01565 if (outer_radius <= 0) {
01566 outer_radius = nx / 2;
01567 outer_radius_square = outer_radius * outer_radius;
01568 }
01569
01570 if (inner_radius <= 0) {
01571 inner_radius_square = 0;
01572 }
01573 }
01574
01575
01576 void MaskEdgeMeanProcessor::calc_locals(EMData * image)
01577 {
01578 if (!image) {
01579 throw NullPointerException("NULL image");
01580 }
01581 int nitems = 0;
01582 float sum = 0;
01583 float *data = image->get_data();
01584 size_t i = 0;
01585
01586 for (int z = 0; z < nz; ++z) {
01587 for (int y = 0; y < ny; ++y) {
01588 for (int x = 0; x < nx; ++x) {
01589 float x1 = sqrt((x - xc) * (x - xc) + (y - yc) * (y - yc) + (z - zc) * (z - zc));
01590 if (x1 <= outer_radius + ring_width && x1 >= outer_radius - ring_width) {
01591 sum += data[i];
01592 ++nitems;
01593 }
01594 ++i;
01595 }
01596 }
01597 }
01598
01599 ring_avg = sum / nitems;
01600 }
01601
01602 void ToMinvalProcessor::process_inplace(EMData * image)
01603 {
01604 if (!image) {
01605 LOGWARN("NULL Image");
01606 return;
01607 }
01608
01609 float minval = params.set_default("minval",0.0f);
01610 float newval = params.set_default("newval",minval);
01611
01612 size_t size = (size_t)image->get_xsize() *
01613 (size_t)image->get_ysize() *
01614 (size_t)image->get_zsize();
01615 float *data = image->get_data();
01616
01617
01618
01619 for (size_t i = 0; i < size; i++) {
01620 if (data[i]<minval) data[i]=newval;
01621 }
01622 image->update();
01623 }
01624
01625
01626 void ComplexPixelProcessor::process_inplace(EMData * image)
01627 {
01628 if (!image) {
01629 LOGWARN("NULL image");
01630 return;
01631 }
01632 if (!image->is_complex()) {
01633 LOGWARN("cannot apply complex processor on a real image. Nothing is done.");
01634 return;
01635 }
01636
01637 size_t size = (size_t)image->get_xsize() *
01638 (size_t)image->get_ysize() *
01639 (size_t)image->get_zsize();
01640 float *data = image->get_data();
01641
01642 image->ri2ap();
01643
01644 for (size_t i = 0; i < size; i += 2) {
01645 process_pixel(data);
01646 data += 2;
01647 }
01648
01649 image->update();
01650 image->ap2ri();
01651 }
01652
01653
01654
01655 void AreaProcessor::process_inplace(EMData * image)
01656 {
01657 if (!image) {
01658 LOGWARN("NULL Image");
01659 return;
01660 }
01661
01662 float *data = image->get_data();
01663
01664 nx = image->get_xsize();
01665 ny = image->get_ysize();
01666 nz = image->get_zsize();
01667
01668 int n = (areasize - 1) / 2;
01669 matrix_size = areasize * areasize;
01670
01671 if (nz > 1) {
01672 matrix_size *= areasize;
01673 }
01674
01675 float *matrix = new float[matrix_size];
01676 kernel = new float[matrix_size];
01677
01678 int cpysize = areasize * (int) sizeof(float);
01679 int start = (nx * ny + nx + 1) * n;
01680
01681 int xend = nx - n;
01682 int yend = ny - n;
01683
01684 int zstart = n;
01685 int zend = nz - n;
01686
01687 int zbox_start = 0;
01688 int zbox_end = areasize;
01689
01690 if (nz == 1) {
01691 zstart = 0;
01692 zend = 1;
01693 zbox_end = 1;
01694 }
01695
01696 size_t nsec = (size_t)nx * (size_t)ny;
01697 int box_nsec = areasize * areasize;
01698
01699 create_kernel();
01700
01701 size_t total_size = (size_t)nx * (size_t)ny * (size_t)nz;
01702 float *data2 = new float[total_size];
01703 memcpy(data2, data, total_size * sizeof(float));
01704
01705 size_t k;
01706 for (int z = zstart; z < zend; z++) {
01707 for (int y = n; y < yend; y++) {
01708 for (int x = n; x < xend; x++) {
01709
01710 k = z * nsec + y * nx + x;
01711
01712 for (int bz = zbox_start; bz < zbox_end; bz++) {
01713 for (int by = 0; by < areasize; by++) {
01714 memcpy(&matrix[bz * box_nsec + by * areasize],
01715 &data2[k - start + bz * nsec + by * nx], cpysize);
01716 }
01717 }
01718
01719 process_pixel(&data[k], (float) x, (float) y, (float) z, matrix);
01720 }
01721 }
01722 }
01723
01724 if( matrix )
01725 {
01726 delete[]matrix;
01727 matrix = 0;
01728 }
01729
01730 if( kernel )
01731 {
01732 delete[]kernel;
01733 kernel = 0;
01734 }
01735 image->update();
01736 }
01737
01738
01739 void LaplacianProcessor::create_kernel() const
01740 {
01741 if (nz == 1) {
01742 memset(kernel, 0, areasize * areasize);
01743 kernel[1] = -0.25f;
01744 kernel[3] = -0.25f;
01745 kernel[5] = -0.25f;
01746 kernel[7] = -0.25f;
01747 kernel[4] = 1;
01748 }
01749 else {
01750 memset(kernel, 0, areasize * areasize * areasize);
01751 kernel[4] = -1.0f / 6.0f;
01752 kernel[10] = -1.0f / 6.0f;
01753 kernel[12] = -1.0f / 6.0f;
01754 kernel[14] = -1.0f / 6.0f;
01755 kernel[16] = -1.0f / 6.0f;
01756 kernel[22] = -1.0f / 6.0f;
01757 kernel[13] = 1;
01758 }
01759 }
01760
01761 void BoxStatProcessor::process_inplace(EMData * image)
01762 {
01763 if (!image) {
01764 LOGWARN("NULL Image");
01765 return;
01766 }
01767
01768 int nx = image->get_xsize();
01769 int ny = image->get_ysize();
01770 int nz = image->get_zsize();
01771
01772 int n = params.set_default("radius",1);
01773 int areasize = 2 * n + 1;
01774
01775 int matrix_size = areasize * areasize;
01776 if (nz > 1) {
01777 matrix_size *= areasize;
01778 }
01779
01780 float *array = new float[matrix_size];
01781
01782
01783 float *data = image->get_data();
01784 size_t total_size = (size_t)nx * (size_t)ny * (size_t)nz;
01785 float *data2 = new float[total_size];
01786 memcpy(data2, data, total_size * sizeof(float));
01787
01788 int z_begin = 0;
01789 int z_end = 1;
01790 int nzz=0;
01791 if (nz > 1) {
01792 z_begin = n;
01793 z_end = nz - n;
01794 nzz=n;
01795 }
01796
01797 int nxy = nx * ny;
01798
01799 for (int k = z_begin; k < z_end; k++) {
01800 size_t knxy = k * nxy;
01801
01802 for (int j = n; j < ny - n; j++) {
01803 int jnx = j * nx;
01804
01805 for (int i = n; i < nx - n; i++) {
01806 size_t s = 0;
01807
01808 for (int i2 = i - n; i2 <= i + n; i2++) {
01809 for (int j2 = j - n; j2 <= j + n; j2++) {
01810 for (int k2 = k - nzz; k2 <= k + nzz; k2++) {
01811 array[s] = data2[i2 + j2 * nx + k2 * nxy];
01812 ++s;
01813 }
01814 }
01815 }
01816
01817 process_pixel(&data[i + jnx + knxy], array, matrix_size);
01818 }
01819 }
01820 }
01821
01822 image->update();
01823
01824 if( data2 )
01825 {
01826 delete[]data2;
01827 data2 = 0;
01828 }
01829 }
01830
01831 void DiffBlockProcessor::process_inplace(EMData * image)
01832 {
01833 if (!image) {
01834 LOGWARN("NULL Image");
01835 return;
01836 }
01837
01838 int nz = image->get_zsize();
01839
01840 if (nz > 1) {
01841 LOGERR("%s Processor doesn't support 3D", get_name().c_str());
01842 throw ImageDimensionException("3D model not supported");
01843 }
01844
01845 int nx = image->get_xsize();
01846 int ny = image->get_ysize();
01847
01848 int v1 = params["cal_half_width"];
01849 int v2 = params["fill_half_width"];
01850
01851 int v0 = v1 > v2 ? v1 : v2;
01852
01853 if (v2 <= 0) {
01854 v2 = v1;
01855 }
01856
01857 float *data = image->get_data();
01858
01859 for (int y = v0; y <= ny - v0 - 1; y += v2) {
01860 for (int x = v0; x <= nx - v0 - 1; x += v2) {
01861
01862 float sum = 0;
01863 for (int y1 = y - v1; y1 <= y + v1; y1++) {
01864 for (int x1 = x - v1; x1 <= x + v1; x1++) {
01865 sum += data[x1 + y1 * nx];
01866 }
01867 }
01868 float mean = sum / ((v1 * 2 + 1) * (v1 * 2 + 1));
01869
01870 for (int j = y - v2; j <= y + v2; j++) {
01871 for (int i = x - v2; i <= x + v2; i++) {
01872 data[i + j * nx] = mean;
01873 }
01874 }
01875 }
01876 }
01877
01878 image->update();
01879 }
01880
01881
01882 void CutoffBlockProcessor::process_inplace(EMData * image)
01883 {
01884 if (!image) {
01885 LOGWARN("NULL Image");
01886 return;
01887 }
01888 int nz = image->get_zsize();
01889
01890 if (nz > 1) {
01891 LOGERR("%s Processor doesn't support 3D", get_name().c_str());
01892 throw ImageDimensionException("3D model not supported");
01893 }
01894
01895 int nx = image->get_xsize();
01896 int ny = image->get_ysize();
01897
01898 float value1 = params["value1"];
01899 float value2 = params["value2"];
01900
01901 int v1 = (int) value1;
01902 int v2 = (int) value2;
01903 if (v2 > v1 / 2) {
01904 LOGERR("invalid value2 '%f' in CutoffBlockProcessor", value2);
01905 return;
01906 }
01907
01908 if (v2 <= 0) {
01909 v2 = v1;
01910 }
01911
01912 float *data = image->get_data();
01913 int y = 0, x = 0;
01914 for (y = 0; y <= ny - v1; y += v1) {
01915 for (x = 0; x <= nx - v1; x += v1) {
01916
01917 EMData *clip = image->get_clip(Region(x, y, v1, v1));
01918 EMData *fft = clip->do_fft();
01919
01920 float *fft_data = fft->get_data();
01921 float sum = 0;
01922 int nitems = 0;
01923
01924 for (int i = -v2; i < v2; i++) {
01925 for (int j = 0; j < v2; j++) {
01926 if (j == 0 && i == 0) {
01927 continue;
01928 }
01929
01930 #ifdef _WIN32
01931 if (_hypot(j, i) < value2) {
01932 #else
01933 if (hypot(j, i) < value2) {
01934 #endif
01935 int t = j * 2 + (i + v1 / 2) * (v1 + 2);
01936 sum += (fft_data[t] * fft_data[t] + fft_data[t + 1] * fft_data[t + 1]);
01937 nitems++;
01938 }
01939 }
01940 }
01941
01942 if( clip )
01943 {
01944 delete clip;
01945 clip = 0;
01946 }
01947
01948 float mean = sum / nitems;
01949
01950 for (int i = y; i < y + v1; i++) {
01951 for (int j = x; j < x + v1; j++) {
01952 data[i * nx + j] = mean;
01953 }
01954 }
01955 }
01956 }
01957
01958 memset(&data[y * nx], 0, (ny - y) * nx * sizeof(float));
01959
01960 for (int i = 0; i < ny; i++) {
01961 memset(&data[i * nx + x], 0, (nx - x) * sizeof(float));
01962 }
01963
01964 image->update();
01965 }
01966
01967 void MedianShrinkProcessor::process_inplace(EMData * image)
01968 {
01969 if (image->is_complex()) throw ImageFormatException("Error, the median shrink processor does not work on complex images");
01970
01971 int shrink_factor = params.set_default("n",0);
01972 if (shrink_factor <= 1) {
01973 throw InvalidValueException(shrink_factor,
01974 "median shrink: shrink factor must > 1");
01975 }
01976
01977 int nx = image->get_xsize();
01978 int ny = image->get_ysize();
01979 int nz = image->get_zsize();
01980
01981
01982
01983
01984
01985
01986 int shrunken_nx = nx / shrink_factor;
01987 int shrunken_ny = ny / shrink_factor;
01988 int shrunken_nz = 1;
01989 if (nz > 1) shrunken_nz = nz / shrink_factor;
01990
01991 EMData* copy = image->copy();
01992 image->set_size(shrunken_nx, shrunken_ny, shrunken_nz);
01993 accrue_median(image,copy,shrink_factor);
01994 image->update();
01995 if( copy )
01996 {
01997 delete copy;
01998 copy = 0;
01999 }
02000 }
02001
02002
02003 EMData* MedianShrinkProcessor::process(const EMData *const image)
02004 {
02005 if (image->is_complex()) throw ImageFormatException("Error, the median shrink processor does not work on complex images");
02006
02007 int shrink_factor = params.set_default("n",0);
02008 if (shrink_factor <= 1) {
02009 throw InvalidValueException(shrink_factor,
02010 "median shrink: shrink factor must > 1");
02011 }
02012 int nx = image->get_xsize();
02013 int ny = image->get_ysize();
02014 int nz = image->get_zsize();
02015
02016
02017
02018
02019
02020
02021
02022 int shrunken_nx = nx / shrink_factor;
02023 int shrunken_ny = ny / shrink_factor;
02024 int shrunken_nz = 1;
02025 if (nz > 1) shrunken_nz = nz / shrink_factor;
02026
02027
02028 EMData *ret = image->copy_head();
02029 ret->set_size(shrunken_nx, shrunken_ny, shrunken_nz);
02030
02031 accrue_median(ret,image,shrink_factor);
02032 ret->update();
02033 return ret;
02034 }
02035
02036 void MedianShrinkProcessor::accrue_median(EMData* to, const EMData* const from,const int shrink_factor)
02037 {
02038
02039 int nx_old = from->get_xsize();
02040 int ny_old = from->get_ysize();
02041
02042 int threed_shrink_factor = shrink_factor * shrink_factor;
02043 int z_shrink_factor = 1;
02044 if (from->get_zsize() > 1) {
02045 threed_shrink_factor *= shrink_factor;
02046 z_shrink_factor = shrink_factor;
02047 }
02048
02049 float *mbuf = new float[threed_shrink_factor];
02050
02051
02052 int nxy_old = nx_old * ny_old;
02053
02054 int nx = to->get_xsize();
02055 int ny = to->get_ysize();
02056 int nz = to->get_zsize();
02057 int nxy_new = nx * ny;
02058
02059 float * rdata = to->get_data();
02060 const float *const data_copy = from->get_const_data();
02061
02062 for (int l = 0; l < nz; l++) {
02063 int l_min = l * shrink_factor;
02064 int l_max = l * shrink_factor + z_shrink_factor;
02065 int cur_l = l * nxy_new;
02066
02067 for (int j = 0; j < ny; j++) {
02068 int j_min = j * shrink_factor;
02069 int j_max = (j + 1) * shrink_factor;
02070 int cur_j = j * nx + cur_l;
02071
02072 for (int i = 0; i < nx; i++) {
02073 int i_min = i * shrink_factor;
02074 int i_max = (i + 1) * shrink_factor;
02075
02076 int k = 0;
02077 for (int l2 = l_min; l2 < l_max; l2++) {
02078 int cur_l2 = l2 * nxy_old;
02079
02080 for (int j2 = j_min; j2 < j_max; j2++) {
02081 int cur_j2 = j2 * nx_old + cur_l2;
02082
02083 for (int i2 = i_min; i2 < i_max; i2++) {
02084 mbuf[k] = data_copy[i2 + cur_j2];
02085 ++k;
02086 }
02087 }
02088 }
02089
02090 for (k = 0; k < threed_shrink_factor / 2 + 1; k++) {
02091 for (int i2 = k + 1; i2 < threed_shrink_factor; i2++) {
02092 if (mbuf[i2] < mbuf[k]) {
02093 float f = mbuf[i2];
02094 mbuf[i2] = mbuf[k];
02095 mbuf[k] = f;
02096 }
02097 }
02098 }
02099
02100 rdata[i + cur_j] = mbuf[threed_shrink_factor / 2];
02101 }
02102 }
02103 }
02104
02105 if( mbuf )
02106 {
02107 delete[]mbuf;
02108 mbuf = 0;
02109 }
02110
02111 to->scale_pixel((float)shrink_factor);
02112 }
02113
02114 EMData* FFTResampleProcessor::process(const EMData *const image)
02115 {
02116 float sample_rate = params.set_default("n",0.0f);
02117 if (sample_rate <= 0.0F ) {
02118 throw InvalidValueException(sample_rate, "sample rate must be >0 ");
02119 }
02120
02121 EMData* result;
02122 if (image->is_complex()) result = image->copy();
02123 else result = image->do_fft();
02124 fft_resample(result,image,sample_rate);
02125
02126 result->update();
02127 result->scale_pixel(sample_rate);
02128 return result;
02129 }
02130
02131 void FFTResampleProcessor::process_inplace(EMData * image)
02132 {
02133 if (image->is_complex()) throw ImageFormatException("Error, the fft resampling processor does not work on complex images");
02134
02135
02136 float sample_rate = params.set_default("n",0.0f);
02137 if (sample_rate <= 0.0F ) {
02138 throw InvalidValueException(sample_rate, "sample rate (n) must be >0 ");
02139 }
02140
02141 fft_resample(image,image,sample_rate);
02142
02143 image->scale_pixel(sample_rate);
02144 image->update();
02145
02146
02147 }
02148
02149 void FFTResampleProcessor::fft_resample(EMData* to, const EMData *const from, const float& sample_rate) {
02150 int nx = from->get_xsize();
02151 int ny = from->get_ysize();
02152 int nz = from->get_zsize();
02153
02154 int new_nx = static_cast<int>( static_cast<float> (nx) / sample_rate);
02155 int new_ny = static_cast<int>( static_cast<float> (ny) / sample_rate);
02156 int new_nz = static_cast<int>( static_cast<float> (nz) / sample_rate);
02157
02158 if (new_nx == 0) throw UnexpectedBehaviorException("The resample rate causes the pixel dimensions in the x direction to go to zero");
02159 if (new_ny == 0) new_ny = 1;
02160 if (new_nz == 0) new_nz = 1;
02161
02162 int ndim = from->get_ndim();
02163 if ( ndim < 3 ) {
02164 new_nz = 1;
02165 }
02166 if ( ndim < 2 ) {
02167 new_ny = 1;
02168 }
02169
02170 int fft_x_correction = 1;
02171 if (new_nx % 2 == 0) fft_x_correction = 2;
02172
02173 int fft_y_correction = 0;
02174 if (ny != 1 && new_ny % 2 == 0 && ny % 2 == 1) fft_y_correction = 1;
02175 else if (ny != 1 && new_ny % 2 == 1 && ny % 2 == 0) fft_y_correction = -1;
02176
02177 int fft_z_correction = 0;
02178 if (nz != 1 && new_nz % 2 == 0 && nz % 2 == 1) fft_z_correction = 1;
02179 else if (nz != 1 && new_nz % 2 == 1 && nz % 2 == 0) fft_z_correction = -1;
02180
02181 if ( ! to->is_complex()) to->do_fft_inplace();
02182
02183 if (ndim != 1) to->process_inplace("xform.fourierorigin.tocenter");
02184
02185 Region clip(0,(ny-new_ny)/2-fft_y_correction,(nz-new_nz)/2-fft_z_correction,new_nx+fft_x_correction,new_ny,new_nz);
02186 to->clip_inplace(clip);
02187
02188 if (fft_x_correction == 1) to->set_fftodd(true);
02189 else to->set_fftodd(false);
02190
02191 if (ndim != 1) to->process_inplace("xform.fourierorigin.tocorner");
02192
02193 to->do_ift_inplace();
02194 to->depad_corner();
02195
02196 }
02197
02198
02199 EMData* MeanShrinkProcessor::process(const EMData *const image)
02200 {
02201 if (image->is_complex()) throw ImageFormatException("Error, the mean shrink processor does not work on complex images");
02202
02203 if (image->get_ndim() == 1) { throw ImageDimensionException("Error, mean shrink works only for 2D & 3D images"); }
02204
02205 float shrink_factor0 = params.set_default("n",0.0f);
02206 int shrink_factor = int(shrink_factor0);
02207 if (shrink_factor0 <= 1.0F || ((shrink_factor0 != shrink_factor) && (shrink_factor0 != 1.5F) ) ) {
02208 throw InvalidValueException(shrink_factor0,
02209 "mean shrink: shrink factor must be >1 integer or 1.5");
02210 }
02211
02212 int nx = image->get_xsize();
02213 int ny = image->get_ysize();
02214 int nz = image->get_zsize();
02215
02216
02217
02218 if (shrink_factor0==1.5 ) {
02219 if (nz > 1 ) throw InvalidValueException(shrink_factor0, "mean shrink: only support 2D images for shrink factor = 1.5");
02220
02221 int shrunken_nx = (int(nx / 1.5)+1)/2*2;
02222 int shrunken_ny = (int(ny / 1.5)+1)/2*2;
02223 EMData* result = new EMData(shrunken_nx,shrunken_ny,1);
02224
02225 accrue_mean_one_p_five(result,image);
02226 result->update();
02227
02228 return result;
02229 }
02230
02231 int shrunken_nx = nx / shrink_factor;
02232 int shrunken_ny = ny / shrink_factor;
02233 int shrunken_nz = 1;
02234
02235 if (nz > 1) {
02236 shrunken_nz = nz / shrink_factor;
02237 }
02238
02239
02240 EMData* result = image->copy_head();
02241 result->set_size(shrunken_nx,shrunken_ny,shrunken_nz);
02242 accrue_mean(result,image,shrink_factor);
02243
02244 result->update();
02245
02246 return result;
02247 }
02248
02249 void MeanShrinkProcessor::process_inplace(EMData * image)
02250 {
02251 if (image->is_complex()) throw ImageFormatException("Error, the mean shrink processor does not work on complex images");
02252
02253 if (image->get_ndim() == 1) { throw ImageDimensionException("Error, mean shrink works only for 2D & 3D images"); }
02254
02255 float shrink_factor0 = params.set_default("n",0.0f);
02256 int shrink_factor = int(shrink_factor0);
02257 if (shrink_factor0 <= 1.0F || ((shrink_factor0 != shrink_factor) && (shrink_factor0 != 1.5F) ) ) {
02258 throw InvalidValueException(shrink_factor0,
02259 "mean shrink: shrink factor must be >1 integer or 1.5");
02260 }
02261
02262
02263
02264
02265
02266
02267
02268 int nx = image->get_xsize();
02269 int ny = image->get_ysize();
02270 int nz = image->get_zsize();
02271
02272 if (shrink_factor0==1.5 ) {
02273 if (nz > 1 ) throw InvalidValueException(shrink_factor0, "mean shrink: only support 2D images for shrink factor = 1.5");
02274
02275 int shrunken_nx = (int(nx / 1.5)+1)/2*2;
02276 int shrunken_ny = (int(ny / 1.5)+1)/2*2;
02277
02278 EMData* orig = image->copy();
02279 image->set_size(shrunken_nx, shrunken_ny, 1);
02280 image->to_zero();
02281
02282 accrue_mean_one_p_five(image,orig);
02283
02284 if( orig ) {
02285 delete orig;
02286 orig = 0;
02287 }
02288 image->update();
02289
02290 return;
02291 }
02292
02293 accrue_mean(image,image,shrink_factor);
02294
02295 int shrunken_nx = nx / shrink_factor;
02296 int shrunken_ny = ny / shrink_factor;
02297 int shrunken_nz = 1;
02298 if (nz > 1) shrunken_nz = nz / shrink_factor;
02299
02300 image->update();
02301 image->set_size(shrunken_nx, shrunken_ny, shrunken_nz);
02302 }
02303
02304 void MeanShrinkProcessor::accrue_mean(EMData* to, const EMData* const from,const int shrink_factor)
02305 {
02306 const float * const data = from->get_const_data();
02307 float* rdata = to->get_data();
02308
02309 int nx = from->get_xsize();
02310 int ny = from->get_ysize();
02311 int nz = from->get_zsize();
02312 int nxy = nx*ny;
02313
02314
02315 int shrunken_nx = nx / shrink_factor;
02316 int shrunken_ny = ny / shrink_factor;
02317 int shrunken_nz = 1;
02318 int shrunken_nxy = shrunken_nx * shrunken_ny;
02319
02320 int normalize_shrink_factor = shrink_factor * shrink_factor;
02321 int z_shrink_factor = 1;
02322
02323 if (nz > 1) {
02324 shrunken_nz = nz / shrink_factor;
02325 normalize_shrink_factor *= shrink_factor;
02326 z_shrink_factor = shrink_factor;
02327 }
02328
02329 float invnormfactor = 1.0f/(float)normalize_shrink_factor;
02330
02331 for (int k = 0; k < shrunken_nz; k++) {
02332 int k_min = k * shrink_factor;
02333 int k_max = k * shrink_factor + z_shrink_factor;
02334 size_t cur_k = k * shrunken_nxy;
02335
02336 for (int j = 0; j < shrunken_ny; j++) {
02337 int j_min = j * shrink_factor;
02338 int j_max = j * shrink_factor + shrink_factor;
02339 size_t cur_j = j * shrunken_nx + cur_k;
02340
02341 for (int i = 0; i < shrunken_nx; i++) {
02342 int i_min = i * shrink_factor;
02343 int i_max = i * shrink_factor + shrink_factor;
02344
02345 float sum = 0;
02346 for (int kk = k_min; kk < k_max; kk++) {
02347 size_t cur_kk = kk * nxy;
02348
02349 for (int jj = j_min; jj < j_max; jj++) {
02350 size_t cur_jj = jj * nx + cur_kk;
02351 for (int ii = i_min; ii < i_max; ii++) {
02352 sum += data[ii + cur_jj];
02353 }
02354 }
02355 }
02356 rdata[i + cur_j] = sum * invnormfactor;
02357 }
02358 }
02359 }
02360 to->scale_pixel((float)shrink_factor);
02361 }
02362
02363
02364 void MeanShrinkProcessor::accrue_mean_one_p_five(EMData* to, const EMData * const from)
02365 {
02366 int nx0 = from->get_xsize(), ny0 = from->get_ysize();
02367
02368 int nx = to->get_xsize(), ny = to->get_ysize();
02369
02370 float *data = to->get_data();
02371 const float * const data0 = from->get_const_data();
02372
02373 for (int j = 0; j < ny; j++) {
02374 int jj = int(j * 1.5);
02375 float jw0 = 1.0F, jw1 = 0.5F;
02376 if ( j%2 ) {
02377 jw0 = 0.5F;
02378 jw1 = 1.0F;
02379 }
02380 for (int i = 0; i < nx; i++) {
02381 int ii = int(i * 1.5);
02382 float iw0 = 1.0F, iw1 = 0.5F;
02383 float w = 0.0F;
02384
02385 if ( i%2 ) {
02386 iw0 = 0.5F;
02387 iw1 = 1.0F;
02388 }
02389 if ( jj < ny0 ) {
02390 if ( ii < nx0 ) {
02391 data[j * nx + i] = data0[ jj * nx0 + ii ] * jw0 * iw0 ;
02392 w += jw0 * iw0 ;
02393 if ( ii+1 < nx0 ) {
02394 data[j * nx + i] += data0[ jj * nx0 + ii + 1] * jw0 * iw1;
02395 w += jw0 * iw1;
02396 }
02397 }
02398 if ( jj +1 < ny0 ) {
02399 if ( ii < nx0 ) {
02400 data[j * nx + i] += data0[ (jj+1) * nx0 + ii ] * jw1 * iw0;
02401 w += jw1 * iw0;
02402 if ( ii+1 < nx0 ) {
02403 data[j * nx + i] += data0[ (jj+1) * nx0 + ii + 1] * jw1 * iw1;
02404 w += jw1 * iw1;
02405 }
02406 }
02407 }
02408 }
02409 if ( w>0 ) data[j * nx + i] /= w;
02410 }
02411 }
02412
02413 to->update();
02414 to->scale_pixel((float)1.5);
02415 }
02416
02417
02418 template<class LogicOp>
02419 EMData* BooleanShrinkProcessor::process(const EMData *const image, Dict& params)
02420 {
02421
02422
02423
02424 if (!image) throw NullPointerException("Attempt to max shrink a null image");
02425
02426 if (image->is_complex() ) throw ImageFormatException("Can not max shrink a complex image");
02427
02428
02429 int shrink = params.set_default("n",2);
02430 int search = params.set_default("search",2);
02431
02432 if ( shrink < 0 ) throw InvalidValueException(shrink, "Can not shrink by a value less than 0");
02433
02434
02435 int nz = image->get_zsize();
02436 int ny = image->get_ysize();
02437 int nx = image->get_xsize();
02438
02439 if (nx == 1 && ny == 1 && nz == 1 ) return image->copy();
02440
02441 LogicOp op;
02442 EMData* return_image = new EMData();
02443
02444 int shrinkx = shrink;
02445 int shrinky = shrink;
02446 int shrinkz = shrink;
02447
02448 int searchx = search;
02449 int searchy = search;
02450 int searchz = search;
02451
02452
02453
02454 if ( shrinkx > nx ) shrinkx = nx;
02455 if ( shrinky > ny ) shrinky = ny;
02456 if ( shrinkz > nz ) shrinkz = nz;
02457
02458 if ( nz == 1 && ny == 1 )
02459 {
02460 return_image->set_size(nx/shrinkx);
02461 for(int i = 0; i < nx/shrinkx; ++i)
02462 {
02463 float tmp = op.get_start_val();
02464 for(int s=0; s < searchx; ++s)
02465 {
02466 int idx = shrinkx*i+s;
02467
02468 if ( idx > nx ) break;
02469 else
02470 {
02471 float val = image->get_value_at(idx);
02472 if ( op( val,tmp) ) tmp = val;
02473 }
02474 }
02475 return_image->set_value_at(i,tmp);
02476 }
02477 }
02478 else if ( nz == 1 )
02479 {
02480 int ty = ny/shrinky;
02481 int tx = nx/shrinkx;
02482 return_image->set_size(tx,ty);
02483 for(int y = 0; y < ty; ++y) {
02484 for(int x = 0; x < tx; ++x) {
02485 float tmp = op.get_start_val();
02486 for(int sy=0; sy < searchy; ++sy) {
02487 int yidx = shrinky*y+sy;
02488 if ( yidx >= ny) break;
02489 for(int sx=0; sx < searchx; ++sx) {
02490 int xidx = shrinkx*x+sx;
02491 if ( xidx >= nx) break;
02492
02493 float val = image->get_value_at(xidx,yidx);
02494 if ( op( val,tmp) ) tmp = val;
02495 }
02496 }
02497 return_image->set_value_at(x,y,tmp);
02498 }
02499 }
02500 }
02501 else
02502 {
02503 int tz = nz/shrinkz;
02504 int ty = ny/shrinky;
02505 int tx = nx/shrinkx;
02506
02507 return_image->set_size(tx,ty,tz);
02508 for(int z = 0; z < tz; ++z) {
02509 for(int y = 0; y < ty; ++y) {
02510 for(int x = 0; x < tx; ++x) {
02511 float tmp = op.get_start_val();
02512
02513 for(int sz=0; sz < searchz; ++sz) {
02514 int zidx = shrinkz*z+sz;
02515 if ( zidx >= nz) break;
02516
02517 for(int sy=0; sy < searchy; ++sy) {
02518 int yidx = shrinky*y+sy;
02519 if ( yidx >= ny) break;
02520
02521 for(int sx=0; sx < searchx; ++sx) {
02522 int xidx = shrinkx*x+sx;
02523 if ( xidx >= nx) break;
02524 float val = image->get_value_at(xidx,yidx,zidx);
02525 if ( op( val,tmp) ) tmp = val;
02526 }
02527 }
02528 }
02529 return_image->set_value_at(x,y,z,tmp);
02530 }
02531 }
02532 }
02533 }
02534 return_image->update();
02535
02536 return return_image;
02537 }
02538
02539 template<class LogicOp>
02540 void BooleanShrinkProcessor::process_inplace(EMData * image, Dict& params)
02541 {
02542
02543
02544 if (!image) throw NullPointerException("Attempt to max shrink a null image");
02545
02546 if (image->is_complex() ) throw ImageFormatException("Can not max shrink a complex image");
02547
02548
02549 int shrink = params.set_default("shrink",2);
02550 int search = params.set_default("search",2);
02551
02552 if ( shrink < 0 ) throw InvalidValueException(shrink, "Can not shrink by a value less than 0");
02553
02554
02555 int nz = image->get_zsize();
02556 int ny = image->get_ysize();
02557 int nx = image->get_xsize();
02558
02559 LogicOp op;
02560
02561 int shrinkx = shrink;
02562 int shrinky = shrink;
02563 int shrinkz = shrink;
02564
02565 int searchx = search;
02566 int searchy = search;
02567 int searchz = search;
02568
02569
02570
02571 if ( shrinkx > nx ) shrinkx = nx;
02572 if ( shrinky > ny ) shrinkx = ny;
02573 if ( shrinkz > nz ) shrinkx = nz;
02574
02575 if (nx == 1 && ny == 1 && nz == 1 ) return;
02576
02577 if ( nz == 1 && ny == 1 )
02578 {
02579 for(int i = 0; i < nx/shrink; ++i)
02580 {
02581 float tmp = op.get_start_val();
02582 for(int s=0; s < searchx; ++s)
02583 {
02584 int idx = shrinkx*i+s;
02585 if ( idx > nx ) break;
02586 else
02587 {
02588 float val = image->get_value_at(idx);
02589 if ( op( val,tmp) ) tmp = val;
02590 }
02591 }
02592 image->set_value_at(i,tmp);
02593 }
02594
02595 image->set_size(nx/shrinkx);
02596 }
02597 else if ( nz == 1 )
02598 {
02599 int ty = ny/shrinky;
02600 int tx = nx/shrinkx;
02601 for(int y = 0; y < ty; ++y) {
02602 for(int x = 0; x < tx; ++x) {
02603 float tmp = op.get_start_val();
02604 for(int sy=0; sy < searchy; ++sy) {
02605 int yidx = shrinky*y+sy;
02606 if ( yidx >= ny) break;
02607 for(int sx=0; sx < searchx; ++sx) {
02608 int xidx = shrinkx*x+sx;
02609 if ( xidx >= nx) break;
02610
02611 float val = image->get_value_at(xidx,yidx);
02612 if ( op( val,tmp) ) tmp = val;
02613 }
02614 }
02615 (*image)(x+tx*y) = tmp;
02616 }
02617 }
02618 image->set_size(tx,ty);
02619 }
02620 else
02621 {
02622 int tnxy = nx/shrinkx*ny/shrinky;
02623 int tz = nz/shrinkz;
02624 int ty = ny/shrinky;
02625 int tx = nx/shrinkx;
02626
02627 for(int z = 0; z < tz; ++z) {
02628 for(int y = 0; y < ty; ++y) {
02629 for(int x = 0; x < tx; ++x) {
02630 float tmp = op.get_start_val();
02631 for(int sz=0; sz < searchz; ++sz) {
02632 int zidx = shrinkz*z+sz;
02633 if ( zidx >= nz) break;
02634 for(int sy=0; sy < searchy; ++sy) {
02635 int yidx = shrinky*y+sy;
02636 if ( yidx >= ny) break;
02637 for(int sx=0; sx < shrinkx; ++sx) {
02638 int xidx = shrinkx*x+sx;
02639 if ( xidx >= nx) break;
02640
02641 float val = image->get_value_at(xidx,yidx,zidx);
02642 if ( op( val,tmp) ) tmp = val;
02643 }
02644 }
02645 }
02646 (*image)(x+tx*y+tnxy*z) = tmp;
02647 }
02648 }
02649 }
02650 image->set_size(tx,ty,tz);
02651 }
02652 image->update();
02653 }
02654
02655
02656
02657 void GradientRemoverProcessor::process_inplace(EMData * image)
02658 {
02659 if (!image) {
02660 LOGWARN("NULL Image");
02661 return;
02662 }
02663
02664 int nz = image->get_zsize();
02665 if (nz > 1) {
02666 LOGERR("%s Processor doesn't support 3D model", get_name().c_str());
02667 throw ImageDimensionException("3D model not supported");
02668 }
02669
02670 int nx = image->get_xsize();
02671 int ny = image->get_ysize();
02672 float *dy = new float[ny];
02673 float m = 0;
02674 float b = 0;
02675 float sum_y = 0;
02676 float *data = image->get_data();
02677
02678 for (int i = 0; i < ny; i++) {
02679 Util::calc_least_square_fit(nx, 0, data + i * nx, &m, &b, false);
02680 dy[i] = b;
02681 sum_y += m;
02682 }
02683
02684 float mean_y = sum_y / ny;
02685 float sum_x = 0;
02686 Util::calc_least_square_fit(ny, 0, dy, &sum_x, &b, false);
02687
02688 for (int j = 0; j < ny; j++) {
02689 for (int i = 0; i < nx; i++) {
02690 data[i + j * nx] -= i * sum_x + j * mean_y + b;
02691 }
02692 }
02693
02694 image->update();
02695 }
02696
02697 void FlattenBackgroundProcessor::process_inplace(EMData * image)
02698 {
02699
02700 EMData* mask = params.set_default("mask",(EMData*)0);
02701 int radius = params.set_default("radius",0);
02702
02703 if (radius != 0 && mask != 0) throw InvalidParameterException("Error - the mask and radius parameters are mutually exclusive.");
02704
02705 if (mask == 0 && radius == 0) throw InvalidParameterException("Error - you must specify either the mask or the radius parameter.");
02706
02707
02708 bool deletemask = false;
02709 if (radius != 0) {
02710 mask = new EMData;
02711 int n = image->get_ndim();
02712 if (n==1){
02713 mask->set_size(2*radius+1);
02714 } else if (n==2) {
02715 mask->set_size(2*radius+1,2*radius+1);
02716 }
02717 else {
02718 mask->set_size(2*radius+1,2*radius+1,2*radius+1);
02719 }
02720
02721 mask->process_inplace("testimage.circlesphere");
02722 }
02723
02724
02725 int mnx = mask->get_xsize(); int mny = mask->get_ysize(); int mnz = mask->get_zsize();
02726 int nx = image->get_xsize(); int ny = image->get_ysize(); int nz = image->get_zsize();
02727 int nxc = nx+mnx; int nyc = ny+mny; int nzc = nz+mnz;
02728 if (nz == 1) nzc = 1;
02729 if (ny == 1) nyc = 1;
02730
02731 if ( mnx > nx || mny > ny || mnz > nz)
02732 throw ImageDimensionException("Can not flatten using a mask that is larger than the image.");
02733
02734
02735 float normfac = 0.0;
02736 for (int i=0; i<mask->get_xsize()*mask->get_ysize()*mask->get_zsize(); ++i){
02737 normfac += mask->get_value_at(i);
02738 }
02739
02740
02741
02742 if (normfac == 0) throw InvalidParameterException("Error - the pixels in the mask sum to zero. This breaks the flattening procedure");
02743 normfac = 1.0f/normfac;
02744
02745
02746
02747
02748 Region r;
02749 if (ny == 1) r = Region((mnx-nxc)/2,nxc);
02750 else if (nz == 1) r = Region((mnx-nxc)/2, (mny-nyc)/2,nxc,nyc);
02751 else r = Region((mnx-nxc)/2, (mny-nyc)/2,(mnz-nzc)/2,nxc,nyc,nzc);
02752 mask->clip_inplace(r,0);
02753
02754
02755
02756
02757
02758
02759
02760 Region r2;
02761 if (ny == 1) r2 = Region((nx-nxc)/2,nxc);
02762 else if (nz == 1) r2 = Region((nx-nxc)/2, (ny-nyc)/2,nxc,nyc);
02763 else r2 = Region((nx-nxc)/2, (ny-nyc)/2,(nz-nzc)/2,nxc,nyc,nzc);
02764 image->clip_inplace(r2,image->get_edge_mean());
02765
02766 EMData* m = image->convolute(mask);
02767
02768 m->mult(normfac);
02769
02770 m->process_inplace("xform.phaseorigin.tocenter");
02771
02772
02773
02774 image->sub(*m);
02775 delete m;
02776
02777 if (deletemask) {
02778 delete mask;
02779 } else {
02780 Region r;
02781 if (ny == 1) r = Region((nxc-mnx)/2,mnx);
02782 else if (nz == 1) r = Region((nxc-mnx)/2, (nyc-mny)/2,mnx,mny);
02783 else r = Region((nxc-mnx)/2, (nyc-mny)/2,(nzc-mnz)/2,mnx,mny,mnz);
02784 mask->clip_inplace(r);
02785 }
02786
02787 Region r3;
02788 if (ny == 1) r3 = Region((nxc-nx)/2,nx);
02789 else if (nz == 1) r3 = Region((nxc-nx)/2, (nyc-ny)/2,nx,ny);
02790 else r3 = Region((nxc-nx)/2, (nyc-ny)/2,(nzc-nz)/2,nx,ny,nz);
02791 image->clip_inplace(r3);
02792
02793
02794
02795
02796
02797 }
02798
02799 #include <gsl/gsl_linalg.h>
02800 void GradientPlaneRemoverProcessor::process_inplace(EMData * image)
02801 {
02802 if (!image) {
02803 LOGWARN("NULL Image");
02804 return;
02805 }
02806
02807 int nz = image->get_zsize();
02808 if (nz > 1) {
02809 LOGERR("%s Processor doesn't support 3D model", get_name().c_str());
02810 throw ImageDimensionException("3D map not supported");
02811 }
02812
02813 int nx = image->get_xsize();
02814 int ny = image->get_ysize();
02815 float *d = image->get_data();
02816 EMData *mask = 0;
02817 float *dm = 0;
02818 if (params.has_key("mask")) {
02819 mask = params["mask"];
02820 if (nx!=mask->get_xsize() || ny!=mask->get_ysize()) {
02821 LOGERR("%s Processor requires same size mask image", get_name().c_str());
02822 throw ImageDimensionException("wrong size mask image");
02823 }
02824 dm = mask->get_data();
02825 }
02826 int count = 0;
02827 if (dm) {
02828 for(int i=0; i<nx*ny; i++) {
02829 if(dm[i]) count++;
02830 }
02831 }
02832 else {
02833 count = nx * ny;
02834 }
02835 if(count<3) {
02836 LOGERR("%s Processor requires at least 3 pixels to fit a plane", get_name().c_str());
02837 throw ImageDimensionException("too few usable pixels to fit a plane");
02838 }
02839
02840 gsl_vector *S=gsl_vector_calloc(3);
02841 gsl_matrix *A=gsl_matrix_calloc(count,3);
02842 gsl_matrix *V=gsl_matrix_calloc(3,3);
02843
02844 double m[3] = {0, 0, 0};
02845 int index=0;
02846 if (dm) {
02847 for(int j=0; j<ny; j++){
02848 for(int i=0; i<nx; i++){
02849 int ij=j*nx+i;
02850 if(dm[ij]) {
02851 m[0]+=i;
02852 m[1]+=j;
02853 m[2]+=d[ij];
02854
02855
02856 index++;
02857 }
02858 }
02859 }
02860 }
02861 else {
02862 for(int j=0; j<ny; j++){
02863 for(int i=0; i<nx; i++){
02864 int ij=j*nx+i;
02865 m[0]+=i;
02866 m[1]+=j;
02867 m[2]+=d[ij];
02868
02869
02870 index++;
02871 }
02872 }
02873 }
02874
02875 for(int i=0; i<3; i++) m[i]/=count;
02876
02877 index=0;
02878 if (dm) {
02879 for(int j=0; j<ny; j++){
02880 for(int i=0; i<nx; i++){
02881 int ij=j*nx+i;
02882 if(dm[ij]) {
02883
02884 gsl_matrix_set(A,index,0,i-m[0]);
02885 gsl_matrix_set(A,index,1,j-m[1]);
02886 gsl_matrix_set(A,index,2,d[ij]-m[2]);
02887 index++;
02888 }
02889 }
02890 }
02891 mask->update();
02892 }
02893 else {
02894 for(int j=0; j<ny; j++){
02895 for(int i=0; i<nx; i++){
02896 int ij=j*nx+i;
02897
02898 gsl_matrix_set(A,index,0,i-m[0]);
02899 gsl_matrix_set(A,index,1,j-m[1]);
02900 gsl_matrix_set(A,index,2,d[ij]-m[2]);
02901 index++;
02902 }
02903 }
02904 }
02905
02906
02907 gsl_linalg_SV_decomp_jacobi(A, V, S);
02908
02909 double n[3];
02910 for(int i=0; i<3; i++) n[i] = gsl_matrix_get(V, i, 2);
02911
02912 #ifdef DEBUG
02913 printf("S=%g,%g,%g\n",gsl_vector_get(S,0), gsl_vector_get(S,1), gsl_vector_get(S,2));
02914 printf("V[0,:]=%g,%g,%g\n",gsl_matrix_get(V,0,0), gsl_matrix_get(V,0,1),gsl_matrix_get(V,0,2));
02915 printf("V[1,:]=%g,%g,%g\n",gsl_matrix_get(V,1,0), gsl_matrix_get(V,1,1),gsl_matrix_get(V,1,2));
02916 printf("V[2,:]=%g,%g,%g\n",gsl_matrix_get(V,2,0), gsl_matrix_get(V,2,1),gsl_matrix_get(V,2,2));
02917 printf("Fitted plane: p0=%g,%g,%g\tn=%g,%g,%g\n",m[0],m[1],m[2],n[0],n[1],n[2]);
02918 #endif
02919
02920 int changeZero = 0;
02921 if (params.has_key("changeZero")) changeZero = params["changeZero"];
02922 if (changeZero) {
02923 for(int j=0; j<nx; j++){
02924 for(int i=0; i<ny; i++){
02925 int ij = j*nx+i;
02926 d[ij]-=static_cast<float>(-((i-m[0])*n[0]+(j-m[1])*n[1])/n[2]+m[2]);
02927 }
02928 }
02929 }
02930 else {
02931 for(int j=0; j<nx; j++){
02932 for(int i=0; i<ny; i++){
02933 int ij = j*nx+i;
02934 if(d[ij]) d[ij]-=static_cast<float>(-((i-m[0])*n[0]+(j-m[1])*n[1])/n[2]+m[2]);
02935 }
02936 }
02937 }
02938 image->update();
02939
02940 vector< float > planeParam;
02941 planeParam.resize(6);
02942 for(int i=0; i<3; i++) planeParam[i] = static_cast<float>(n[i]);
02943 for(int i=0; i<3; i++) planeParam[i+3] = static_cast<float>(m[i]);
02944 params["planeParam"]=EMObject(planeParam);
02945 }
02946
02947 void VerticalStripeProcessor::process_inplace(EMData * image)
02948 {
02949 if (!image) {
02950 LOGWARN("NULL Image");
02951 return;
02952 }
02953
02954 int nx = image->get_xsize();
02955 int ny = image->get_ysize();
02956 int nz = image->get_zsize();
02957
02958 float *data = image->get_data();
02959 float sigma = image->get_attr("sigma");
02960
02961 for (int k = 0; k < nz; k++) {
02962 for (int i = 0; i < nx; i++) {
02963 double sum = 0;
02964 for (int j = ny / 4; j < 3 * ny / 4; j++) {
02965 sum += data[i + j * nx];
02966 }
02967
02968 float mean = (float)sum / (ny / 2);
02969 for (int j = 0; j < ny; j++) {
02970 data[i + j * nx] = (data[i + j * nx] - mean) / sigma;
02971 }
02972 }
02973 }
02974
02975 image->update();
02976 }
02977
02978 void RealToFFTProcessor::process_inplace(EMData *image)
02979 {
02980 if (!image) {
02981 LOGWARN("NULL Image");
02982 return;
02983 }
02984
02985
02986 if(image->is_complex()) {
02987 LOGERR("%s Processor only operates on real images", get_name().c_str());
02988 throw ImageFormatException("apply to real image only");
02989 }
02990
02991
02992 int nz = image->get_zsize();
02993 if (nz > 1) {
02994 LOGERR("%s Processor doesn't support 3D models", get_name().c_str());
02995 throw ImageDimensionException("3D model not supported");
02996 }
02997
02998 EMData *ff=image->do_fft();
02999 ff->ri2ap();
03000
03001 int nx=image->get_xsize();
03002 int ny=image->get_ysize();
03003
03004 int x,y;
03005 float norm=static_cast<float>(nx*ny);
03006
03007 for (y=0; y<ny; y++) image->set_value_at(0,y,0);
03008
03009 for (x=1; x<nx/2; x++) {
03010 for (y=0; y<ny; y++) {
03011 int y2;
03012 if (y<ny/2) y2=y+ny/2;
03013 else if (y==ny/2) y2=ny;
03014 else y2=y-ny/2;
03015 image->set_value_at(x,y,ff->get_value_at(nx-x*2,ny-y2)/norm);
03016 }
03017 }
03018
03019 for (x=nx/2; x<nx; x++) {
03020 for (y=0; y<ny; y++) {
03021 int y2;
03022 if (y<ny/2) y2=y+ny/2;
03023 else y2=y-ny/2;
03024 image->set_value_at(x,y,ff->get_value_at(x*2-nx,y2)/norm);
03025 }
03026 }
03027
03028 image->update();
03029 if( ff )
03030 {
03031 delete ff;
03032 ff = 0;
03033 }
03034 }
03035
03036 void SigmaZeroEdgeProcessor::process_inplace(EMData * image)
03037 {
03038 if (!image) {
03039 LOGWARN("NULL Image");
03040 return;
03041 }
03042
03043 if (image->get_zsize() > 1) {
03044 LOGERR("%s Processor doesn't support 3D model", get_name().c_str());
03045 throw ImageDimensionException("3D model not supported");
03046 }
03047 float *d = image->get_data();
03048 int i = 0;
03049 int j = 0;
03050
03051 int nx = image->get_xsize();
03052 int ny = image->get_ysize();
03053
03054 for (j = 0; j < ny; j++) {
03055 for (i = 0; i < nx - 1; i++) {
03056 if (d[i + j * nx] != 0) {
03057 break;
03058 }
03059 }
03060
03061 float v = d[i + j * nx];
03062 while (i >= 0) {
03063 d[i + j * nx] = v;
03064 i--;
03065 }
03066
03067 for (i = nx - 1; i > 0; i--) {
03068 if (d[i + j * nx] != 0)
03069 break;
03070 }
03071 v = d[i + j * nx];
03072 while (i < nx) {
03073 d[i + j * nx] = v;
03074 i++;
03075 }
03076 }
03077
03078 for (i = 0; i < nx; i++) {
03079 for (j = 0; j < ny; j++) {
03080 if (d[i + j * nx] != 0)
03081 break;
03082 }
03083
03084 float v = d[i + j * nx];
03085 while (j >= 0) {
03086 d[i + j * nx] = v;
03087 j--;
03088 }
03089
03090 for (j = ny - 1; j > 0; j--) {
03091 if (d[i + j * nx] != 0)
03092 break;
03093 }
03094 v = d[i + j * nx];
03095 while (j < ny) {
03096 d[i + j * nx] = v;
03097 j++;
03098 }
03099 }
03100
03101
03102 image->update();
03103 }
03104
03105
03106
03107 void BeamstopProcessor::process_inplace(EMData * image)
03108 {
03109 if (!image) {
03110 LOGWARN("NULL Image");
03111 return;
03112 }
03113 if (image->get_zsize() > 1) {
03114 LOGERR("BeamstopProcessor doesn't support 3D model");
03115 throw ImageDimensionException("3D model not supported");
03116 }
03117
03118 float value1 = params["value1"];
03119 float value2 = params["value2"];
03120 float value3 = params["value3"];
03121
03122 float thr = fabs(value1);
03123 float *data = image->get_data();
03124 int cenx = (int) value2;
03125 int ceny = (int) value3;
03126
03127 int nx = image->get_xsize();
03128 int ny = image->get_ysize();
03129
03130 if (cenx <= 0) {
03131 cenx = nx / 2;
03132 }
03133
03134 if (ceny <= 0) {
03135 ceny = ny / 2;
03136 }
03137
03138 int mxr = (int) floor(sqrt(2.0f) * nx / 2);
03139
03140 float *mean_values = new float[mxr];
03141 float *sigma_values = new float[mxr];
03142 double sum = 0;
03143 int count = 0;
03144 double square_sum = 0;
03145
03146 for (int i = 0; i < mxr; i++) {
03147 sum = 0;
03148 count = 0;
03149 square_sum = 0;
03150 int nitems = 6 * i + 2;
03151
03152 for (int j = 0; j < nitems; j++) {
03153 float ang = j * 2 * M_PI / nitems;
03154 int x0 = (int) floor(cos(ang) * i + cenx);
03155 int y0 = (int) floor(sin(ang) * i + ceny);
03156
03157 if (x0 < 0 || y0 < 0 || x0 >= nx || y0 >= ny) {
03158 continue;
03159 }
03160
03161 float f = data[x0 + y0 * nx];
03162 sum += f;
03163 square_sum += f * f;
03164 count++;
03165 }
03166
03167 mean_values[i] = (float)sum / count;
03168 sigma_values[i] = (float) sqrt(square_sum / count - mean_values[i] * mean_values[i]);
03169 }
03170
03171
03172 for (int k = 0; k < 5; k++) {
03173 for (int i = 0; i < mxr; i++) {
03174 sum = 0;
03175 count = 0;
03176 square_sum = 0;
03177 int nitems = 6 * i + 2;
03178 double thr1 = mean_values[i] - sigma_values[i] * thr;
03179 double thr2 = mean_values[i] + sigma_values[i];
03180
03181 for (int j = 0; j < nitems; j++) {
03182 float ang = j * 2 * M_PI / nitems;
03183 int x0 = (int) floor(cos(ang) * i + cenx);
03184 int y0 = (int) floor(sin(ang) * i + ceny);
03185
03186 if (x0 < 0 || y0 < 0 || x0 >= nx || y0 >= ny ||
03187 data[x0 + y0 * nx] < thr1 || data[x0 + y0 * nx] > thr2) {
03188 continue;
03189 }
03190
03191 sum += data[x0 + y0 * nx];
03192 square_sum += data[x0 + y0 * nx] * data[x0 + y0 * nx];
03193 count++;
03194 }
03195
03196 mean_values[i] = (float) sum / count;
03197 sigma_values[i] = (float) sqrt(square_sum / count - mean_values[i] * mean_values[i]);
03198 }
03199 }
03200
03201 for (int i = 0; i < nx; i++) {
03202 for (int j = 0; j < ny; j++) {
03203
03204 #ifdef _WIN32
03205 int r = Util::round(_hypot((float) i - cenx, (float) j - ceny));
03206 #else
03207 int r = Util::round(hypot((float) i - cenx, (float) j - ceny));
03208 #endif //_WIN32
03209
03210 if (value1 < 0) {
03211 if (data[i + j * nx] < (mean_values[r] - sigma_values[r] * thr)) {
03212 data[i + j * nx] = 0;
03213 }
03214 else {
03215 data[i + j * nx] -= mean_values[r];
03216 }
03217 continue;
03218 }
03219 if (data[i + j * nx] > (mean_values[r] - sigma_values[r] * thr)) {
03220 continue;
03221 }
03222 data[i + j * nx] = mean_values[r];
03223 }
03224 }
03225
03226 if( mean_values )
03227 {
03228 delete[]mean_values;
03229 mean_values = 0;
03230 }
03231
03232 if( sigma_values )
03233 {
03234 delete[]sigma_values;
03235 sigma_values = 0;
03236 }
03237
03238 image->update();
03239 }
03240
03241
03242
03243 void MeanZeroEdgeProcessor::process_inplace(EMData * image)
03244 {
03245 if (!image) {
03246 LOGWARN("NULL Image");
03247 return;
03248 }
03249 if (image->get_zsize() > 1) {
03250 LOGERR("MeanZeroEdgeProcessor doesn't support 3D model");
03251 throw ImageDimensionException("3D model not supported");
03252 }
03253
03254 int nx = image->get_xsize();
03255 int ny = image->get_ysize();
03256 Dict dict = image->get_attr_dict();
03257 float mean_nonzero = dict.get("mean_nonzero");
03258
03259 float *d = image->get_data();
03260 int i = 0;
03261 int j = 0;
03262
03263 for (j = 0; j < ny; j++) {
03264 for (i = 0; i < nx - 1; i++) {
03265 if (d[i + j * nx] != 0) {
03266 break;
03267 }
03268 }
03269
03270 if (i == nx - 1) {
03271 i = -1;
03272 }
03273
03274 float v = d[i + j * nx] - mean_nonzero;
03275
03276 while (i >= 0) {
03277 v *= 0.9f;
03278 d[i + j * nx] = v + mean_nonzero;
03279 i--;
03280 }
03281
03282
03283 for (i = nx - 1; i > 0; i--) {
03284 if (d[i + j * nx] != 0) {
03285 break;
03286 }
03287 }
03288
03289 if (i == 0) {
03290 i = nx;
03291 }
03292
03293 v = d[i + j * nx] - mean_nonzero;
03294
03295 while (i < nx) {
03296 v *= .9f;
03297 d[i + j * nx] = v + mean_nonzero;
03298 i++;
03299 }
03300 }
03301
03302
03303 for (i = 0; i < nx; i++) {
03304 for (j = 0; j < ny; j++) {
03305 if (d[i + j * nx] != 0)
03306 break;
03307 }
03308
03309 float v = d[i + j * nx] - mean_nonzero;
03310
03311 while (j >= 0) {
03312 v *= .9f;
03313 d[i + j * nx] = v + mean_nonzero;
03314 j--;
03315 }
03316
03317 for (j = ny - 1; j > 0; j--) {
03318 if (d[i + j * nx] != 0)
03319 break;
03320 }
03321
03322 v = d[i + j * nx] - mean_nonzero;
03323
03324 while (j < ny) {
03325 v *= .9f;
03326 d[i + j * nx] = v + mean_nonzero;
03327 j++;
03328 }
03329 }
03330
03331 image->update();
03332 }
03333
03334
03335
03336 void AverageXProcessor::process_inplace(EMData * image)
03337 {
03338 if (!image) {
03339 LOGWARN("NULL Image");
03340 return;
03341 }
03342
03343 float *data = image->get_data();
03344 int nx = image->get_xsize();
03345 int ny = image->get_ysize();
03346 int nz = image->get_zsize();
03347 size_t nxy = (size_t)nx * ny;
03348
03349 size_t idx;
03350 for (int z = 0; z < nz; z++) {
03351 for (int x = 0; x < nx; x++) {
03352 double sum = 0;
03353 for (int y = 0; y < ny; y++) {
03354 idx = x + y * nx + z * nxy;
03355 sum += data[idx];
03356 }
03357 float mean = (float) sum / ny;
03358
03359 for (int y = 0; y < ny; y++) {
03360 idx = x + y * nx + z * nxy;
03361 data[idx] = mean;
03362 }
03363 }
03364 }
03365
03366 image->update();
03367 }
03368
03369 void DecayEdgeProcessor::process_inplace(EMData * image)
03370 {
03371 if (!image) {
03372 LOGWARN("NULL Image");
03373 return;
03374 }
03375
03376 if (image->get_zsize() > 1) throw ImageDimensionException("3D model not supported");
03377
03378 int nx = image->get_xsize();
03379 int ny = image->get_ysize();
03380
03381 float *d = image->get_data();
03382 int width = params["width"];
03383
03384 for (int i=0; i<width; i++) {
03385 float frac=i/(float)width;
03386 for (int j=0; j<nx; j++) {
03387 d[j+i*nx]*=frac;
03388 d[nx*ny-j-i*nx-1]*=frac;
03389 }
03390 for (int j=0; j<ny; j++) {
03391 d[j*nx+i]*=frac;
03392 d[nx*ny-j*nx-i-1]*=frac;
03393 }
03394 }
03395
03396 image->update();
03397 }
03398
03399 void ZeroEdgeRowProcessor::process_inplace(EMData * image)
03400 {
03401 if (!image) {
03402 LOGWARN("NULL Image");
03403 return;
03404 }
03405
03406 if (image->get_zsize() > 1) {
03407 LOGERR("ZeroEdgeRowProcessor is not supported in 3D models");
03408 throw ImageDimensionException("3D model not supported");
03409 }
03410
03411 int nx = image->get_xsize();
03412 int ny = image->get_ysize();
03413
03414 float *d = image->get_data();
03415 int top_nrows = params["y0"];
03416 int bottom_nrows = params["y1"];
03417
03418 int left_ncols = params["x0"];
03419 int right_ncols = params["x1"];
03420
03421 size_t row_size = nx * sizeof(float);
03422
03423 memset(d, 0, top_nrows * row_size);
03424 memset(d + (ny - bottom_nrows) * nx, 0, bottom_nrows * row_size);
03425
03426 for (int i = top_nrows; i < ny - bottom_nrows; i++) {
03427 memset(d + i * nx, 0, left_ncols * sizeof(float));
03428 memset(d + i * nx + nx - right_ncols, 0, right_ncols * sizeof(float));
03429 }
03430 image->update();
03431 }
03432
03433 void ZeroEdgePlaneProcessor::process_inplace(EMData * image)
03434 {
03435 if (!image) {
03436 LOGWARN("NULL Image");
03437 return;
03438 }
03439
03440 if (image->get_zsize() <= 1) {
03441 LOGERR("ZeroEdgePlaneProcessor only support 3D models");
03442 throw ImageDimensionException("3D model only");
03443 }
03444
03445 int nx = image->get_xsize();
03446 int ny = image->get_ysize();
03447 int nz = image->get_zsize();
03448
03449 float *d = image->get_data();
03450
03451 int x0=params["x0"];
03452 int x1=params["x1"];
03453 int y0=params["y0"];
03454 int y1=params["y1"];
03455 int z0=params["z0"];
03456 int z1=params["z1"];
03457
03458 size_t row_size = nx * sizeof(float);
03459 size_t nxy = nx * ny;
03460 size_t sec_size = nxy * sizeof(float);
03461 size_t y0row = y0 * row_size;
03462 size_t y1row = y1 * row_size;
03463 int max_y = ny-y1;
03464 size_t x0size = x0*sizeof(float);
03465 size_t x1size = x1*sizeof(float);
03466
03467 memset(d,0,z0*sec_size);
03468 memset(d+(nxy*(nz-z1)),0,sec_size*z1);
03469
03470 for (int z=z0; z<nz-z1; z++) {
03471 memset(d+z*nxy,0,y0row);
03472 memset(d+z*nxy+(ny-y1)*nx,0,y1row);
03473
03474 int znxy = z * nxy;
03475 int znxy2 = znxy + nx - x1;
03476
03477 for (int y=y0; y<max_y; y++) {
03478 memset(d+znxy+y*nx,0,x0size);
03479 memset(d+znxy2+y*nx,0,x1size);
03480 }
03481 }
03482
03483 image->update();
03484 }
03485
03486
03487 float NormalizeProcessor::calc_sigma(EMData * image) const
03488 {
03489 return image->get_attr("sigma");
03490 }
03491
03492 void NormalizeProcessor::process_inplace(EMData * image)
03493 {
03494 if (!image) {
03495 LOGWARN("cannot do normalization on NULL image");
03496 return;
03497 }
03498
03499 if (image->is_complex()) {
03500 LOGWARN("cannot do normalization on complex image");
03501 return;
03502 }
03503
03504 float sigma = calc_sigma(image);
03505 if (sigma == 0 || !Util::goodf(&sigma)) {
03506 LOGWARN("cannot do normalization on image with sigma = 0");
03507 return;
03508 }
03509
03510 float mean = calc_mean(image);
03511
03512 size_t size = (size_t)image->get_xsize() * (size_t)image->get_ysize() *
03513 (size_t)image->get_zsize();
03514 float *data = image->get_data();
03515
03516 for (size_t i = 0; i < size; i++) {
03517 data[i] = (data[i] - mean) / sigma;
03518 }
03519
03520 image->update();
03521 }
03522
03523 float NormalizeUnitProcessor::calc_sigma(EMData * image) const
03524 {
03525 if (!image) {
03526 LOGWARN("NULL Image");
03527 return 0;
03528 }
03529 float ret=sqrt((float)image->get_attr("square_sum"));
03530 return ret==0.0f?1.0f:ret;
03531 }
03532
03533 float NormalizeUnitSumProcessor::calc_sigma(EMData * image) const
03534 {
03535 if (!image) {
03536 LOGWARN("NULL Image");
03537 return 0;
03538 }
03539 float ret=(float)image->get_attr("mean")*image->get_xsize()*image->get_ysize()*image->get_zsize();
03540 return ret==0.0f?1.0f:ret;
03541 }
03542
03543 float NormalizeMaskProcessor::calc_sigma(EMData * image) const
03544 {
03545 if (!image) {
03546 LOGWARN("NULL Image");
03547 return 0;
03548 }
03549 EMData *mask = params["mask"];
03550 int no_sigma = params["no_sigma"];
03551
03552 if(no_sigma == 0) {
03553 return 1;
03554 }
03555 else {
03556 if (!EMUtil::is_same_size(mask, image)) {
03557 LOGERR("normalize.maskProcessor: mask and image must be the same size");
03558 throw ImageDimensionException("mask and image must be the same size");
03559 }
03560
03561 float *data = image->get_data();
03562 float *mask_data = mask->get_data();
03563 size_t size = image->get_xsize() * image->get_ysize() * image->get_zsize();
03564 double sum = 0;
03565 double sq2 = 0;
03566 size_t n_norm = 0;
03567
03568 for (size_t i = 0; i < size; i++) {
03569 if (mask_data[i] > 0.5f) {
03570 sum += data[i];
03571 sq2 += data[i]*double (data[i]);
03572 n_norm++;
03573 }
03574 }
03575 return sqrt(static_cast<float>((sq2 - sum * sum /n_norm)/(n_norm -1))) ;
03576 }
03577 }
03578
03579 float NormalizeMaskProcessor::calc_mean(EMData * image) const
03580 {
03581 if (!image) {
03582 LOGWARN("NULL Image");
03583 return 0;
03584 }
03585 EMData *mask = params["mask"];
03586
03587 if (!EMUtil::is_same_size(mask, image)) {
03588 LOGERR("normalize.maskProcessor: mask and image must be the same size");
03589 throw ImageDimensionException("mask and image must be the same size");
03590 }
03591
03592 float *data = image->get_data();
03593 float *mask_data = mask->get_data();
03594 size_t size = image->get_xsize() * image->get_ysize() * image->get_zsize();
03595 double sum = 0;
03596 size_t n_norm = 0;
03597
03598 for (size_t i = 0; i < size; i++) {
03599 if (mask_data[i] > 0.5f) {
03600 sum += data[i];
03601 n_norm++;
03602 }
03603 }
03604
03605 float mean = 0;
03606 if (n_norm == 0) {
03607 mean = image->get_edge_mean();
03608 }
03609 else {
03610 mean = (float) sum / n_norm;
03611 }
03612
03613 return mean;
03614 }
03615
03616 void NormalizeRampNormVar::process_inplace(EMData * image)
03617 {
03618 if (!image) {
03619 LOGWARN("cannot do normalization on NULL image");
03620 return;
03621 }
03622
03623 if (image->is_complex()) {
03624 LOGWARN("cannot do normalization on complex image");
03625 return;
03626 }
03627
03628 image->process_inplace( "filter.ramp" );
03629 int nx = image->get_xsize();
03630 EMData mask(nx,nx);
03631 mask.process_inplace("testimage.circlesphere", Dict("radius",nx/2-2,"fill",1));
03632
03633 vector<float> rstls = Util::infomask( image, &mask, false);
03634 image->add((float)-rstls[0]);
03635 image->mult((float)1.0/rstls[1]);
03636 image->update();
03637 }
03638
03639 void NormalizeByMassProcessor::process_inplace(EMData * image)
03640 {
03641 float mass = params.set_default("mass",-1.0f);
03642
03643 if (mass <= 0) throw InvalidParameterException("You must specify a positive non zero mass");
03644
03645 float thr = params.set_default("thr",(float)image->get_attr("mean")+(float)image->get_attr("sigma"));
03646
03647 float apix = params.set_default("apix",-1.123456789f);
03648 if (apix == -1.123456789 ) {
03649 if (image->has_attr("apix_x")) {
03650 apix = image->get_attr("apix_x");
03651 }
03652 }
03653
03654 if (apix <= 0) throw InvalidParameterException("You must specify a positive non zero apix");
03655
03656 float step = ((float)image->get_attr("sigma"))/2.0f;
03657
03658 int count=0;
03659 size_t n = image->get_size();
03660 float* d = image->get_data();
03661
03662 for (size_t i=0; i<n; ++i) {
03663 if (d[i]>=thr) ++count;
03664 }
03665
03666 float max = image->get_attr("maximum");
03667 float min = image->get_attr("minimum");
03668 for (int j=0; j<4; j++) {
03669 while (thr<max && count*apix*apix*apix*.81/1000.0>mass) {
03670 thr+=step;
03671 count=0;
03672 for (size_t i=0; i<n; ++i) {
03673 if (d[i]>=thr) ++count;
03674 }
03675 }
03676
03677 step/=4.0;
03678
03679 while (thr>min && count*apix*apix*apix*.81/1000.0<mass) {
03680 thr-=step;
03681 count=0;
03682 for (size_t i=0; i<n; ++i) {
03683 if (d[i]>=thr) ++count;
03684 }
03685 }
03686
03687 step/=4.0;
03688 }
03689
03690 image->mult((float)1.0/thr);
03691 image->update();
03692 }
03693
03694 float NormalizeEdgeMeanProcessor::calc_mean(EMData * image) const
03695 {
03696 if (!image) {
03697 LOGWARN("NULL Image");
03698 return 0;
03699 }
03700 return image->get_edge_mean();
03701 }
03702
03703 float NormalizeCircleMeanProcessor::calc_mean(EMData * image) const
03704 {
03705 if (!image) {
03706 LOGWARN("NULL Image");
03707 return 0;
03708 }
03709 return image->get_circle_mean();
03710 }
03711
03712
03713 float NormalizeMaxMinProcessor::calc_sigma(EMData * image) const
03714 {
03715 if (!image) {
03716 LOGWARN("NULL Image");
03717 return 0;
03718 }
03719 float maxval = image->get_attr("maximum");
03720 float minval = image->get_attr("minimum");
03721 return (maxval + minval) / 2;
03722 }
03723
03724 float NormalizeMaxMinProcessor::calc_mean(EMData * image) const
03725 {
03726 if (!image) {
03727 LOGWARN("NULL Image");
03728 return 0;
03729 }
03730 float maxval = image->get_attr("maximum");
03731 float minval = image->get_attr("minimum");
03732 return (maxval - minval) / 2;
03733 }
03734
03735 float NormalizeLREdgeMeanProcessor::calc_mean(EMData * image) const
03736 {
03737 if (!image) {
03738 LOGWARN("NULL Image");
03739 return 0;
03740 }
03741 double sum = 0;
03742 int nx = image->get_xsize();
03743 int ny = image->get_ysize();
03744 int nz = image->get_zsize();
03745 float *d = image->get_data();
03746 int nyz = ny * nz;
03747
03748 for (int i = 0; i < nyz; i++) {
03749 size_t l = i * nx;
03750 size_t r = l + nx - 2;
03751 sum += d[l] + d[l + 1] + d[r] + d[r + 1];
03752 }
03753 float mean = (float) sum / (4 * nyz);
03754 return mean;
03755 }
03756
03757 void NormalizeRowProcessor::process_inplace(EMData * image)
03758 {
03759 if (!image) {
03760 LOGWARN("NULL Image");
03761 return;
03762 }
03763
03764 if (image->get_zsize() > 1) {
03765 LOGERR("row normalize only works for 2D image");
03766 return;
03767 }
03768
03769 float *rdata = image->get_data();
03770 int nx = image->get_xsize();
03771 int ny = image->get_ysize();
03772
03773 for (int y = 0; y < ny; y++) {
03774 double row_sum = 0;
03775 for (int x = 0; x < nx; x++) {
03776 row_sum += rdata[x + y * nx];
03777 }
03778
03779 double row_mean = row_sum / nx;
03780 if (row_mean <= 0) {
03781 row_mean = 1;
03782 }
03783
03784 for (int x = 0; x < nx; x++) {
03785 rdata[x + y * nx] /= (float)row_mean;
03786 }
03787 }
03788
03789 image->update();
03790 }
03791
03792 float NormalizeStdProcessor::calc_mean(EMData * image) const
03793 {
03794 if (!image) {
03795 LOGWARN("NULL Image");
03796 return 0;
03797 }
03798 return image->get_attr("mean");
03799 }
03800
03801
03802
03803 void NormalizeToLeastSquareProcessor::process_inplace(EMData * image)
03804 {
03805 if (!image) {
03806 LOGWARN("NULL Image");
03807 return;
03808 }
03809
03810 EMData *to = params["to"];
03811
03812 bool ignore_zero = params.set_default("ignore_zero",true);
03813
03814 float low_threshold = FLT_MIN;
03815 string low_thr_name = "low_threshold";
03816 if (params.has_key(low_thr_name)) {
03817 low_threshold = params[low_thr_name];
03818 }
03819
03820 float high_threshold = FLT_MAX;
03821 string high_thr_name = "high_threshold";
03822 if (params.has_key(high_thr_name)) {
03823 high_threshold = params[high_thr_name];
03824 }
03825
03826 float *rawp = image->get_data();
03827 float *refp = to->get_data();
03828
03829 int nx = image->get_xsize();
03830 int ny = image->get_ysize();
03831 int nz = image->get_zsize();
03832 size_t size = nx * ny * nz;
03833
03834 float sum_x = 0;
03835 float sum_y = 0;
03836 int count = 0;
03837
03838 float sum_x_mean = 0;
03839 float sum_tt = 0;
03840 float b = 0;
03841
03842
03843 if (ignore_zero) {
03844 for (size_t i = 0; i < size; i++) {
03845 if (refp[i] >= low_threshold && refp[i] <= high_threshold && refp[i] != 0.0 && rawp[i] != 0.0) {
03846 count++;
03847 sum_x += refp[i];
03848 sum_y += rawp[i];
03849 }
03850 }
03851
03852 sum_x_mean = sum_x / count;
03853 sum_tt = 0;
03854 b = 0;
03855
03856 float t;
03857 for (size_t i = 0; i < size; i++) {
03858 if (refp[i] >= low_threshold && refp[i] <= high_threshold && refp[i] != 0.0 && rawp[i] != 0.0) {
03859 t = refp[i] - sum_x_mean;
03860 sum_tt += t * t;
03861 b += t * rawp[i];
03862 }
03863 }
03864 }
03865 else {
03866 for (size_t i = 0; i < size; i++) {
03867 if (refp[i] >= low_threshold && refp[i] <= high_threshold) {
03868 count++;
03869 sum_x += refp[i];
03870 sum_y += rawp[i];
03871 }
03872 }
03873
03874 sum_x_mean = sum_x / count;
03875 sum_tt = 0;
03876 b = 0;
03877
03878 float t;
03879 for (size_t i = 0; i < size; i++) {
03880 if (refp[i] >= low_threshold && refp[i] <= high_threshold) {
03881 t = refp[i] - sum_x_mean;
03882 sum_tt += t * t;
03883 b += t * rawp[i];
03884 }
03885 }
03886 }
03887
03888 b /= sum_tt;
03889
03890 float a = (sum_y - sum_x * b) / count;
03891 float scale = 1 / b;
03892 float shift = -a / b;
03893
03894 for (size_t i = 0; i < size; i++) {
03895 rawp[i] = (rawp[i] - a) / b;
03896 }
03897
03898 image->update();
03899
03900 params["scale"] = scale;
03901 params["shift"] = shift;
03902
03903 image->set_attr("norm_mult",scale);
03904 image->set_attr("norm_add",shift);
03905
03906 }
03907
03908
03909 void BinarizeFourierProcessor::process_inplace(EMData* image) {
03910 ENTERFUNC;
03911 if (!image->is_complex()) throw ImageFormatException("Fourier binary thresholding processor only works for complex images");
03912
03913 float threshold = params.set_default("value",-1.0f);
03914 if (threshold < 0) throw InvalidParameterException("For fourier amplitude-based thresholding, the threshold must be greater than or equal to 0.");
03915
03916 image->ri2ap();
03917
03918 #ifdef EMAN2_USING_CUDA
03919 if (image->gpu_operation_preferred()) {
03920 EMDataForCuda tmp = image->get_data_struct_for_cuda();
03921 binarize_fourier_amp_processor(&tmp,threshold);
03922 image->set_ri(true);
03923 image->gpu_update();
03924 EXITFUNC;
03925 return;
03926 }
03927 #endif
03928
03929 float* d = image->get_data();
03930 for( size_t i = 0; i < image->get_size()/2; ++i, d+=2) {
03931 float v = *d;
03932 if ( v >= threshold ) {
03933 *d = 1;
03934 *(d+1) = 0;
03935 } else {
03936 *d = 0;
03937 *(d+1) = 0;
03938 }
03939 }
03940
03941
03942 image->set_ri(true);
03943 image->update();
03944 EXITFUNC;
03945 }
03946
03947
03948 void BilateralProcessor::process_inplace(EMData * image)
03949 {
03950 if (!image) {
03951 LOGWARN("NULL Image");
03952 return;
03953 }
03954
03955 float distance_sigma = params["distance_sigma"];
03956 float value_sigma = params["value_sigma"];
03957 int max_iter = params["niter"];
03958 int half_width = params["half_width"];
03959
03960 if (half_width < distance_sigma) {
03961 LOGWARN("localwidth(=%d) should be larger than distance_sigma=(%f)\n",
03962 half_width, distance_sigma);
03963 }
03964
03965 distance_sigma *= distance_sigma;
03966
03967 float image_sigma = image->get_attr("sigma");
03968 if (image_sigma > value_sigma) {
03969 LOGWARN("image sigma(=%f) should be smaller than value_sigma=(%f)\n",
03970 image_sigma, value_sigma);
03971 }
03972 value_sigma *= value_sigma;
03973
03974 int nx = image->get_xsize();
03975 int ny = image->get_ysize();
03976 int nz = image->get_zsize();
03977
03978 if(nz==1) {
03979 int width=nx, height=ny;
03980
03981 int i,j,m,n;
03982
03983 float tempfloat1,tempfloat2,tempfloat3;
03984 int index1,index2,index;
03985 int Iter;
03986 int tempint1,tempint3;
03987
03988 tempint1=width;
03989 tempint3=width+2*half_width;
03990
03991 float* mask=(float*)calloc((2*half_width+1)*(2*half_width+1),sizeof(float));
03992 float* OrgImg=(float*)calloc((2*half_width+width)*(2*half_width+height),sizeof(float));
03993 float* NewImg=image->get_data();
03994
03995 for(m=-(half_width);m<=half_width;m++)
03996 for(n=-(half_width);n<=half_width;n++) {
03997 index=(m+half_width)*(2*half_width+1)+(n+half_width);
03998 mask[index]=exp((float)(-(m*m+n*n)/distance_sigma/2.0));
03999 }
04000
04001
04002
04003 Iter=0;
04004 while(Iter<max_iter) {
04005 for(i=0;i<height;i++)
04006 for(j=0;j<width;j++) {
04007 index1=(i+half_width)*tempint3+(j+half_width);
04008 index2=i*tempint1+j;
04009 OrgImg[index1]=NewImg[index2];
04010 }
04011
04012
04013 for(i=0;i<height;i++){
04014 for(j=0;j<half_width;j++) OrgImg[(i+half_width)*tempint3+(j)]=OrgImg[(i+half_width)*tempint3+(2*half_width-j)];
04015 for(j=0;j<half_width;j++) OrgImg[(i+half_width)*tempint3+(j+width+half_width)]=OrgImg[(i+half_width)*tempint3+(width+half_width-j-2)];
04016 }
04017 for(i=0;i<half_width;i++){
04018 for(j=0;j<(width+2*half_width);j++) OrgImg[i*tempint3+j]=OrgImg[(2*half_width-i)*tempint3+j];
04019 for(j=0;j<(width+2*half_width);j++) OrgImg[(i+height+half_width)*tempint3+j]=OrgImg[(height+half_width-2-i)*tempint3+j];
04020 }
04021
04022
04023
04024
04025 for(i=0;i<height;i++){
04026
04027 for(j=0;j<width;j++){
04028 tempfloat1=0.0; tempfloat2=0.0;
04029 for(m=-(half_width);m<=half_width;m++)
04030 for(n=-(half_width);n<=half_width;n++){
04031 index =(m+half_width)*(2*half_width+1)+(n+half_width);
04032 index1=(i+half_width)*tempint3+(j+half_width);
04033 index2=(i+half_width+m)*tempint3+(j+half_width+n);
04034 tempfloat3=(OrgImg[index1]-OrgImg[index2])*(OrgImg[index1]-OrgImg[index2]);
04035
04036 tempfloat3=mask[index]*(1.0f/(1+tempfloat3/value_sigma));
04037
04038 tempfloat1+=tempfloat3;
04039
04040 tempfloat2+=tempfloat3*OrgImg[(i+half_width+m)*tempint3+(j+half_width+n)];
04041 }
04042 NewImg[i*width+j]=tempfloat2/tempfloat1;
04043 }
04044 }
04045 Iter++;
04046 }
04047
04048
04049
04050 free(mask);
04051 free(OrgImg);
04052
04053
04054 }
04055 else {
04056 int width = nx;
04057 int height = ny;
04058 int slicenum = nz;
04059
04060 int slice_size = width * height;
04061 int new_width = width + 2 * half_width;
04062 int new_slice_size = (width + 2 * half_width) * (height + 2 * half_width);
04063
04064 int width1 = 2 * half_width + 1;
04065 int mask_size = width1 * width1;
04066 int old_img_size = (2 * half_width + width) * (2 * half_width + height);
04067
04068 int zstart = -half_width;
04069 int zend = -half_width;
04070 int is_3d = 0;
04071 if (nz > 1) {
04072 mask_size *= width1;
04073 old_img_size *= (2 * half_width + slicenum);
04074 zend = half_width;
04075 is_3d = 1;
04076 }
04077
04078 float *mask = (float *) calloc(mask_size, sizeof(float));
04079 float *old_img = (float *) calloc(old_img_size, sizeof(float));
04080
04081 float *new_img = image->get_data();
04082
04083 for (int p = zstart; p <= zend; p++) {
04084 int cur_p = (p + half_width) * (2 * half_width + 1) * (2 * half_width + 1);
04085
04086 for (int m = -half_width; m <= half_width; m++) {
04087 int cur_m = (m + half_width) * (2 * half_width + 1) + half_width;
04088
04089 for (int n = -half_width; n <= half_width; n++) {
04090 int l = cur_p + cur_m + n;
04091 mask[l] = exp((float) (-(m * m + n * n + p * p * is_3d) / distance_sigma / 2.0f));
04092 }
04093 }
04094 }
04095
04096 int iter = 0;
04097 while (iter < max_iter) {
04098 for (int k = 0; k < slicenum; k++) {
04099 int cur_k1 = (k + half_width) * new_slice_size * is_3d;
04100 int cur_k2 = k * slice_size;
04101
04102 for (int i = 0; i < height; i++) {
04103 int cur_i1 = (i + half_width) * new_width;
04104 int cur_i2 = i * width;
04105
04106 for (int j = 0; j < width; j++) {
04107 int k1 = cur_k1 + cur_i1 + (j + half_width);
04108 int k2 = cur_k2 + cur_i2 + j;
04109 old_img[k1] = new_img[k2];
04110 }
04111 }
04112 }
04113
04114 for (int k = 0; k < slicenum; k++) {
04115 int cur_k = (k + half_width) * new_slice_size * is_3d;
04116
04117 for (int i = 0; i < height; i++) {
04118 int cur_i = (i + half_width) * new_width;
04119
04120 for (int j = 0; j < half_width; j++) {
04121 int k1 = cur_k + cur_i + j;
04122 int k2 = cur_k + cur_i + (2 * half_width - j);
04123 old_img[k1] = old_img[k2];
04124 }
04125
04126 for (int j = 0; j < half_width; j++) {
04127 int k1 = cur_k + cur_i + (width + half_width + j);
04128 int k2 = cur_k + cur_i + (width + half_width - j - 2);
04129 old_img[k1] = old_img[k2];
04130 }
04131 }
04132
04133
04134 for (int i = 0; i < half_width; i++) {
04135 int i2 = i * new_width;
04136 int i3 = (2 * half_width - i) * new_width;
04137 for (int j = 0; j < (width + 2 * half_width); j++) {
04138 int k1 = cur_k + i2 + j;
04139 int k2 = cur_k + i3 + j;
04140 old_img[k1] = old_img[k2];
04141 }
04142
04143 i2 = (height + half_width + i) * new_width;
04144 i3 = (height + half_width - 2 - i) * new_width;
04145 for (int j = 0; j < (width + 2 * half_width); j++) {
04146 int k1 = cur_k + i2 + j;
04147 int k2 = cur_k + i3 + j;
04148 old_img[k1] = old_img[k2];
04149 }
04150 }
04151 }
04152
04153 size_t idx;
04154 for (int k = 0; k < slicenum; k++) {
04155 int cur_k = (k + half_width) * new_slice_size;
04156
04157 for (int i = 0; i < height; i++) {
04158 int cur_i = (i + half_width) * new_width;
04159
04160 for (int j = 0; j < width; j++) {
04161 float f1 = 0;
04162 float f2 = 0;
04163 int k1 = cur_k + cur_i + (j + half_width);
04164
04165 for (int p = zstart; p <= zend; p++) {
04166 int cur_p1 = (p + half_width) * (2 * half_width + 1) * (2 * half_width + 1);
04167 int cur_p2 = (k + half_width + p) * new_slice_size;
04168
04169 for (int m = -half_width; m <= half_width; m++) {
04170 int cur_m1 = (m + half_width) * (2 * half_width + 1);
04171 int cur_m2 = cur_p2 + cur_i + m * new_width + j + half_width;
04172
04173 for (int n = -half_width; n <= half_width; n++) {
04174 int k = cur_p1 + cur_m1 + (n + half_width);
04175 int k2 = cur_m2 + n;
04176 float f3 = Util::square(old_img[k1] - old_img[k2]);
04177
04178 f3 = mask[k] * (1.0f / (1 + f3 / value_sigma));
04179 f1 += f3;
04180 int l1 = cur_m2 + n;
04181 f2 += f3 * old_img[l1];
04182 }
04183
04184 idx = k * height * width + i * width + j;
04185 new_img[idx] = f2 / f1;
04186 }
04187 }
04188 }
04189 }
04190 }
04191 iter++;
04192 }
04193 if( mask ) {
04194 free(mask);
04195 mask = 0;
04196 }
04197
04198 if( old_img ) {
04199 free(old_img);
04200 old_img = 0;
04201 }
04202 }
04203
04204 image->update();
04205 }
04206
04207 void RotationalAverageProcessor::process_inplace(EMData * image)
04208 {
04209 if (!image || image->is_complex()) {
04210 LOGWARN("only works on real image. do nothing.");
04211 return;
04212 }
04213
04214 if (image->get_ndim() <= 0 || image->get_ndim() > 3) throw ImageDimensionException("radial average processor only works for 2D and 3D images");
04215
04216 float *rdata = image->get_data();
04217 int nx = image->get_xsize();
04218 int ny = image->get_ysize();
04219
04220 vector < float >dist = image->calc_radial_dist(nx / 2, 0, 1,0);
04221
04222 float midx = (float)((int)nx/2);
04223 float midy = (float)((int)ny/2);
04224
04225 size_t c = 0;
04226 if (image->get_ndim() == 2) {
04227 for (int y = 0; y < ny; y++) {
04228 for (int x = 0; x < nx; x++, c++) {
04229 #ifdef _WIN32
04230 float r = (float) _hypot(x - midx, y - midy);
04231 #else
04232 float r = (float) hypot(x - midx, y - midy);
04233 #endif //_WIN32
04234
04235
04236 int i = (int) floor(r);
04237 r -= i;
04238 if (i >= 0 && i < nx / 2 - 1) {
04239 rdata[c] = dist[i] * (1.0f - r) + dist[i + 1] * r;
04240 }
04241 else if (i < 0) {
04242 rdata[c] = dist[0];
04243 }
04244 else {
04245 rdata[c] = 0;
04246 }
04247 }
04248 }
04249 }
04250 else if (image->get_ndim() == 3) {
04251 int nz = image->get_zsize();
04252 float midz = (float)((int)nz/2);
04253 float r;
04254 int i;
04255 for (int z = 0; z < nz; ++z) {
04256 for (int y = 0; y < ny; ++y) {
04257 for (int x = 0; x < nx; ++x, ++c) {
04258
04259 r = (float) Util::hypot3(x - midx, y - midy, z - midz);
04260
04261 i = Util::fast_floor(r);
04262 r -= i;
04263 if (i >= 0 && i < nx / 2 - 1) {
04264 rdata[c] = dist[i] * (1.0f - r) + dist[i + 1] * r;
04265 }
04266 else if (i < 0) {
04267 rdata[c] = dist[0];
04268 }
04269 else {
04270 rdata[c] = 0;
04271 }
04272 }
04273 }
04274 }
04275 }
04276
04277 image->update();
04278 }
04279
04280
04281
04282 void RotationalSubstractProcessor::process_inplace(EMData * image)
04283 {
04284 if (!image || image->is_complex()) {
04285 LOGWARN("only works on real image. do nothing.");
04286 return;
04287 }
04288
04289 if (image->get_ndim() != 2) throw ImageDimensionException("This processor works only for 2D images");
04290
04291 float *rdata = image->get_data();
04292 int nx = image->get_xsize();
04293 int ny = image->get_ysize();
04294
04295 vector < float >dist = image->calc_radial_dist(nx / 2, 0, 1,0);
04296
04297 int c = 0;
04298 for (int y = 0; y < ny; y++) {
04299 for (int x = 0; x < nx; x++, c++) {
04300 #ifdef _WIN32
04301 float r = (float) _hypot(x - nx / 2, y - ny / 2);
04302 #else
04303 float r = (float) hypot(x - nx / 2, y - ny / 2);
04304 #endif
04305 int i = (int) floor(r);
04306 r -= i;
04307 if (i >= 0 && i < nx / 2 - 1) {
04308 rdata[c] -= dist[i] * (1.0f - r) + dist[i + 1] * r;
04309 }
04310 else {
04311 rdata[c] = 0;
04312 }
04313 }
04314 }
04315
04316 image->update();
04317 }
04318
04319
04320 EMData* TransposeProcessor::process(const EMData* const image) {
04321 if (image->get_ndim() != 2) throw UnexpectedBehaviorException("Transpose processor only works with 2D images");
04322 if (image->is_complex()) throw UnexpectedBehaviorException("Transpose processor only works with real images");
04323
04324 EMData* ret = new EMData(image->get_ysize(),image->get_xsize(),1);
04325
04326 for(int j = 0; j< image->get_ysize();++j) {
04327 for(int i = 0; i< image->get_xsize();++i) {
04328 ret->set_value_at(j,i,image->get_value_at(i,j));
04329 }
04330 }
04331
04332 return ret;
04333
04334 }
04335
04336 void TransposeProcessor::process_inplace(EMData* image) {
04337 if (image->get_ndim() != 2) throw UnexpectedBehaviorException("Transpose processor only works with 2D images");
04338 if (image->is_complex()) throw UnexpectedBehaviorException("Transpose processor only works with real images");
04339
04340 float* data = (float*)malloc(image->get_ysize()*image->get_xsize()*sizeof(float));
04341
04342 int nx = image->get_ysize();
04343 for(int j = 0; j< image->get_ysize();++j) {
04344 for(int i = 0; i< image->get_xsize();++i) {
04345 data[i*nx+j] = image->get_value_at(i,j);
04346 }
04347 }
04348
04349 image->set_data(data,image->get_ysize(),image->get_xsize(),1);
04350
04351 }
04352
04353 void FlipProcessor::process_inplace(EMData * image)
04354 {
04355 ENTERFUNC;
04356 if (!image) {
04357 LOGWARN("NULL Image");
04358 return;
04359 }
04360 string axis = (const char*)params["axis"];
04361 #ifdef EMAN2_USING_CUDA
04362 if (image->gpu_operation_preferred()) {
04363 float array[12] = {1.0, 0.0, 0.0, 0.0,
04364 0.0, 1.0, 0.0, 0.0,
04365 0.0, 0.0, 1.0, 0.0};
04366 if (axis == "x" || axis == "X") {
04367 array[0] = -1.0;
04368 }else if (axis == "y" || axis == "Y") {
04369 array[5] = -1.0;
04370 }
04371 else if (axis == "z" || axis == "Z") {
04372 array[10] = -1.0;
04373 }
04374 Transform t(array);
04375 Dict params("transform",(Transform*)&t);
04376 image->process_inplace("xform",params);
04377 EXITFUNC;
04378 return;
04379 }
04380 #endif
04381
04382
04383 float *d = image->get_data();
04384 int nx = image->get_xsize();
04385 int ny = image->get_ysize();
04386 int nz = image->get_zsize();
04387
04388 size_t nxy = nx * ny;
04389
04390
04391
04392
04393
04394
04395 if (axis == "x" || axis == "X") {
04396 int offset = (nx%2 == 0);
04397 size_t idx1, idx2;
04398 for(int z = 0; z < nz; ++z) {
04399 for(int y = 0; y < ny; ++y) {
04400 if (offset != 0 ) {
04401 idx1 = z*nxy + y*nx;
04402 d[idx1] = 0;
04403 }
04404 for(int x = offset; x < nx / 2; ++x) {
04405 idx1 = z*nxy + y*nx + x;
04406 idx2 = z*nxy + y*nx + (nx-x-1+offset);
04407 std::swap(d[idx1], d[idx2]);
04408 }
04409
04410 }
04411 }
04412 }
04413
04414 else if (axis == "y" || axis == "Y") {
04415 int offset = (ny%2 == 0);
04416 for(int z=0; z<nz; ++z) {
04417 if (offset != 0) {
04418 std::fill(d+z*nxy,d+z*nxy+nx,0);
04419 }
04420 for(int y=offset; y<ny/2; ++y) {
04421 for(int x=0; x<nx; ++x) {
04422 std::swap(d[z*nxy + y*nx +x], d[z*nxy + (ny -y -1+offset)*nx +x]);
04423 }
04424 }
04425 }
04426 }
04427 else if (axis == "z" || axis == "Z") {
04428 int offset = (nz%2 == 0);
04429 if (offset != 0) {
04430 std::fill(d,d+nxy,0);
04431 }
04432 size_t idx1, idx2;
04433 for(int z=offset; z<nz/2; ++z) {
04434 for(int y=0; y<ny; ++y) {
04435 for(int x=0; x<nx; ++x) {
04436 idx1 = z*nxy + y*nx + x;
04437 idx2 = (nz-z-1+offset)*nxy + y*nx + x;
04438 std::swap(d[idx1], d[idx2]);
04439 }
04440 }
04441 }
04442 }
04443
04444 image->update();
04445 EXITFUNC;
04446 }
04447
04448 void AddNoiseProcessor::process_inplace(EMData * image)
04449 {
04450 if (!image) {
04451 LOGWARN("NULL Image");
04452 return;
04453 }
04454
04455 Randnum * randnum = Randnum::Instance();
04456 if(params.has_key("seed")) {
04457 randnum->set_seed((int)params["seed"]);
04458 }
04459
04460 float addnoise = params["noise"];
04461 addnoise *= get_sigma(image);
04462 float *dat = image->get_data();
04463
04464 for (size_t j = 0; j < image->get_size(); ++j) {
04465 dat[j] += randnum->get_gauss_rand(addnoise, addnoise / 2);
04466 }
04467
04468 image->update();
04469 }
04470
04471 float AddSigmaNoiseProcessor::get_sigma(EMData * image)
04472 {
04473 if (!image) {
04474 LOGWARN("NULL Image");
04475 return 0;
04476 }
04477 return image->get_attr("sigma");
04478 }
04479
04480 void FourierToCornerProcessor::process_inplace(EMData * image)
04481 {
04482 if ( !image->is_complex() ) throw ImageFormatException("Can not Fourier origin shift an image that is not complex");
04483
04484 int nx=image->get_xsize();
04485 int ny=image->get_ysize();
04486 int nz=image->get_zsize();
04487
04488 int nxy = nx*ny;
04489
04490 if ( ny == 1 && nz == 1 ){
04491 cout << "Warning- attempted Fourier origin shift a 1D image - no action taken" << endl;
04492 return;
04493 }
04494 int yodd = (ny%2==1);
04495 int zodd = (nz%2==1);
04496
04497 float* rdata = image->get_data();
04498
04499 float tmp[2];
04500 float* p1;
04501 float* p2;
04502
04503 if (yodd){
04504
04505
04506
04507
04508 float prev[2];
04509 size_t idx;
04510 for( int s = 0; s < nz; s++ ) {
04511 for( int c =0; c < nx; c += 2 ) {
04512 idx = s*nxy+ny/2*nx+c;
04513 prev[0] = rdata[idx];
04514 prev[1] = rdata[idx+1];
04515 for( int r = 0; r <= ny/2; ++r ) {
04516 idx = s*nxy+r*nx+c;
04517 float* p1 = &rdata[idx];
04518 tmp[0] = p1[0];
04519 tmp[1] = p1[1];
04520
04521 p1[0] = prev[0];
04522 p1[1] = prev[1];
04523
04524 prev[0] = tmp[0];
04525 prev[1] = tmp[1];
04526 }
04527 }
04528 }
04529 }
04530
04531
04532 size_t idx1, idx2;
04533 for( int s = 0; s < nz; ++s ) {
04534 for( int r = 0 + yodd; r < ny/2+yodd; ++r ) {
04535 for( int c =0; c < nx; c += 2 ) {
04536 idx1 = s*nxy+r*nx+c;
04537 idx2 = s*nxy+(r+ny/2)*nx+c;
04538 p1 = &rdata[idx1];
04539 p2 = &rdata[idx2];
04540
04541 tmp[0] = p1[0];
04542 tmp[1] = p1[1];
04543
04544 p1[0] = p2[0];
04545 p1[1] = p2[1];
04546
04547 p2[0] = tmp[0];
04548 p2[1] = tmp[1];
04549 }
04550 }
04551 }
04552
04553 if ( nz != 1 )
04554 {
04555
04556 if (zodd){
04557
04558
04559
04560 float prev[2];
04561 size_t idx;
04562 for( int r = 0; r < ny; ++r ) {
04563 for( int c =0; c < nx; c += 2 ) {
04564 idx = nz/2*nxy+r*nx+c;
04565 prev[0] = rdata[idx];
04566 prev[1] = rdata[idx+1];
04567 for( int s = 0; s <= nz/2; ++s ) {
04568 idx = s*nxy+r*nx+c;
04569 float* p1 = &rdata[idx];
04570 tmp[0] = p1[0];
04571 tmp[1] = p1[1];
04572
04573 p1[0] = prev[0];
04574 p1[1] = prev[1];
04575
04576 prev[0] = tmp[0];
04577 prev[1] = tmp[1];
04578 }
04579 }
04580 }
04581 }
04582
04583
04584 size_t idx1, idx2;
04585 for( int s = 0+zodd; s < nz/2 + zodd; ++s ) {
04586 for( int r = 0; r < ny; ++r ) {
04587 for( int c =0; c < nx; c += 2 ) {
04588 idx1 = s*nxy+r*nx+c;
04589 idx2 = (s+nz/2)*nxy+r*nx+c;
04590 p1 = &rdata[idx1];
04591 p2 = &rdata[idx2];
04592
04593 tmp[0] = p1[0];
04594 tmp[1] = p1[1];
04595
04596 p1[0] = p2[0];
04597 p1[1] = p2[1];
04598
04599 p2[0] = tmp[0];
04600 p2[1] = tmp[1];
04601 }
04602 }
04603 }
04604 }
04605 image->set_shuffled(false);
04606 }
04607
04608 void FourierToCenterProcessor::process_inplace(EMData * image)
04609 {
04610
04611
04612 int nx=image->get_xsize();
04613 int ny=image->get_ysize();
04614 int nz=image->get_zsize();
04615
04616 int nxy = nx*ny;
04617
04618 if ( ny == 1 && nz == 1 ){
04619 cout << "Warning- attempted Fourier origin shift a 1D image - no action taken" << endl;
04620 return;
04621 }
04622
04623 int yodd = (ny%2==1);
04624 int zodd = (nz%2==1);
04625
04626 float* rdata = image->get_data();
04627
04628 float tmp[2];
04629 float* p1;
04630 float* p2;
04631
04632
04633
04634 if ( !image->is_complex() ) {
04635 if (nz!=1 && !yodd && !zodd) {
04636 for (int x=0; x<nx; x++) {
04637 for (int y=0; y<ny; y++) {
04638 for (int z=0; z<nz/2; z++) {
04639 int y2=(y+ny/2)%ny;
04640 int z2=(z+nz/2)%nz;
04641 size_t i=x+y*nx+z*nxy;
04642 size_t i2=x+y2*nx+z2*nxy;
04643 float swp=rdata[i];
04644 rdata[i]=rdata[i2];
04645 rdata[i2]=swp;
04646 }
04647 }
04648 }
04649
04650 return;
04651 }
04652 else throw ImageFormatException("Can not Fourier origin shift an image that is not complex unless it is even in ny,nz and nx=ny/2+1");
04653 }
04654
04655 if (yodd){
04656
04657
04658 float prev[2];
04659 size_t idx;
04660 for( int s = 0; s < nz; s++ ) {
04661 for( int c =0; c < nx; c += 2 ) {
04662 idx = s*nxy+c;
04663 prev[0] = rdata[idx];
04664 prev[1] = rdata[idx+1];
04665 for( int r = ny/2; r >= 0; --r ) {
04666 idx = s*nxy+r*nx+c;
04667 float* p1 = &rdata[idx];
04668 tmp[0] = p1[0];
04669 tmp[1] = p1[1];
04670
04671 p1[0] = prev[0];
04672 p1[1] = prev[1];
04673
04674 prev[0] = tmp[0];
04675 prev[1] = tmp[1];
04676 }
04677 }
04678 }
04679 }
04680
04681
04682 size_t idx1, idx2;
04683 for( int s = 0; s < nz; ++s ) {
04684 for( int r = 0; r < ny/2; ++r ) {
04685 for( int c =0; c < nx; c += 2 ) {
04686 idx1 = s*nxy+r*nx+c;
04687 idx2 = s*nxy+(r+ny/2+yodd)*nx+c;
04688 p1 = &rdata[idx1];
04689 p2 = &rdata[idx2];
04690
04691 tmp[0] = p1[0];
04692 tmp[1] = p1[1];
04693
04694 p1[0] = p2[0];
04695 p1[1] = p2[1];
04696
04697 p2[0] = tmp[0];
04698 p2[1] = tmp[1];
04699 }
04700 }
04701 }
04702
04703 if ( nz != 1 ) {
04704 if (zodd){
04705
04706
04707 float prev[2];
04708 size_t idx;
04709 for( int r = 0; r < ny; ++r ) {
04710 for( int c =0; c < nx; c += 2 ) {
04711 prev[0] = rdata[r*nx+c];
04712 prev[1] = rdata[r*nx+c+1];
04713 for( int s = nz/2; s >= 0; --s ) {
04714 idx = s*nxy+r*nx+c;
04715 float* p1 = &rdata[idx];
04716 tmp[0] = p1[0];
04717 tmp[1] = p1[1];
04718
04719 p1[0] = prev[0];
04720 p1[1] = prev[1];
04721
04722 prev[0] = tmp[0];
04723 prev[1] = tmp[1];
04724 }
04725 }
04726 }
04727 }
04728
04729
04730 size_t idx1, idx2;
04731 for( int s = 0; s < nz/2; ++s ) {
04732 for( int r = 0; r < ny; ++r ) {
04733 for( int c =0; c < nx; c += 2 ) {
04734 idx1 = s*nxy+r*nx+c;
04735 idx2 = (s+nz/2+zodd)*nxy+r*nx+c;
04736 p1 = &rdata[idx1];
04737 p2 = &rdata[idx2];
04738
04739 tmp[0] = p1[0];
04740 tmp[1] = p1[1];
04741
04742 p1[0] = p2[0];
04743 p1[1] = p2[1];
04744
04745 p2[0] = tmp[0];
04746 p2[1] = tmp[1];
04747 }
04748 }
04749 }
04750 }
04751 image->set_shuffled(true);
04752 }
04753
04754 void Phase180Processor::fourier_phaseshift180(EMData * image)
04755 {
04756 if ( !image->is_complex() ) throw ImageFormatException("Can not handle images that are not complex in fourier phase shift 180");
04757
04758 int nx = image->get_xsize();
04759 int ny = image->get_ysize();
04760 int nz = image->get_zsize();
04761
04762 int nxy = nx * ny;
04763
04764 float *rdata = image->get_data();
04765
04766
04767
04768 int of=0;
04769 if (((ny/2)%2)+((nz/2)%2)==1) of=1;
04770
04771 for (int k = 0; k < nz; k++) {
04772 size_t k2 = k * nxy;
04773
04774 for (int j = 0; j < ny; j++) {
04775 int i = ((k+j)%2==of?2:0);
04776 size_t j2 = j * nx + k2;
04777
04778 for (; i < nx; i += 4) {
04779 rdata[i + j2] *= -1.0f;
04780 rdata[i + j2 + 1] *= -1.0f;
04781 }
04782 }
04783 }
04784 }
04785
04786 void Phase180Processor::swap_corners_180(EMData * image)
04787 {
04788 int nx = image->get_xsize();
04789 int ny = image->get_ysize();
04790 int nz = image->get_zsize();
04791
04792 int xodd = (nx % 2) == 1;
04793 int yodd = (ny % 2) == 1;
04794 int zodd = (nz % 2) == 1;
04795
04796 int nxy = nx * ny;
04797
04798 float *rdata = image->get_data();
04799
04800 if ( ny == 1 && nz == 1 ){
04801 throw ImageDimensionException("Error, cannot handle 1D images. This function should not have been called");
04802 }
04803 else if ( nz == 1 ) {
04804
04805
04806 for ( int r = 0; r < ny/2; ++r ) {
04807 for ( int c = 0; c < nx/2; ++c) {
04808 int idx1 = r*nx + c;
04809 int idx2 = (r+ny/2+yodd)*nx + c + nx/2+xodd;
04810 float tmp = rdata[idx1];
04811 rdata[idx1] = rdata[idx2];
04812 rdata[idx2] = tmp;
04813 }
04814 }
04815
04816
04817 for ( int r = ny-1; r >= (ny/2+yodd); --r ) {
04818 for ( int c = 0; c < nx/2; ++c) {
04819 int idx1 = r*nx + c;
04820 int idx2 = (r-ny/2-yodd)*nx + c + nx/2+xodd;
04821 float tmp = rdata[idx1];
04822 rdata[idx1] = rdata[idx2];
04823 rdata[idx2] = tmp;
04824 }
04825 }
04826 }
04827 else
04828 {
04829 float tmp;
04830
04831 size_t idx1, idx2;
04832
04833 for ( int s = 0; s < nz/2; ++s ) {
04834 for ( int r = 0; r < ny/2; ++r ) {
04835 for ( int c = 0; c < nx/2; ++ c) {
04836 idx1 = s*nxy+r*nx+c;
04837 idx2 = (s+nz/2+zodd)*nxy+(r+ny/2+yodd)*nx+c+nx/2+xodd;
04838 tmp = rdata[idx1];
04839 rdata[idx1] = rdata[idx2];
04840 rdata[idx2] = tmp;
04841 }
04842 }
04843 }
04844
04845 for ( int s = 0; s < nz/2; ++s ) {
04846 for ( int r = 0; r < ny/2; ++r ) {
04847 for ( int c = nx-1; c >= (nx/2+xodd); --c) {
04848 idx1 = s*nxy+r*nx+c;
04849 idx2 = (s+nz/2+zodd)*nxy+(r+ny/2+yodd)*nx+c-nx/2-xodd;
04850 tmp = rdata[idx1];
04851 rdata[idx1] = rdata[idx2];
04852 rdata[idx2] = tmp;
04853 }
04854 }
04855 }
04856
04857 for ( int s = 0; s < nz/2; ++s ) {
04858 for ( int r = ny-1; r >= (ny/2+yodd); --r ) {
04859 for ( int c = nx-1; c >= (nx/2+xodd); --c) {
04860 idx1 = s*nxy+r*nx+c;
04861 idx2 = (s+nz/2+zodd)*nxy+(r-ny/2-yodd)*nx+c-nx/2-xodd;
04862 tmp = rdata[idx1];
04863 rdata[idx1] = rdata[idx2];
04864 rdata[idx2] = tmp;
04865 }
04866 }
04867 }
04868
04869 for ( int s = 0; s < nz/2; ++s ) {
04870 for ( int r = ny-1; r >= (ny/2+yodd); --r ) {
04871 for ( int c = 0; c < nx/2; ++c) {
04872 idx1 = s*nxy+r*nx+c;
04873 idx2 = (s+nz/2+zodd)*nxy+(r-ny/2-yodd)*nx+c+nx/2+xodd;
04874 tmp = rdata[idx1];
04875 rdata[idx1] = rdata[idx2];
04876 rdata[idx2] = tmp;
04877 }
04878 }
04879 }
04880 }
04881 }
04882
04883 void Phase180Processor::swap_central_slices_180(EMData * image)
04884 {
04885 int nx = image->get_xsize();
04886 int ny = image->get_ysize();
04887 int nz = image->get_zsize();
04888
04889 int xodd = (nx % 2) == 1;
04890 int yodd = (ny % 2) == 1;
04891 int zodd = (nz % 2) == 1;
04892
04893 int nxy = nx * ny;
04894
04895 float *rdata = image->get_data();
04896
04897 if ( ny == 1 && nz == 1 ){
04898 throw ImageDimensionException("Error, cannot handle 1D images. This function should not have been called");
04899 }
04900 else if ( nz == 1 ) {
04901 float tmp;
04902 if ( yodd ) {
04903
04904 int r = ny/2;
04905 for ( int c = 0; c < nx/2; ++c ) {
04906 int idx1 = r*nx + c;
04907 int idx2 = r*nx + c + nx/2+ xodd;
04908 tmp = rdata[idx1];
04909 rdata[idx1] = rdata[idx2];
04910 rdata[idx2] = tmp;
04911 }
04912 }
04913
04914 if ( xodd ) {
04915
04916 int c = nx/2;
04917 for ( int r = 0; r < ny/2; ++r ) {
04918 int idx1 = r*nx + c;
04919 int idx2 = (r+ny/2+yodd)*nx + c;
04920 tmp = rdata[idx1];
04921 rdata[idx1] = rdata[idx2];
04922 rdata[idx2] = tmp;
04923 }
04924 }
04925 }
04926 else
04927 {
04928 float tmp;
04929 if ( xodd ) {
04930
04931 int c = nx/2;
04932 size_t idx1, idx2;
04933 for( int s = 0; s < nz/2; ++s ) {
04934 for ( int r = 0; r < ny/2; ++r ) {
04935 idx1 = s*nxy+r*nx+c;
04936 idx2 = (s+nz/2+zodd)*nxy+(r+ny/2+yodd)*nx+c;
04937 tmp = rdata[idx1];
04938 rdata[idx1] = rdata[idx2];
04939 rdata[idx2] = tmp;
04940 }
04941 }
04942
04943 for( int s = nz-1; s >= (nz/2+zodd); --s ) {
04944 for ( int r = 0; r < ny/2; ++r ) {
04945 idx1 = s*nxy+r*nx+c;
04946 idx2 = (s-nz/2-zodd)*nxy+(r+ny/2+yodd)*nx+c;
04947 tmp = rdata[idx1];
04948 rdata[idx1] = rdata[idx2];
04949 rdata[idx2] = tmp;
04950 }
04951 }
04952 }
04953 if ( yodd ) {
04954
04955 int r = ny/2;
04956 size_t idx1, idx2;
04957 for( int s = 0; s < nz/2; ++s ) {
04958 for ( int c = 0; c < nx/2; ++c ) {
04959 idx1 = s*nxy+r*nx+c;
04960 idx2 =(s+nz/2+zodd)*nxy+r*nx+c+nx/2+xodd;
04961 tmp = rdata[idx1];
04962 rdata[idx1] = rdata[idx2];
04963 rdata[idx2] = tmp;
04964 }
04965 }
04966
04967 for( int s = nz-1; s >= (nz/2+zodd); --s ) {
04968 for ( int c = 0; c < nx/2; ++c ) {
04969 idx1 = s*nxy+r*nx+c;
04970 idx2 = (s-nz/2-zodd)*nxy+r*nx+c+nx/2+xodd;
04971 tmp = rdata[idx1];
04972 rdata[idx1] = rdata[idx2];
04973 rdata[idx2] = tmp;
04974 }
04975 }
04976 }
04977 if ( zodd ) {
04978
04979 int s = nz/2;
04980 size_t idx1, idx2;
04981 for( int r = 0; r < ny/2; ++r ) {
04982 for ( int c = 0; c < nx/2; ++c ) {
04983 idx1 = s*nxy+r*nx+c;
04984 idx2 = s*nxy+(r+ny/2+yodd)*nx+c+nx/2+xodd;
04985 tmp = rdata[idx1];
04986 rdata[idx1] = rdata[idx2];
04987 rdata[idx2] = tmp;
04988 }
04989 }
04990
04991 for( int r = ny-1; r >= (ny/2+yodd); --r ) {
04992 for ( int c = 0; c < nx/2; ++c ) {
04993 idx1 = s*nxy+r*nx+c;
04994 idx2 = s*nxy+(r-ny/2-yodd)*nx+c+nx/2+xodd;
04995 tmp = rdata[idx1];
04996 rdata[idx1] = rdata[idx2];
04997 rdata[idx2] = tmp;
04998 }
04999 }
05000 }
05001 }
05002 }
05003
05004 void PhaseToCornerProcessor::process_inplace(EMData * image)
05005 {
05006 if (!image) throw NullPointerException("Error: attempt to phase shift a null image");
05007
05008 if (image->is_complex()) {
05009 fourier_phaseshift180(image);
05010 return;
05011 }
05012
05013 int nx = image->get_xsize();
05014 int ny = image->get_ysize();
05015 int nz = image->get_zsize();
05016
05017 if ( ny == 1 && nz == 1 && nx == 1) return;
05018
05019 int nxy = nx * ny;
05020
05021 float *rdata = image->get_data();
05022
05023 bool xodd = (nx % 2) == 1;
05024 bool yodd = (ny % 2) == 1;
05025 bool zodd = (nz % 2) == 1;
05026
05027 if ( ny == 1 && nz == 1 ){
05028 if (xodd){
05029
05030
05031 float in_x = rdata[nx-1];
05032 float tmp;
05033 for ( int i = nx/2; i < nx; ++i ) {
05034 tmp = rdata[i];
05035 rdata[i] = in_x;
05036 in_x = tmp;
05037 }
05038 }
05039
05040 for ( int i = 0; i < nx/2; ++i ) {
05041 int idx = i+nx/2+xodd;
05042 float tmp = rdata[i];
05043 rdata[i] = rdata[idx];
05044 rdata[idx] = tmp;
05045 }
05046
05047 }
05048 else if ( nz == 1 ) {
05049 if (yodd) {
05050
05051
05052 for ( int c = 0; c < nx; ++c ) {
05053
05054 float last_val = rdata[(ny-1)*nx + c];
05055 float tmp;
05056 for ( int r = ny/2; r < ny; ++r ){
05057 int idx =r*nx+c;
05058 tmp = rdata[idx];
05059 rdata[idx] = last_val;
05060 last_val = tmp;
05061 }
05062 }
05063 }
05064
05065 if (xodd) {
05066
05067
05068 for ( int r = 0; r < ny; ++r ) {
05069 float last_val = rdata[(r+1)*nx -1];
05070 float tmp;
05071 for ( int c = nx/2; c < nx; ++c ){
05072 int idx =r*nx+c;
05073 tmp = rdata[idx];
05074 rdata[idx] = last_val;
05075 last_val = tmp;
05076 }
05077 }
05078 }
05079
05080 swap_central_slices_180(image);
05081
05082 swap_corners_180(image);
05083
05084 }
05085 else
05086 {
05087 float tmp;
05088 if (zodd) {
05089
05090
05091 size_t idx = 0;
05092 for (int r = 0; r < ny; ++r){
05093 for (int c = 0; c < nx; ++c) {
05094 float last_val = rdata[(nz-1)*nxy+r*nx+c];
05095 for (int s = nz/2; s < nz; ++s) {
05096 idx = s*nxy+r*nx+c;
05097 tmp = rdata[idx];
05098 rdata[idx] = last_val;
05099 last_val = tmp;
05100 }
05101 }
05102 }
05103 }
05104 if (yodd) {
05105
05106
05107 size_t idx = 0;
05108 for (int s = 0; s < nz; ++s) {
05109 for (int c = 0; c < nx; ++c) {
05110 float last_val = rdata[s*nxy+(ny-1)*nx+c];
05111 for (int r = ny/2; r < ny; ++r){
05112 idx = s*nxy+r*nx+c;
05113 tmp = rdata[idx];
05114 rdata[idx] = last_val;
05115 last_val = tmp;
05116 }
05117 }
05118 }
05119 }
05120 if (xodd) {
05121
05122
05123 size_t idx = 0;
05124 for (int s = 0; s < nz; ++s) {
05125 for (int r = 0; r < ny; ++r) {
05126 float last_val = rdata[s*nxy+r*nx+nx-1];
05127 for (int c = nx/2; c < nx; ++c){
05128 idx = s*nxy+r*nx+c;
05129 tmp = rdata[idx];
05130 rdata[idx] = last_val;
05131 last_val = tmp;
05132 }
05133 }
05134 }
05135 }
05136
05137 swap_central_slices_180(image);
05138
05139 swap_corners_180(image);
05140 }
05141 }
05142
05143
05144 void PhaseToCenterProcessor::process_inplace(EMData * image)
05145 {
05146 if (!image) throw NullPointerException("Error: attempt to phase shift a null image");
05147 bool proceed = true;
05148
05149 #ifdef EMAN2_USING_CUDA
05150 bool cpu = image->cpu_rw_is_current();
05151 bool gpu = image->gpu_rw_is_current();
05152 if ( !cpu && !gpu )
05153 throw UnexpectedBehaviorException("Both the CPU and GPU data are not current");
05154 if (gpu && image->get_ndim() == 2) {
05155 EMDataForCuda tmp = image->get_data_struct_for_cuda();
05156 emdata_phaseorigin_to_center(&tmp);
05157 proceed = false;
05158 image->gpu_update();
05159 }
05160 #endif // EMAN2_USING_CUDA
05161 if (!proceed) return;
05162
05163 if (image->is_complex()) {
05164 fourier_phaseshift180(image);
05165 return;
05166 }
05167
05168 int nx = image->get_xsize();
05169 int ny = image->get_ysize();
05170 int nz = image->get_zsize();
05171
05172 if ( ny == 1 && nz == 1 && nx == 1) return;
05173
05174 int nxy = nx * ny;
05175
05176 float *rdata = image->get_data();
05177
05178 bool xodd = (nx % 2) == 1;
05179 bool yodd = (ny % 2) == 1;
05180 bool zodd = (nz % 2) == 1;
05181
05182 if ( ny == 1 && nz == 1 ){
05183 if (xodd) {
05184
05185
05186 float in_x = rdata[nx/2];
05187 float tmp;
05188 for ( int i = nx-1; i >= nx/2; --i ) {
05189 tmp = rdata[i];
05190 rdata[i] = in_x;
05191 in_x = tmp;
05192 }
05193 }
05194
05195 for ( int i = 0; i < nx/2; ++i ) {
05196 int idx = i + nx/2;
05197 float tmp = rdata[i];
05198 rdata[i] = rdata[idx];
05199 rdata[idx] = tmp;
05200 }
05201 }
05202 else if ( nz == 1 ){
05203
05204
05205
05206 swap_corners_180(image);
05207
05208 swap_central_slices_180(image);
05209
05210 float tmp;
05211
05212 if (xodd) {
05213
05214
05215 for ( int r = 0; r < ny; ++r ) {
05216 float last_val = rdata[r*nx+nx/2];
05217 for ( int c = nx-1; c >= nx/2; --c ){
05218 int idx = r*nx+c;
05219 tmp = rdata[idx];
05220 rdata[idx] = last_val;
05221 last_val = tmp;
05222 }
05223 }
05224 }
05225 if (yodd) {
05226
05227
05228 for ( int c = 0; c < nx; ++c ) {
05229
05230 float last_val = rdata[ny/2*nx + c];
05231 for ( int r = ny-1; r >= ny/2; --r ){
05232 int idx = r*nx+c;
05233 tmp = rdata[idx];
05234 rdata[idx] = last_val;
05235 last_val = tmp;
05236 }
05237 }
05238 }
05239 }
05240 else
05241 {
05242
05243
05244
05245 swap_corners_180(image);
05246
05247 swap_central_slices_180(image);
05248
05249 float tmp;
05250
05251 if (xodd) {
05252
05253
05254
05255 size_t idx = 0;
05256 for (int s = 0; s < nz; ++s) {
05257 for (int r = 0; r < ny; ++r) {
05258 float last_val = rdata[s*nxy+r*nx+nx/2];
05259 for (int c = nx-1; c >= nx/2; --c){
05260 idx = s*nxy+r*nx+c;
05261 tmp = rdata[idx];
05262 rdata[idx] = last_val;
05263 last_val = tmp;
05264 }
05265 }
05266 }
05267 }
05268 if (yodd) {
05269
05270
05271 size_t idx = 0;
05272 for (int s = 0; s < nz; ++s) {
05273 for (int c = 0; c < nx; ++c) {
05274 float last_val = rdata[s*nxy+ny/2*nx+c];
05275 for (int r = ny-1; r >= ny/2; --r){
05276 idx = s*nxy+r*nx+c;
05277 tmp = rdata[idx];
05278 rdata[idx] = last_val;
05279 last_val = tmp;
05280 }
05281 }
05282 }
05283 }
05284 if (zodd) {
05285
05286
05287 size_t idx = 0;
05288 for (int r = 0; r < ny; ++r){
05289 for (int c = 0; c < nx; ++c) {
05290 float last_val = rdata[nz/2*nxy+r*nx+c];
05291 for (int s = nz-1; s >= nz/2; --s) {
05292 idx = s*nxy+r*nx+c;
05293 tmp = rdata[idx];
05294 rdata[idx] = last_val;
05295 last_val = tmp;
05296 }
05297 }
05298 }
05299 }
05300
05301
05302 }
05303 }
05304
05305 void AutoMaskAsymUnit::process_inplace(EMData* image) {
05306 if (!image) {
05307 LOGWARN("NULL Image");
05308 return;
05309 }
05310
05311 int nx = image->get_xsize();
05312 int ny = image->get_ysize();
05313 int nz = image->get_zsize();
05314
05315 int ox = nx/2;
05316 int oy = ny/2;
05317 int oz = nz/2;
05318
05319 Symmetry3D* sym = Factory<Symmetry3D>::get((string)params["sym"]);
05320 int au = params.set_default("au",0);
05321
05322 float *d = image->get_data();
05323 for(int k = 0; k < nz; ++k ) {
05324 for(int j = 0; j < ny; ++j ) {
05325 for (int i = 0; i< nx; ++i, ++d) {
05326
05327 Vec3f v(i-ox,j-oy,k-oz);
05328
05329 int a = sym->point_in_which_asym_unit(v);
05330 if (au == -1) {
05331 *d = (float)a;
05332 } else {
05333 if ( a == au ) *d = 1;
05334 else *d = 0;
05335 }
05336 }
05337 }
05338 }
05339
05340 delete sym;
05341
05342 }
05343
05344 void AutoMask2DProcessor::process_inplace(EMData * image)
05345 {
05346 if (!image) {
05347 LOGWARN("NULL Image");
05348 return;
05349 }
05350
05351 if (image->get_ndim() != 2) {
05352 throw ImageDimensionException("This processor only supports 2D images.");
05353 }
05354
05355
05356
05357
05358
05359
05360
05361
05362
05363
05364
05365 int radius=0;
05366 if (params.has_key("radius")) {
05367 radius = params["radius"];
05368 }
05369 int nmaxseed=0;
05370 if (params.has_key("nmaxseed")) {
05371 nmaxseed = params["nmaxseed"];
05372 }
05373
05374 float threshold=0.0;
05375 if (params.has_key("sigma")) threshold=(float)(image->get_attr("mean"))+(float)(image->get_attr("sigma"))*(float)params["sigma"];
05376 else threshold=params["threshold"];
05377
05378
05379 int nshells = params["nshells"];
05380 int nshellsgauss = params["nshellsgauss"];
05381 int verbose=params.set_default("verbose",0);
05382
05383 int nx = image->get_xsize();
05384 int ny = image->get_ysize();
05385
05386 EMData *amask = new EMData();
05387 amask->set_size(nx, ny);
05388
05389 float *dat = image->get_data();
05390 float *dat2 = amask->get_data();
05391 int i,j;
05392 size_t l = 0;
05393
05394 if (verbose) printf("%f\t%f\t%f\n",(float)image->get_attr("mean"),(float)image->get_attr("sigma"),threshold);
05395
05396
05397 if (nmaxseed>0) {
05398 vector<Pixel> maxs=image->calc_n_highest_locations(nmaxseed);
05399
05400 for (vector<Pixel>::iterator i=maxs.begin(); i<maxs.end(); i++) {
05401 amask->set_value_at((*i).x,(*i).y,0,1.0);
05402 if (verbose) printf("Seed at %d,%d,%d (%1.3f)\n",(*i).x,(*i).y,(*i).z,(*i).value);
05403 }
05404 }
05405
05406
05407 if (radius>0) {
05408
05409 l=0;
05410 for (j = -ny / 2; j < ny / 2; ++j) {
05411 for (i = -nx / 2; i < nx / 2; ++i,++l) {
05412 if ( abs(j) > radius || abs(i) > radius) continue;
05413
05414 if ( (j * j + i * i) > (radius*radius) ) continue;
05415 dat2[l] = 1.0f;
05416 }
05417 }
05418 }
05419
05420
05421 int done=0;
05422 int iter=0;
05423 while (!done) {
05424 iter++;
05425 done=1;
05426 if (verbose && iter%10==0) printf("%d iterations\n",iter);
05427 for (j=1; j<ny-1; ++j) {
05428 for (i=1; i<nx-1; ++i) {
05429 l=i+j*nx;
05430 if (dat2[l]) continue;
05431 if (dat[l]>threshold && (dat2[l-1]||dat2[l+1]||dat2[l+nx]||dat2[l-nx])) {
05432 dat2[l]=1.0;
05433 done=0;
05434 }
05435 }
05436 }
05437 }
05438
05439 amask->update();
05440
05441 if (verbose) printf("extending mask\n");
05442 amask->process_inplace("mask.addshells.gauss", Dict("val1", nshells, "val2", nshellsgauss));
05443
05444 bool return_mask = params.set_default("return_mask",false);
05445 if (return_mask) {
05446
05447 memcpy(dat,dat2,image->get_size()*sizeof(float));
05448 } else {
05449 image->mult(*amask);
05450 }
05451
05452
05453
05454
05455
05456
05457
05458 delete amask;
05459 }
05460
05461
05462 void AddRandomNoiseProcessor::process_inplace(EMData * image)
05463 {
05464 if (!image) {
05465 LOGWARN("NULL Image");
05466 return;
05467 }
05468
05469 if (!image->is_complex()) {
05470 LOGERR("AddRandomNoise Processor only works for complex image");
05471 throw ImageFormatException("only work for complex image");
05472 }
05473
05474 int n = params["n"];
05475 float x0 = params["x0"];
05476 float dx = params["dx"];
05477 vector < float >y = params["y"];
05478
05479 int interpolation = 1;
05480 if (params.has_key("interpolation")) {
05481 interpolation = params["interpolation"];
05482 }
05483
05484 Randnum * randnum = Randnum::Instance();
05485 if(params.has_key("seed")) {
05486 randnum->set_seed((int)params["seed"]);
05487 }
05488
05489 int nx = image->get_xsize();
05490 int ny = image->get_ysize();
05491 int nz = image->get_zsize();
05492
05493 image->ap2ri();
05494 float *rdata = image->get_data();
05495
05496 size_t k = 0;
05497 float half_nz = 0;
05498 if (nz > 1) {
05499 half_nz = nz / 2.0f;
05500 }
05501
05502 const float sqrt_2 = sqrt((float) 2);
05503
05504 float r;
05505 for (int h = 0; h < nz; h++) {
05506 for (int j = 0; j < ny; j++) {
05507 for (int i = 0; i < nx; i += 2, k += 2) {
05508 r = (Util::hypot3(i / 2.0f, j - ny / 2.0f, h - half_nz));
05509
05510 r = (r - x0) / dx;
05511 int l = 0;
05512 if (interpolation) {
05513 l = Util::fast_floor(r);
05514 }
05515 else {
05516 l = Util::fast_floor(r + 0.5f);
05517 }
05518 r -= l;
05519 float f = 0;
05520 if (l >= n - 2) {
05521 f = y[n - 1];
05522 }
05523 else if (l < 0) {
05524 l = 0;
05525 }
05526 else {
05527 if (interpolation) {
05528 f = (y[l] * (1 - r) + y[l + 1] * r);
05529 }
05530 else {
05531 f = y[l];
05532 }
05533 }
05534 f = randnum->get_gauss_rand(sqrt(f), sqrt(f) / 3);
05535 float a = randnum->get_frand(0.0f, (float)(2 * M_PI));
05536 if (i == 0) {
05537 f *= sqrt_2;
05538 }
05539 rdata[k] += f * cos(a);
05540 rdata[k + 1] += f * sin(a);
05541 }
05542 }
05543 }
05544
05545 image->update();
05546 }
05547
05548 void AddMaskShellProcessor::process_inplace(EMData * image)
05549 {
05550 if (!image) {
05551 LOGWARN("NULL Image");
05552 return;
05553 }
05554
05555 int nx = image->get_xsize();
05556 int ny = image->get_ysize();
05557 int nz = image->get_zsize();
05558
05559 if (ny == 1) {
05560 LOGERR("Tried to add mask shell to 1d image");
05561 return;
05562 }
05563
05564 int num_shells = params["nshells"];
05565
05566 float *d = image->get_data();
05567 float k = 0.99999f;
05568 int nxy = nx * ny;
05569
05570 if (nz == 1) {
05571 for (int i = 0; i < num_shells; i++) {
05572 for (int y = 1; y < ny - 1; y++) {
05573 int cur_y = y * nx;
05574
05575 for (int x = 1; x < nx - 1; x++) {
05576 int j = x + cur_y;
05577 if (!d[j] && (d[j - 1] > k || d[j + 1] > k || d[j + nx] > k || d[j - nx] > k)) {
05578 d[j] = k;
05579 }
05580 }
05581 }
05582 k -= 0.00001f;
05583 }
05584 }
05585 else {
05586 for (int i = 0; i < num_shells; i++) {
05587 for (int z = 1; z < nz - 1; z++) {
05588 size_t cur_z = z * nx * ny;
05589
05590 for (int y = 1; y < ny - 1; y++) {
05591 size_t cur_y = y * nx + cur_z;
05592
05593 for (int x = 1; x < nx - 1; x++) {
05594 size_t j = x + cur_y;
05595
05596 if (!d[j] && (d[j - 1] > k || d[j + 1] > k || d[j + nx] > k ||
05597 d[j - nx] > k || d[j - nxy] > k || d[j + nxy] > k)) {
05598 d[j] = k;
05599 }
05600 }
05601 }
05602 }
05603
05604 k -= 0.00001f;
05605 }
05606 }
05607
05608 size_t size = nx * ny * nz;
05609 for (size_t i = 0; i < size; i++) {
05610 if (d[i]) {
05611 d[i] = 1;
05612 }
05613 else {
05614 d[i] = 0;
05615 }
05616 }
05617
05618 image->update();
05619 }
05620
05621 void ToMassCenterProcessor::process_inplace(EMData * image)
05622 {
05623 if (!image) {
05624 LOGWARN("NULL Image");
05625 return;
05626 }
05627
05628 int int_shift_only = params.set_default("int_shift_only",1);
05629
05630
05631 if ((float)image->get_attr("sigma")==0.0f) return;
05632
05633 FloatPoint com = image->calc_center_of_mass();
05634
05635 int nx = image->get_xsize();
05636 int ny = image->get_ysize();
05637 int nz = image->get_zsize();
05638
05639 if (int_shift_only) {
05640 int dx = -(int)(floor(com[0] + 0.5f) - nx / 2);
05641 int dy = -(int)(floor(com[1] + 0.5f) - ny / 2);
05642 int dz = 0;
05643 if (nz > 1) {
05644 dz = -(int)(floor(com[2] + 0.5f) - nz / 2);
05645 }
05646 image->translate(dx, dy, dz);
05647
05648 Transform t;
05649 t.set_trans((float)dx,(float)dy,(float)dz);
05650
05651 if (nz > 1) {
05652 image->set_attr("xform.align3d",&t);
05653 } else {
05654 image->set_attr("xform.align2d",&t);
05655 }
05656 }
05657 else {
05658 float dx = -(com[0] - nx / 2);
05659 float dy = -(com[1] - ny / 2);
05660 float dz = 0;
05661 if (nz > 1) {
05662 dz = -(com[2] - nz / 2);
05663 }
05664 image->translate(dx, dy, dz);
05665
05666 Transform t;
05667 t.set_trans(dx,dy,dz);
05668
05669 if (nz > 1) {
05670 image->set_attr("xform.align3d",&t);
05671 } else {
05672 image->set_attr("xform.align2d",&t);
05673 }
05674 }
05675 }
05676
05677 void PhaseToMassCenterProcessor::process_inplace(EMData * image)
05678 {
05679 if (!image) {
05680 LOGWARN("NULL Image");
05681 return;
05682 }
05683
05684 int int_shift_only = params.set_default("int_shift_only",1);
05685
05686 vector<float> pcog = image->phase_cog();
05687
05688 int dims = image->get_ndim();
05689
05690 if (int_shift_only) {
05691 int dx=-int(pcog[0]+0.5f),dy=0,dz=0;
05692 if ( dims >= 2 ) dy = -int(pcog[1]+0.5);
05693 if ( dims == 3 ) dz = -int(pcog[2]+0.5);
05694
05695 Transform t;
05696 t.set_trans((float)dx,(float)dy,(float)dz);
05697 if (dims == 3) image->set_attr("xform.align3d",&t);
05698 else if (dims == 2) image->set_attr("xform.align2d",&t);
05699
05700 image->translate(dx,dy,dz);
05701 } else {
05702 float dx=-pcog[0],dy=0.0,dz=0.0;
05703 if ( dims >= 2 ) dy = -pcog[1];
05704 if ( dims == 3 ) dz = -pcog[2];
05705 image->translate(dx,dy,dz);
05706
05707 Transform t;
05708 t.set_trans(dx,dy,dz);
05709 if (dims == 3) image->set_attr("xform.align3d",&t);
05710 else if (dims == 2) image->set_attr("xform.align2d",&t);
05711 }
05712 }
05713
05714 void ACFCenterProcessor::process_inplace(EMData * image)
05715 {
05716 if (!image) {
05717 LOGWARN("NULL Image");
05718 return;
05719 }
05720
05721 Dict params1;
05722 params1["intonly"] = 1;
05723 params1["maxshift"] = image->get_xsize() / 4;
05724 EMData* aligned = image->align("translational", 0, params1);
05725 if ( image->get_ndim() == 3 ) {
05726 Transform* t = aligned->get_attr("xform.align3d");
05727 image->translate(t->get_trans());
05728 image->set_attr("xform.align3d",t);
05729 delete t;
05730 }
05731 else {
05732
05733 Transform* t = aligned->get_attr("xform.align2d");
05734 image->translate(t->get_trans());
05735 image->set_attr("xform.align2d",t);
05736 delete t;
05737 }
05738
05739 delete aligned;
05740
05741 }
05742
05743 void SNRProcessor::process_inplace(EMData * image)
05744 {
05745 if (!image) {
05746 return;
05747 }
05748
05749 int wiener = params["wiener"];
05750 const char *snrfile = params["snrfile"];
05751
05752 XYData sf;
05753 int err = sf.read_file(snrfile);
05754 if (err) {
05755 LOGERR("couldn't read structure factor file!");
05756 return;
05757 }
05758
05759
05760 for (size_t i = 0; i < sf.get_size(); i++) {
05761 if (sf.get_y(i) <= 0) {
05762 sf.set_y(i, -4.0f);
05763 }
05764 else {
05765 sf.set_y(i, log10(sf.get_y(i)));
05766 }
05767 }
05768 sf.update();
05769
05770 Ctf *image_ctf = image->get_ctf();
05771
05772 vector < float >ctf;
05773 if (wiener) {
05774 ctf = image_ctf->compute_1d(image->get_ysize(),1.0f/(image_ctf->apix*image->get_ysize()), Ctf::CTF_WIENER_FILTER, &sf);
05775 }
05776 else {
05777 ctf = image_ctf->compute_1d(image->get_ysize(),1.0f/(image_ctf->apix*image->get_ysize()), Ctf::CTF_SNR, &sf);
05778 }
05779
05780 if(image_ctf) {delete image_ctf; image_ctf=0;}
05781
05782 image->process_inplace("normalize.circlemean");
05783
05784 int nx = image->get_xsize();
05785 int ny = image->get_ysize();
05786
05787 Region clip_r(-nx / 2, -ny / 2, nx * 2, ny * 2);
05788 EMData *d3 = image->get_clip(clip_r);
05789 EMData *d2 = d3->do_fft();
05790
05791 d2->apply_radial_func(0, 2.0f / Ctf::CTFOS, ctf, 0);
05792
05793 if( d3 )
05794 {
05795 delete d3;
05796 d3 = 0;
05797 }
05798
05799 if( image )
05800 {
05801 delete image;
05802 image = 0;
05803 }
05804
05805 EMData *d1 = d2->do_ift();
05806 int d1_nx = d1->get_xsize();
05807 int d1_ny = d1->get_ysize();
05808 Region d1_r(d1_nx / 4, d1_ny / 4, d1_nx / 2, d1_ny / 2);
05809
05810 image = d1->get_clip(d1_r);
05811
05812 if( d1 )
05813 {
05814 delete d1;
05815 d1 = 0;
05816 }
05817
05818 if( d2 )
05819 {
05820 delete d2;
05821 d2 = 0;
05822 }
05823 }
05824
05825 void FileFourierProcessor::process_inplace(EMData * image)
05826 {
05827 if (!image) {
05828 LOGWARN("NULL Image");
05829 return;
05830 }
05831 const char *filename = params["filename"];
05832 float apix = params["apix"];
05833
05834 FILE *in = fopen(filename, "rb");
05835 if (!in) {
05836 LOGERR("FileFourierProcessor: cannot open file '%s'", filename);
05837 return;
05838 }
05839
05840 float f = 0;
05841 int n = 0;
05842 while (fscanf(in, " %f %f", &f, &f) == 2) {
05843 n++;
05844 }
05845 rewind(in);
05846
05847 vector < float >xd(n);
05848 vector < float >yd(n);
05849
05850 float sf = apix * image->get_xsize();
05851
05852 for (int i = 0; fscanf(in, " %f %f", &xd[i], &yd[i]) == 2; i++) {
05853 xd[i] *= sf;
05854 }
05855
05856 if (xd[2] - xd[1] != xd[1] - xd[0]) {
05857 LOGWARN("Warning, x spacing appears nonuniform %g!=%g\n",
05858 xd[2] - xd[1], xd[1] - xd[0]);
05859 }
05860
05861 EMData *d2 = image->do_fft();
05862 if( image )
05863 {
05864 delete image;
05865 image = 0;
05866 }
05867
05868 d2->apply_radial_func(xd[0], xd[1] - xd[0], yd, 1);
05869 image = d2->do_ift();
05870 }
05871
05872 void LocalNormProcessor::process_inplace(EMData * image)
05873 {
05874 if (!image) {
05875 LOGWARN("NULL Image");
05876 return;
05877 }
05878 float apix = params["apix"];
05879 float threshold = params["threshold"];
05880 float radius = params["radius"];
05881
05882 if (apix > 0) {
05883 int ny = image->get_ysize();
05884 radius = ny * apix / radius;
05885
05886 }
05887
05888 EMData *blur = image->copy();
05889 EMData *maskblur = image->copy();
05890
05891 maskblur->process_inplace("threshold.binary", Dict("value", threshold));
05892 maskblur->process_inplace("eman1.filter.lowpass.gaussian", Dict("lowpass", radius));
05893 maskblur->process_inplace("eman1.filter.highpass.tanh", Dict("highpass", -10.0f));
05894 maskblur->process_inplace("threshold.belowtozero", Dict("minval", 0.001f));
05895 maskblur->process_inplace("threshold.belowtozero", Dict("minval", 0.001f));
05896
05897
05898 blur->process_inplace("threshold.belowtozero", Dict("minval", threshold));
05899 blur->process_inplace("eman1.filter.lowpass.gaussian", Dict("lowpass", radius));
05900 blur->process_inplace("eman1.filter.highpass.tanh", Dict("highpass", -10.0f));
05901
05902 maskblur->div(*blur);
05903 image->mult(*maskblur);
05904 maskblur->write_image("norm.mrc", 0, EMUtil::IMAGE_MRC);
05905
05906 if( maskblur )
05907 {
05908 delete maskblur;
05909 maskblur = 0;
05910 }
05911
05912 if( blur )
05913 {
05914 delete blur;
05915 blur = 0;
05916 }
05917 }
05918
05919
05920 void SymSearchProcessor::process_inplace(EMData * image)
05921 {
05922 if (!image) {
05923 LOGWARN("NULL Image");
05924 return;
05925 }
05926 float thresh = params["thresh"];
05927 int output_symlabel = params["output_symlabel"];
05928
05929
05930 const vector<string> sym_list = params["sym"];
05931 int sym_num = sym_list.size();
05932 vector< vector< Transform > > transforms(sym_num);
05933 vector< float* > symvals(sym_num);
05934 for (int i =0; i < sym_num; i++) {
05935 vector<Transform> sym_transform = Symmetry3D::get_symmetries(sym_list[i]);
05936 transforms[i] = sym_transform;
05937 symvals[i] = new float[sym_transform.size()];
05938 }
05939
05940 EMData *orig = image->copy();
05941
05942 image->to_zero();
05943
05944 int nx= image->get_xsize();
05945 int ny= image->get_ysize();
05946 int nz= image->get_zsize();
05947 int xy = nx * ny;
05948 float * data = image->get_data();
05949 float * sdata = orig->get_data();
05950
05951 EMData *symlabel = 0;
05952 float * ldata = symlabel->get_data();
05953 if (output_symlabel) {
05954 symlabel = image->copy();
05955 symlabel->to_zero();
05956 ldata = symlabel->get_data();
05957 }
05958
05959 for (int k = 0; k < nz; k++) {
05960 for (int j = 0; j < ny; j++) {
05961 for(int i = 0; i < nx; i++) {
05962 size_t index = k * nx * ny + j * nx + i;
05963 float val = sdata[ index ];
05964 float bestmean = val, bestsymlevel = FLT_MAX;
05965 int bestsym = 0;
05966 for( int sym = 0; sym< sym_num; sym++) {
05967 int cur_sym_num = transforms[sym].size();
05968 float *symval = symvals[sym];
05969
05970 for( int s = 0; s < cur_sym_num; s++){
05971 Transform r = transforms[sym][s];
05972 float x2 = (float)(r[0][0] * (i-nx/2) + r[0][1] * (j-ny/2) + r[0][2] * (k-nz/2) + nx / 2);
05973 float y2 = (float)(r[1][0] * (i-nx/2) + r[1][1] * (j-ny/2) + r[1][2] * (k-nz/2) + ny / 2);
05974 float z2 = (float)(r[2][0] * (i-nx/2) + r[2][1] * (j-ny/2) + r[2][2] * (k-nz/2) + nz / 2);
05975
05976 if (x2 >= 0 && y2 >= 0 && z2 >= 0 && x2 < (nx - 1) && y2 < (ny - 1)
05977 && z2 < (nz - 1)) {
05978 float x = (float)Util::fast_floor(x2);
05979 float y = (float)Util::fast_floor(y2);
05980 float z = (float)Util::fast_floor(z2);
05981
05982 float t = x2 - x;
05983 float u = y2 - y;
05984 float v = z2 - z;
05985
05986 int ii = (int) (x + y * nx + z * xy);
05987
05988 symval[s]=
05989 Util::trilinear_interpolate(sdata[ii], sdata[ii + 1], sdata[ii + nx],
05990 sdata[ii + nx + 1], sdata[ii + nx * ny],
05991 sdata[ii + xy + 1], sdata[ii + xy + nx],
05992 sdata[ii + xy + nx + 1], t, u, v);
05993 }
05994 else {
05995 symval[s] = 0.0 ;
05996 }
05997 }
05998 float tmean=0, tsigma=0;
05999 for( int s = 0; s < cur_sym_num; s++) {
06000 tmean += symval[s];
06001 tsigma += symval[s] * symval[s];
06002 }
06003 tmean /= cur_sym_num;
06004 tsigma = tsigma/cur_sym_num - tmean*tmean;
06005 if (tsigma < bestsymlevel ) {
06006 bestsymlevel = tsigma;
06007 bestmean = tmean;
06008 bestsym = sym;
06009 }
06010 }
06011 if ( bestsymlevel > thresh) {
06012 if (output_symlabel) ldata[index] = (float)bestsym;
06013 data[index] = bestmean;
06014 }
06015 else {
06016 if (output_symlabel) ldata[index] = -1;
06017 data[index] = val;
06018 }
06019 }
06020 }
06021 }
06022 if( orig )
06023 {
06024 delete orig;
06025 orig = 0;
06026 }
06027 for (int i =0; i < sym_num; i++) {
06028 if( symvals[i] )
06029 {
06030 delete symvals[i];
06031 symvals[i] = 0;
06032 }
06033 }
06034 if (symlabel) params.put("symlabel_map", EMObject(symlabel));
06035 }
06036
06037
06038 void IndexMaskFileProcessor::process_inplace(EMData * image)
06039 {
06040 if (!image) {
06041 LOGWARN("NULL Image");
06042 return;
06043 }
06044
06045 const char *filename = params["filename"];
06046 EMData *msk = new EMData();
06047 msk->read_image(filename);
06048 if (!EMUtil::is_same_size(image, msk)) {
06049 LOGERR("IndexMaskFileProcessor: Mask size different than image");
06050 return;
06051 }
06052
06053 if ((int) params["ismaskset"] != 0) {
06054 msk->process_inplace("threshold.binaryrange", Dict("low", 0.5f, "high", 1.5f));
06055 }
06056
06057 image->mult(*msk);
06058 if( msk )
06059 {
06060 delete msk;
06061 msk = 0;
06062 }
06063 }
06064
06065
06066 void CoordinateMaskFileProcessor::process_inplace(EMData * image)
06067 {
06068 if (!image) {
06069 LOGWARN("NULL Image");
06070 return;
06071 }
06072
06073 const char *filename = params["filename"];
06074 EMData *msk = new EMData();
06075 msk->read_image(filename);
06076
06077 int nx = image->get_xsize();
06078 int ny = image->get_ysize();
06079 int nz = image->get_zsize();
06080
06081 int xm = msk->get_xsize();
06082 int ym = msk->get_ysize();
06083 int zm = msk->get_zsize();
06084
06085 float apix = image->get_attr("apix_x");
06086 float apixm = msk->get_attr("apix_x");
06087
06088 float xo = image->get_attr("origin_x");
06089 float yo = image->get_attr("origin_y");
06090 float zo = image->get_attr("origin_z");
06091
06092 float xom = msk->get_attr("origin_x");
06093 float yom = msk->get_attr("origin_y");
06094 float zom = msk->get_attr("origin_z");
06095
06096 float *dp = image->get_data();
06097 float *dpm = msk->get_data();
06098 int nxy = nx * ny;
06099
06100 for (int k = 0; k < nz; k++) {
06101 float zc = zo + k * apix;
06102 if (zc <= zom || zc >= zom + zm * apixm) {
06103 memset(&(dp[k * nxy]), 0, sizeof(float) * nxy);
06104 }
06105 else {
06106 int km = (int) ((zc - zom) / apixm);
06107
06108 for (int j = 0; j < ny; j++) {
06109 float yc = yo + j * apix;
06110 if (yc <= yom || yc >= yom + ym * apixm) {
06111 memset(&(dp[k * nxy + j * nx]), 0, sizeof(float) * nx);
06112 }
06113 else {
06114 int jm = (int) ((yc - yom) / apixm);
06115 size_t idx = 0;
06116 float xc;
06117 int im;
06118 for (int i = 0; i < nx; i++) {
06119 xc = xo + i * apix;
06120 idx = k * nxy + j * nx + i;
06121 if (xc <= xom || xc >= xom + xm * apixm) {
06122 dp[idx] = 0;
06123 }
06124 else {
06125 im = (int) ((xc - xom) / apixm);
06126 if (dpm[km * xm * ym + jm * xm + im] <= 0) {
06127 dp[idx] = 0;
06128 }
06129 }
06130 }
06131 }
06132 }
06133 }
06134 }
06135
06136 image->update();
06137 msk->update();
06138 if( msk )
06139 {
06140 delete msk;
06141 msk = 0;
06142 }
06143 }
06144
06145 void MatchSFProcessor::create_radial_func(vector < float >&radial_mask,EMData *image) const {
06146
06147
06148
06149 EMData *to = params["to"];
06150 XYData *sf = new XYData();
06151 float apixto = to->get_attr("apix_x");
06152
06153
06154 if (to->is_complex()) {
06155 vector<float> rd=to->calc_radial_dist(to->get_ysize()/2.0,0,1.0f,1);
06156 for (size_t i=0; i<rd.size(); i++) {
06157 sf->set_x(i,i/(apixto*2.0f*rd.size()));
06158 sf->set_y(i,rd[i]);
06159 }
06160 }
06161 else {
06162 EMData *tmp=to->do_fft();
06163 vector<float> rd=tmp->calc_radial_dist(to->get_ysize()/2,0,1.0,1);
06164 for (size_t i=0; i<rd.size(); i++) {
06165 sf->set_x(i,i/(apixto*2.0f*rd.size()));
06166 sf->set_y(i,rd[i]);
06167 }
06168 delete tmp;
06169 }
06170
06171 float apix=image->get_attr("apix_x");
06172
06173 sf->write_file("a.txt");
06174 Util::save_data(0,sf->get_x(1),radial_mask,"b.txt");
06175
06176 int n = radial_mask.size();
06177 for (int i=0; i<n; i++) {
06178 if (radial_mask[i]>0) radial_mask[i]= sqrt(sf->get_yatx(i/(apix*2.0f*n),false)/radial_mask[i]);
06179 else if (i>0) radial_mask[i]=radial_mask[i-1];
06180 }
06181
06182 Util::save_data(0,sf->get_x(1),radial_mask,"c.txt");
06183
06184 delete sf;
06185 }
06186
06187 void SetSFProcessor::create_radial_func(vector < float >&radial_mask,EMData *image) const {
06188
06189
06190
06191 XYData *sf = params["strucfac"];
06192 if(params.has_key("apix")) {
06193 image->set_attr("apix_x", (float)params["apix"]);
06194 image->set_attr("apix_y", (float)params["apix"]);
06195 image->set_attr("apix_z", (float)params["apix"]);
06196 }
06197
06198 float apix=image->get_attr("apix_x");
06199
06200 int n = radial_mask.size();
06201 for (int i=0; i<n; i++) {
06202 if (radial_mask[i]>0) radial_mask[i]= n*n*n*sqrt(sf->get_yatx(i/(apix*2.0f*n),false)/radial_mask[i]);
06203 else if (i>0) radial_mask[i]=radial_mask[i-1];
06204 }
06205
06206 }
06207
06208 void SmartMaskProcessor::process_inplace(EMData * image)
06209 {
06210 if (!image) {
06211 LOGWARN("NULL Image");
06212 return;
06213 }
06214
06215 float mask = params["mask"];
06216
06217 int nx = image->get_xsize();
06218 int ny = image->get_ysize();
06219 int nz = image->get_zsize();
06220
06221 float *dat = image->get_data();
06222 double sma = 0;
06223 int smn = 0;
06224 float r = 0.0f;
06225 for (int k = 0; k < nz; ++k) {
06226 for (int j = 0; j < ny; ++j) {
06227 for (int i = 0; i < nx; ++i, ++dat) {
06228 r =
06229 sqrt((float) Util::square(i - nx / 2) + Util::square(j - ny / 2) +
06230 Util::square(k - nz / 2));
06231 if (r > mask - 1.5f && r < mask - 0.5f) {
06232 sma += *dat;
06233 smn++;
06234 }
06235 }
06236 }
06237 }
06238
06239 float smask = (float) sma / smn;
06240 image->update();
06241
06242 dat = image->get_data();
06243 for (int k = 0; k < nz; ++k) {
06244 for (int j = 0; j < ny; ++j) {
06245 for (int i = 0; i < nx; ++i, ++dat) {
06246 r =
06247 sqrt((float) Util::square(i - nx / 2) + Util::square(j - ny / 2) +
06248 Util::square(k - nz / 2));
06249 if (r > mask - .5) {
06250 *dat = 0;
06251 }
06252 else {
06253 *dat -= smask;
06254 }
06255 }
06256 }
06257 }
06258
06259 image->update();
06260 }
06261
06262 void AutoMask3DProcessor::search_nearby(float *dat, float *dat2, int nx, int ny, int nz, float threshold)
06263 {
06264 Assert(dat != 0);
06265 Assert(dat2 != 0);
06266 Assert(nx > 0);
06267 Assert(ny > 0);
06268
06269 bool done = false;
06270 int nxy = nx * ny;
06271
06272 while (!done) {
06273 done = true;
06274 for (int k = 1; k < nz - 1; k++) {
06275 size_t k2 = k * nxy;
06276 for (int j = 1; j < ny - 1; j++) {
06277 size_t l = j * nx + k2 + 1;
06278
06279 for (int i = 1; i < nx - 1; i++) {
06280 if (dat[l] >= threshold || dat2[l]) {
06281 if (dat2[l - 1] || dat2[l + 1] ||
06282 dat2[l - nx] || dat2[l + nx] || dat2[l - nxy] || dat2[l + nxy]) {
06283 dat2[l] = 1.0f;
06284 done = false;
06285 }
06286 }
06287 ++l;
06288 }
06289 }
06290 }
06291 }
06292 }
06293
06294 void AutoMask3DProcessor::fill_nearby(float *dat2, int nx, int ny, int nz)
06295 {
06296 Assert(dat2 != 0);
06297 Assert(nx > 0);
06298 Assert(ny > 0);
06299 Assert(nz >= 0);
06300
06301 int nxy = nx * ny;
06302 size_t idx;
06303 for (int i = 0; i < nx; i++) {
06304 for (int j = 0; j < ny; j++) {
06305 int j2 = j * nx + i;
06306 int k0 = 0;
06307 for (int k = 0; k < nz; k++) {
06308 idx = j2 + k * nxy;
06309 if (dat2[idx]) {
06310 k0 = k;
06311 break;
06312 }
06313 }
06314
06315 if (k0 != nz) {
06316 int k1 = nz - 1;
06317 for (int k = nz - 1; k >= 0; k--) {
06318 idx = j2 + k * nxy;
06319 if (dat2[idx]) {
06320 k1 = k;
06321 break;
06322 }
06323 }
06324
06325 for (int k = k0 + 1; k < k1; k++) {
06326 idx = j2 + k * nxy;
06327 dat2[idx] = 1.0f;
06328 }
06329 }
06330 }
06331 }
06332
06333 for (int i = 0; i < nx; i++) {
06334 for (int j = 0; j < nz; j++) {
06335 size_t j2 = j * nxy + i;
06336 int k0 = 0;
06337 for (int k = 0; k < ny; k++) {
06338 idx = k * nx + j2;
06339 if (dat2[idx]) {
06340 k0 = k;
06341 break;
06342 }
06343 }
06344
06345 if (k0 != ny) {
06346 int k1 = ny - 1;
06347 for (int k = ny - 1; k >= 0; k--) {
06348 idx = k * nx + j2;
06349 if (dat2[idx]) {
06350 k1 = k;
06351 break;
06352 }
06353 }
06354
06355 for (int k = k0 + 1; k < k1; k++) {
06356 idx = k * nx + j2;
06357 dat2[idx] = 1.0f;
06358 }
06359 }
06360 }
06361 }
06362
06363 for (int i = 0; i < ny; i++) {
06364 for (int j = 0; j < nz; j++) {
06365 size_t j2 = i * nx + j * nxy;
06366 int k0 = 0;
06367 for (int k = 0; k < nx; k++) {
06368 if (dat2[k + j2]) {
06369 k0 = k;
06370 break;
06371 }
06372 }
06373 if (k0 != nx) {
06374 int k1 = nx - 1;
06375 for (int k = nx - 1; k >= 0; k--) {
06376 if (dat2[k + j2]) {
06377 k1 = k;
06378 break;
06379 }
06380 }
06381
06382 for (int k = k0 + 1; k < k1; k++) {
06383 dat2[k + j2] = 1.0f;
06384 }
06385 }
06386 }
06387 }
06388
06389 }
06390
06391 void AutoMask3DProcessor::process_inplace(EMData * image)
06392 {
06393 if (!image) {
06394 LOGWARN("NULL Image");
06395 return;
06396 }
06397
06398 int nx = image->get_xsize();
06399 int ny = image->get_ysize();
06400 int nz = image->get_zsize();
06401
06402 EMData *amask = new EMData();
06403 amask->set_size(nx, ny, nz);
06404
06405 float sig = 0;
06406 float mean = 0;
06407
06408 if (params.has_key("threshold1") && params.has_key("threshold2")) {
06409 sig = image->get_attr("sigma");
06410 mean = image->get_attr("mean");
06411 }
06412
06413 float *dat = image->get_data();
06414 float *dat2 = amask->get_data();
06415
06416 float t = 0;
06417 if (params.has_key("threshold1")) {
06418 t = params["threshold1"];
06419 }
06420 else {
06421 t = mean + sig * 2.5f;
06422 }
06423
06424 size_t l = 0;
06425 for (int k = 0; k < nz; ++k) {
06426 for (int j = 0; j < ny; ++j) {
06427 for (int i = 0; i < nx; ++i) {
06428 if (dat[l] > t) {
06429 dat2[l] = 1.0f;
06430 }
06431 ++l;
06432 }
06433 }
06434 }
06435
06436
06437 if (params.has_key("threshold2")) {
06438 t = params["threshold2"];
06439 }
06440 else {
06441 t = mean + sig * 0.5f;
06442 }
06443
06444 search_nearby(dat, dat2, nx, ny, nz, t);
06445
06446 int nxy = nx * ny;
06447
06448 for (int k = 1; k < nz - 1; ++k) {
06449 for (int j = 1; j < ny - 1; ++j) {
06450 size_t l = j * nx + k * nxy + 1;
06451 for (int i = 1; i < nx - 1; ++i, ++l) {
06452 if (dat2[l - 1] == 1.0f || dat2[l + 1] == 1.0f ||
06453 dat2[l - nx] == 1.0f || dat2[l + nx] == 1.0f ||
06454 dat2[l - nxy] == 1.0f || dat2[l + nxy] == 1.0f) {
06455 dat2[l] = 2.0f;
06456 }
06457 }
06458 }
06459 }
06460
06461 size_t size = nx * ny * nz;
06462 for (size_t i = 0; i < size; i++) {
06463 if (dat2[i] == 2.0f) {
06464 dat2[i] = 1.0f;
06465 }
06466 }
06467
06468 fill_nearby(dat2, nx, ny, nz);
06469
06470 image->update();
06471 amask->update();
06472
06473 image->mult(*amask);
06474 amask->write_image("mask.mrc", 0, EMUtil::IMAGE_MRC);
06475 if( amask )
06476 {
06477 delete amask;
06478 amask = 0;
06479 }
06480 }
06481
06482
06483 void AutoMask3D2Processor::process_inplace(EMData * image)
06484 {
06485 if (!image) {
06486 LOGWARN("NULL Image");
06487 return;
06488 }
06489
06490 if (image->get_ndim() != 3) {
06491 throw ImageDimensionException("This processor was only ever designed to work on 3D images.");
06492 }
06493
06494
06495
06496
06497
06498
06499
06500
06501
06502
06503
06504 int radius=0;
06505 if (params.has_key("radius")) {
06506 radius = params["radius"];
06507 }
06508 int nmaxseed=0;
06509 if (params.has_key("nmaxseed")) {
06510 nmaxseed = params["nmaxseed"];
06511 }
06512
06513 float threshold=0.0;
06514 if (params.has_key("sigma")) threshold=(float)(image->get_attr("mean"))+(float)(image->get_attr("sigma"))*(float)params["sigma"];
06515 else threshold=params["threshold"];
06516
06517 int nshells = params["nshells"];
06518 int nshellsgauss = params["nshellsgauss"];
06519 int verbose=params.set_default("verbose",0);
06520
06521 int nx = image->get_xsize();
06522 int ny = image->get_ysize();
06523 int nz = image->get_zsize();
06524 int nxy=nx*ny;
06525
06526 EMData *amask = new EMData();
06527 amask->set_size(nx, ny, nz);
06528
06529 float *dat = image->get_data();
06530 float *dat2 = amask->get_data();
06531 int i,j,k;
06532 size_t l = 0;
06533
06534
06535 if (nmaxseed>0) {
06536 vector<Pixel> maxs=image->calc_n_highest_locations(nmaxseed);
06537
06538 for (vector<Pixel>::iterator i=maxs.begin(); i<maxs.end(); i++) {
06539 amask->set_value_at((*i).x,(*i).y,(*i).z,1.0);
06540 if (verbose) printf("Seed at %d,%d,%d (%1.3f)\n",(*i).x,(*i).y,(*i).z,(*i).value);
06541 }
06542 }
06543
06544
06545 if (radius>0) {
06546
06547 for (k = -nz / 2; k < nz / 2; ++k) {
06548 for (j = -ny / 2; j < ny / 2; ++j) {
06549 for (i = -nx / 2; i < nx / 2; ++i,++l) {
06550 if (abs(k) > radius || abs(j) > radius || abs(i) > radius) continue;
06551 if ( (k * k + j * j + i * i) > (radius*radius) || dat[l] < threshold) continue;
06552 dat2[l] = 1.0f;
06553 }
06554 }
06555 }
06556 }
06557
06558
06559
06560 int done=0;
06561 int iter=0;
06562 while (!done) {
06563 iter++;
06564 done=1;
06565 if (verbose && iter%10==0) printf("%d iterations\n",iter);
06566 for (k=1; k<nz-1; ++k) {
06567 for (j=1; j<ny-1; ++j) {
06568 for (i=1; i<nx-1; ++i) {
06569 l=i+j*nx+k*nx*ny;
06570 if (dat2[l]) continue;
06571 if (dat[l]>threshold && (dat2[l-1]||dat2[l+1]||dat2[l+nx]||dat2[l-nx]||dat2[l-nxy]||dat2[l+nxy])) {
06572 dat2[l]=1.0;
06573 done=0;
06574 }
06575 }
06576 }
06577 }
06578 }
06579
06580 amask->update();
06581
06582 if (verbose) printf("extending mask\n");
06583 amask->process_inplace("mask.addshells.gauss", Dict("val1", nshells, "val2", nshellsgauss));
06584
06585 bool return_mask = params.set_default("return_mask",false);
06586 if (return_mask) {
06587
06588 memcpy(dat,dat2,image->get_size()*sizeof(float));
06589 } else {
06590 image->mult(*amask);
06591 }
06592
06593
06594
06595
06596
06597
06598
06599 delete amask;
06600 }
06601
06602 void IterBinMaskProcessor::process_inplace(EMData * image)
06603 {
06604 if (!image) {
06605 LOGWARN("NULL Image");
06606 return;
06607 }
06608
06609 float val1 = params["val1"];
06610 float val2 = params["val2"];
06611
06612 int nx = image->get_xsize();
06613 int ny = image->get_ysize();
06614 int nz = image->get_zsize();
06615 EMData *image2 = new EMData(nx,ny,nz);
06616
06617
06618
06619
06620
06621
06622 float *d = image->get_data();
06623 float *d2 = image2->get_data();
06624
06625 const int nxy = nx * ny;
06626 size_t size = nx * ny * nz;
06627
06628
06629 if (nz != 1) {
06630 for (int l = 1; l <= (int) val1+val2; ++l) {
06631 for (size_t i=0; i<size; i++) d2[i]=d[i];
06632 for (int k = 1; k < nz - 1; ++k) {
06633 for (int j = 1; j < ny - 1; ++j) {
06634 for (int i = 1; i < nx - 1; ++i) {
06635 size_t t = i + j*nx+k*nx*ny;
06636 if (d[t]) continue;
06637 if (d2[t - 1] || d2[t + 1] || d2[t + nx] || d2[t - nx] || d2[t + nxy] || d2[t - nxy]) d[t] = (float) l + 1;
06638 }
06639 }
06640 }
06641 }
06642 }
06643 else {
06644 for (int l = 1; l <= (int) val1+val2; ++l) {
06645 for (size_t i=0; i<size; i++) d2[i]=d[i];
06646 for (int j = 1; j < ny - 1; ++j) {
06647 for (int i = 1; i < nx - 1; ++i) {
06648 size_t t = i + j * nx;
06649 if (d[t]) continue;
06650 if (d2[t - 1] || d2[t + 1] || d2[t + nx] || d2[t - nx]) d[t] = (float) l + 1;
06651 }
06652 }
06653 }
06654 }
06655
06656 vector<float> vec;
06657 for (int i=0; i<val1+2; i++) vec.push_back(1.0);
06658 for (int i=0; i<val2; i++) {
06659 vec.push_back(exp(-pow(2.0f*i/(val2),2.0f)));
06660
06661 }
06662 for (size_t i = 0; i < size; i++) if (d[i]) d[i]=vec[(int)d[i]];
06663
06664 image->update();
06665 delete image2;
06666 }
06667
06668 EMData* DirectionalSumProcessor::process(const EMData* const image ) {
06669 string dir = params.set_default("direction", "");
06670 if ( dir == "" || ( dir != "x" && dir != "y" && dir != "z" ) )
06671 throw InvalidParameterException("The direction parameter must be either x, y, or z");
06672
06673 int nx = image->get_xsize();
06674 int ny = image->get_ysize();
06675 int nz = image->get_zsize();
06676
06677
06678 if ( dir == "x" ) nx = 1;
06679 else if ( dir == "y" ) ny = 1;
06680 else if ( dir == "z" ) nz = 1;
06681
06682 EMData* ret = new EMData;
06683 ret->set_size(nx,ny,nz);
06684 ret->to_zero();
06685
06686 float* d = image->get_data();
06687 for(int k = 0; k < image->get_zsize(); ++k ) {
06688 for(int j = 0; j < image->get_ysize(); ++j ) {
06689 for(int i = 0; i < image->get_xsize(); ++i, ++d ) {
06690 if ( dir == "x" ) {
06691 float v = ret->get_value_at(0,j,k);
06692 ret->set_value_at(0,j,k,*d+v);
06693 }else if ( dir == "y" ) {
06694 float v = ret->get_value_at(i,0,k);
06695 ret->set_value_at(i,0,k,*d+v);
06696 }
06697 else if ( dir == "z" ) {
06698 float v = ret->get_value_at(i,j,0);
06699 ret->set_value_at(i,j,0,*d+v);
06700 }
06701 }
06702 }
06703 }
06704 ret->update();
06705 return ret;
06706 }
06707
06708 void TestImageProcessor::preprocess(EMData * image)
06709 {
06710 if (!image) {
06711 LOGWARN("NULL Image");
06712 return;
06713 }
06714
06715 nx = image->get_xsize();
06716 ny = image->get_ysize();
06717 nz = image->get_zsize();
06718 }
06719
06720
06721 void TestImageFourierNoiseGaussian::process_inplace(EMData* image)
06722 {
06723 if (!image->is_complex()) {
06724 int nx = image->get_xsize();
06725 int offset = 2 - nx%2;
06726
06727 image->set_size(nx+offset,image->get_ysize(),image->get_zsize());
06728 image->set_complex(true);
06729 if (1 == offset) image->set_fftodd(true);
06730 else image->set_fftodd(false);
06731 image->set_fftpad(true);
06732 }
06733 image->ri2ap();
06734
06735 float sigma = params.set_default("sigma",.25f);
06736
06737 float * d = image->get_data();
06738 int nx = image->get_xsize();
06739 int ny = image->get_ysize();
06740 int nxy = image->get_ysize()*nx;
06741 int nzon2 = image->get_zsize()/2;
06742 int nyon2 = image->get_ysize()/2;
06743 float rx, ry, rz, length, amp, phase;
06744 int twox;
06745 for (int z = 0; z< image->get_zsize(); ++z) {
06746 for (int y = 0; y < image->get_ysize(); ++y) {
06747 for (int x = 0; x < image->get_xsize()/2; ++x) {
06748 rx = (float)x;
06749 ry = (float)nyon2 - (float)y;
06750 rz = (float)nzon2 - (float)z;
06751 length = sqrt(rx*rx + ry*ry + rz*rz);
06752 amp = exp(-sigma*length);
06753 phase = Util::get_frand(0,1)*2*M_PI;
06754
06755 twox = 2*x;
06756 size_t idx1 = twox + y*nx+z*nxy;
06757 size_t idx2 = idx1 + 1;
06758 d[idx1] = amp;
06759 d[idx2] = phase;
06760
06761 }
06762 }
06763 }
06764
06765 image->ap2ri();
06766 if (image->get_ndim() == 2) {
06767 bool yodd = image->get_ysize() % 2 == 1;
06768
06769 int yit = image->get_ysize()/2-1;
06770 int offset = 1;
06771 if (yodd) {
06772 offset = 0;
06773 }
06774 for (int y = 0; y < yit; ++y) {
06775 int bot_idx = (y+offset)*nx;
06776 int top_idx = (ny-1-y)*nx;
06777 float r1 = d[bot_idx];
06778 float i1 = d[bot_idx+1];
06779 float r2 = d[top_idx];
06780 float i2 = d[top_idx+1];
06781 float r = (r1 + r2)/2.0f;
06782 float i = (i1 + i2)/2.0f;
06783 d[bot_idx] = r;
06784 d[top_idx] = r;
06785 d[bot_idx+1] = i;
06786 d[top_idx+1] = -i;
06787
06788 bot_idx = (y+offset)*nx+nx-2;
06789 top_idx = (ny-1-y)*nx+nx-2;
06790 r1 = d[bot_idx];
06791 i1 = d[bot_idx+1];
06792 r2 = d[top_idx];
06793 i2 = d[top_idx+1];
06794 r = (r1 + r2)/2.0f;
06795 i = (i1 + i2)/2.0f;
06796 d[bot_idx] = r;
06797 d[top_idx] = r;
06798 d[bot_idx+1] = i;
06799 d[top_idx+1] = -i;
06800 }
06801
06802 d[1] = 0;
06803 d[nx-1] = 0;
06804 d[ny/2*nx+nx-1] = 0;
06805 d[ny/2*nx+1] = 0;
06806 }
06807
06808 if (image->get_ndim() != 1) image->process_inplace("xform.fourierorigin.tocorner");
06809 image->do_ift_inplace();
06810 image->depad();
06811 }
06812
06813 #include <iostream>
06814 using std::ostream_iterator;
06815
06816 void CTFSNRWeightProcessor::process_inplace(EMData* image) {
06817 if (params.has_key("noise")==false) throw InvalidParameterException("You must supply the noise argument");
06818 if (params.has_key("snr")==false) throw InvalidParameterException("You must supply the snr argument");
06819
06820 float boost = params.set_default("boost",1.0f);
06821
06822 if (!image->is_complex()) {
06823 image->do_fft_inplace();
06824 }
06825 EMData* cpy = image->copy();
06826 cpy->ri2inten();
06827 vector<float> sf = cpy->calc_radial_dist(cpy->get_ysize()/2,0.0,1.0,1);
06828 transform(sf.begin(),sf.end(),sf.begin(),sqrtf);
06829 delete cpy;
06830
06831 image->ri2ap();
06832
06833 vector<float> noise = params["noise"];
06834 vector<float> snr = params["snr"];
06835
06836
06837
06838
06839 for(vector<float>::iterator it = noise.begin(); it != noise.end(); ++it){
06840 if ((*it) == 0) *it = 1;
06841 }
06842 for(vector<float>::iterator it = snr.begin(); it != snr.end(); ++it){
06843 if ((*it) < 0) *it = 0;
06844 }
06845
06846 transform(snr.begin(),snr.end(),noise.begin(),snr.begin(),std::multiplies<float>());
06847 transform(snr.begin(),snr.end(),snr.begin(),sqrtf);
06848
06849
06850
06851 int i = static_cast<int>(snr.size());
06852
06853 float * d = image->get_data();
06854 int nx = image->get_xsize();
06855
06856 int nxy = image->get_ysize()*nx;
06857 int nzon2 = image->get_zsize()/2;
06858 int nyon2 = image->get_ysize()/2;
06859 float rx, ry, rz, amp;
06860 int length;
06861 int twox;
06862 image->process_inplace("xform.fourierorigin.tocenter");
06863 for (int z = 0; z< image->get_zsize(); ++z) {
06864 for (int y = 0; y < image->get_ysize(); ++y) {
06865 for (int x = 0; x < image->get_xsize()/2; ++x) {
06866 rx = (float)x;
06867 ry = (float)nyon2 - (float)y;
06868 rz = (float)nzon2 - (float)z;
06869 length = static_cast<int>(sqrt(rx*rx + ry*ry + rz*rz));
06870
06871 twox = 2*x;
06872 size_t idx1 = twox + y*nx+z*nxy;
06873 if (length >= i || length >= (int)sf.size()) {
06874 d[idx1] = 0;
06875 continue;
06876 } else {
06877 amp = boost*snr[length];
06878
06879
06880 }
06881
06882 if (sf[length] == 0) {
06883 d[idx1] = 0;
06884 continue;
06885 }
06886
06887
06888
06889 d[idx1] /= sf[length];
06890 if (d[idx1] < 0) {
06891 d[idx1] *= amp;
06892 }else {
06893 d[idx1] *= -amp;
06894 }
06895
06896
06897 }
06898 }
06899 }
06900
06901 image->ap2ri();
06902 if (image->get_ndim() != 1) image->process_inplace("xform.fourierorigin.tocorner");
06903 image->do_ift_inplace();
06904 image->depad();
06905 }
06906
06907 void TestImageFourierNoiseProfile::process_inplace(EMData * image) {
06908
06909 if (params.has_key("profile")==false) throw InvalidParameterException("You must supply the profile argument");
06910
06911 if (!image->is_complex()) {
06912 int nx = image->get_xsize();
06913 int offset = 2 - nx%2;
06914
06915 image->set_size(nx+offset,image->get_ysize(),image->get_zsize());
06916 image->set_complex(true);
06917 if (1 == offset) image->set_fftodd(true);
06918 else image->set_fftodd(false);
06919 image->set_fftpad(true);
06920 }
06921 image->to_zero();
06922 image->ri2ap();
06923
06924 vector<float> profile = params["profile"];
06925 transform(profile.begin(),profile.end(),profile.begin(),sqrtf);
06926
06927 int i = static_cast<int>(profile.size());
06928
06929 float * d = image->get_data();
06930 int nx = image->get_xsize();
06931 int ny = image->get_ysize();
06932 int nxy = image->get_ysize()*nx;
06933 int nzon2 = image->get_zsize()/2;
06934 int nyon2 = image->get_ysize()/2;
06935 float rx, ry, rz, amp, phase;
06936 int length;
06937 int twox;
06938 for (int z = 0; z< image->get_zsize(); ++z) {
06939 for (int y = 0; y < image->get_ysize(); ++y) {
06940 for (int x = 0; x < image->get_xsize()/2; ++x) {
06941 rx = (float)x;
06942 ry = (float)nyon2 - (float)y;
06943 rz = (float)nzon2 - (float)z;
06944 length = static_cast<int>(sqrt(rx*rx + ry*ry + rz*rz));
06945
06946 twox = 2*x;
06947 size_t idx1 = twox + y*nx+z*nxy;
06948 size_t idx2 = idx1 + 1;
06949
06950
06951 if (length >= i) {
06952 d[idx1] = 0;
06953 d[idx2] = 0;
06954 continue;
06955 }
06956 amp = profile[length];
06957 phase = Util::get_frand(0,1)*2*M_PI;
06958
06959
06960 d[idx1] = amp;
06961 d[idx2] = phase;
06962
06963 }
06964 }
06965 }
06966
06967 image->ap2ri();
06968 if (image->get_ndim() == 2) {
06969 bool yodd = image->get_ysize() % 2 == 1;
06970
06971 int yit = image->get_ysize()/2-1;
06972 int offset = 1;
06973 if (yodd) {
06974 offset = 0;
06975 }
06976 for (int y = 0; y < yit; ++y) {
06977 int bot_idx = (y+offset)*nx;
06978 int top_idx = (ny-1-y)*nx;
06979 float r1 = d[bot_idx];
06980 float i1 = d[bot_idx+1];
06981 float r2 = d[top_idx];
06982 float i2 = d[top_idx+1];
06983 float r = (r1 + r2)/2.0f;
06984 float i = (i1 + i2)/2.0f;
06985 d[bot_idx] = r;
06986 d[top_idx] = r;
06987 d[bot_idx+1] = i;
06988 d[top_idx+1] = -i;
06989
06990 bot_idx = (y+offset)*nx+nx-2;
06991 top_idx = (ny-1-y)*nx+nx-2;
06992 r1 = d[bot_idx];
06993 i1 = d[bot_idx+1];
06994 r2 = d[top_idx];
06995 i2 = d[top_idx+1];
06996 r = (r1 + r2)/2.0f;
06997 i = (i1 + i2)/2.0f;
06998 d[bot_idx] = r;
06999 d[top_idx] = r;
07000 d[bot_idx+1] = i;
07001 d[top_idx+1] = -i;
07002 }
07003
07004 d[1] = 0;
07005 d[nx-1] = 0;
07006 d[ny/2*nx+nx-1] = 0;
07007 d[ny/2*nx+1] = 0;
07008 }
07009
07010 if (image->get_ndim() != 1) image->process_inplace("xform.fourierorigin.tocorner");
07011 image->do_ift_inplace();
07012 image->depad();
07013 }
07014
07015 void TestImageLineWave::process_inplace(EMData * image)
07016 {
07017 preprocess(image);
07018
07019 float period = params.set_default("period",10.0f);
07020 int n = image->get_xsize()*image->get_ysize()*image->get_zsize();
07021
07022 for(int i = 0; i < n; ++i) {
07023 float x = fmod((float)i,period);
07024 x /= period;
07025 x = (float)sin(x*EMConsts::pi*2.0);
07026 image->set_value_at_fast(i,x);
07027 }
07028 }
07029
07030 void TestImageGaussian::process_inplace(EMData * image)
07031 {
07032 preprocess(image);
07033
07034 float sigma = params["sigma"];
07035 string axis = (const char*)params["axis"];
07036 float c = params["c"];
07037
07038 float *dat = image->get_data();
07039 float r;
07040 float x2, y2, z2;
07041 for (int k = 0; k < nz; ++k) {
07042 for (int j = 0; j < ny; ++j) {
07043 for (int i = 0; i < nx; ++i, ++dat) {
07044 x2 = (float)( i - nx/2 );
07045 y2 = (float)( j - ny/2 );
07046 z2 = (float)( k - nz/2 );
07047
07048 if(axis==""){
07049 r = (float)sqrt(x2*x2+y2*y2+z2*z2);
07050 }
07051 else if(axis == "x"){
07052 float lc = -c;
07053 float rc = c;
07054 r = ( (float)sqrt((x2-lc)*(x2-lc)+y2*y2+z2*z2) +
07055 (float)sqrt((x2-rc)*(x2-rc)+y2*y2+z2*z2) ) /2.0f - c;
07056 }
07057 else if(axis == "y"){
07058 float lc = -c;
07059 float rc = c;
07060 r = ( (float)sqrt(x2*x2+(y2-lc)*(y2-lc)+z2*z2) +
07061 (float)sqrt(x2*x2+(y2-rc)*(y2-rc)+z2*z2) ) /2.0f - c;
07062 }
07063 else if(axis == "z"){
07064 if( nz == 1 ){
07065 throw InvalidValueException(0, "This is a 2D image, no asymmetric feature for z axis");
07066 }
07067 float lc = -c;
07068 float rc = c;
07069 r = ( (float)sqrt(x2*x2+y2*y2+(z2-lc)*(z2-lc)) +
07070 (float)sqrt(x2*x2+y2*y2+(z2-rc)*(z2-rc)) ) /2.0f - c;
07071 }
07072 else{
07073 throw InvalidValueException(0, "please specify a valid axis for asymmetric features");
07074 }
07075
07076 *dat = (float)gsl_ran_gaussian_pdf((double)r,(double)sigma);
07077 }
07078 }
07079 }
07080
07081 image->update();
07082 }
07083
07084 void TestImageGradient::process_inplace(EMData * image)
07085 {
07086 string axis = params.set_default("axis", "x");
07087
07088 float m = params.set_default("m", 1.0f);
07089 float b = params.set_default("b", 0.0f);
07090
07091 if ( axis != "z" && axis != "y" && axis != "x") throw InvalidParameterException("Axis must be x,y or z");
07092
07093 preprocess(image);
07094
07095 if ( axis == "x")
07096 {
07097 for(int k=0; k<nz;++k) {
07098 for(int j=0; j<ny; ++j) {
07099 for(int i=0; i <nx; ++i) {
07100 image->set_value_at(i,j,k,m*i+b);
07101 }
07102 }
07103 }
07104 }
07105 else if ( axis == "y")
07106 {
07107 for(int k=0; k<nz;++k) {
07108 for(int j=0; j<ny; ++j) {
07109 for(int i=0; i <nx; ++i) {
07110 image->set_value_at(i,j,k,m*j+b);
07111 }
07112 }
07113 }
07114 }
07115 else if ( axis == "z")
07116 {
07117 for(int k=0; k<nz;++k) {
07118 for(int j=0; j<ny; ++j) {
07119 for(int i=0; i <nx; ++i) {
07120 image->set_value_at(i,j,k,m*k+b);
07121 }
07122 }
07123 }
07124 }
07125 image->update();
07126 }
07127
07128 void TestImageAxes::process_inplace(EMData * image)
07129 {
07130 preprocess(image);
07131
07132 float fill = params.set_default("fill", 1.0f);
07133
07134 int cx = nx/2;
07135 int cy = ny/2;
07136 int cz = nz/2;
07137
07138
07139
07140
07141
07142 int xoffset = (nx % 2 == 0? 1:0);
07143 int yoffset = (ny % 2 == 0? 1:0);
07144 int zoffset = (nz % 2 == 0? 1:0);
07145
07146
07147
07148
07149
07150
07151 if ( nx == 1 && ny == 1 && nz == 1 )
07152 {
07153 (*image)(0) = fill;
07154 }
07155 else if ( ny == 1 && nz == 1 )
07156 {
07157 int radius = params.set_default("radius", cx );
07158 if ( radius > cx ) radius = cx;
07159
07160 (*image)(cx) = fill;
07161 for ( int i = 1; i <= radius-xoffset; ++i ) (*image)(cx+i) = fill;
07162 for ( int i = 1; i <= radius; ++i ) (*image)(cx-i) = fill;
07163 }
07164 else if ( nz == 1 )
07165 {
07166 int min = ( nx < ny ? nx : ny );
07167 min /= 2;
07168
07169 int radius = params.set_default("radius", min );
07170 if ( radius > min ) radius = min;
07171
07172 (*image)(cx,cy) = fill;
07173
07174 for ( int i = 1; i <= radius-xoffset; ++i ) (*image)(cx+i,cy) = fill;
07175 for ( int i = 1; i <= radius-yoffset; ++i )(*image)(cx,cy+i) = fill;
07176
07177 for ( int i = 1; i <= radius; ++i )
07178 {
07179 (*image)(cx-i,cy) = fill;
07180 (*image)(cx,cy-i) = fill;
07181 }
07182
07183 }
07184 else
07185 {
07186
07187 int min = ( nx < ny ? nx : ny );
07188 if (nz < min ) min = nz;
07189 min /= 2;
07190
07191 int radius = params.set_default("radius", min);
07192 if ( radius > min ) radius = min;
07193
07194
07195 (*image)(cx,cy,cz) = fill;
07196 for ( int i = 1; i <=radius-xoffset; ++i ) (*image)(cx+i,cy,cz) = fill;
07197 for ( int i = 1; i <=radius-yoffset; ++i ) (*image)(cx,cy+i,cz) = fill;
07198 for ( int i = 1; i <=radius-zoffset; ++i ) (*image)(cx,cy,cz+i) = fill;
07199 for ( int i = 1; i <= radius; ++i )
07200 {
07201 (*image)(cx-i,cy,cz) = fill;
07202 (*image)(cx,cy-i,cz) = fill;
07203 (*image)(cx,cy,cz-i) = fill;
07204 }
07205 }
07206
07207 image->update();
07208 }
07209
07210 void TestImageScurve::process_inplace(EMData * image)
07211 {
07212 preprocess(image);
07213
07214 int dim_size = image->get_ndim();
07215 if( 2 != dim_size ) {
07216 throw ImageDimensionException("works for 2D images only");
07217 }
07218
07219 int nx = image->get_xsize();
07220 int ny = image->get_ysize();
07221 image->to_zero();
07222
07223 for (int i=0; i<100; i++) {
07224 int x=static_cast<int>( nx/2+nx/6.0*sin(i*2.0*3.14159/100.0) );
07225 int y=ny/4+i*ny/200;
07226 for (int xx=x-nx/10; xx<x+nx/10; xx++) {
07227 for (int yy=y-ny/10; yy<y+ny/10; yy++) {
07228 #ifdef _WIN32
07229 (*image)(xx,yy)+=exp(-pow(static_cast<float>(_hypot(xx-x,yy-y))*30.0f/nx,2.0f))*(sin(static_cast<float>((xx-x)*(yy-y)))+.5f);
07230 #else
07231 (*image)(xx,yy)+=exp(-pow(static_cast<float>(hypot(xx-x,yy-y))*30.0f/nx,2.0f))*(sin(static_cast<float>((xx-x)*(yy-y)))+.5f);
07232 #endif
07233 }
07234 }
07235 }
07236
07237 image->update();
07238 }
07239
07240 void TestImagePureGaussian::process_inplace(EMData * image)
07241 {
07242 preprocess(image);
07243
07244 float x_sigma = params["x_sigma"];
07245 float y_sigma = params["y_sigma"];
07246 float z_sigma = params["z_sigma"];
07247
07248 float x_center = params["x_center"];
07249 float y_center = params["y_center"];
07250 float z_center = params["z_center"];
07251
07252 int nx = image->get_xsize();
07253 int ny = image->get_ysize();
07254 int nz = image->get_zsize();
07255
07256 float x_twosig2 = 2*x_sigma*x_sigma;
07257 float y_twosig2 = 2*y_sigma*y_sigma;
07258 float z_twosig2 = 2*z_sigma*z_sigma;
07259
07260 float sr2pi = sqrt( 2.0f*(float)pi );
07261 float norm = 1.0f/ ( x_sigma*sr2pi );
07262 if (ny > 1) {
07263 norm *= 1.0f/ ( y_sigma*sr2pi );
07264 if (nz > 1) norm *= 1.0f/ ( z_sigma*sr2pi );
07265 }
07266
07267 float z, y, x, sum, val;
07268 for (int iz=0; iz < nz; ++iz) {
07269 z = static_cast<float>(iz) - z_center;
07270 for (int iy=0; iy < ny; ++iy) {
07271 y = static_cast<float>(iy) - y_center;
07272 for (int ix=0; ix < nx; ++ix) {
07273 x = static_cast<float>(ix) - x_center;
07274 sum = x*x/x_twosig2 + y*y/y_twosig2 + z*z/z_twosig2;
07275 val = norm*exp(-sum);
07276 (*image)(ix,iy,iz) = val;
07277 }
07278 }
07279 }
07280 image->update();
07281 }
07282
07283 void TestImageSphericalWave::process_inplace(EMData * image)
07284 {
07285 preprocess(image);
07286
07287 if(!params.has_key("wavelength")) {
07288 LOGERR("%s wavelength is required parameter", get_name().c_str());
07289 throw InvalidParameterException("wavelength parameter is required.");
07290 }
07291 float wavelength = params["wavelength"];
07292
07293 float phase = 0;
07294 if(params.has_key("phase")) {
07295 phase = params["phase"];
07296 }
07297
07298 float x = (float)(nx/2);
07299 if (params.has_key("x")) x=params["x"];
07300 float y = (float)(ny/2);
07301 if (params.has_key("y")) y=params["y"];
07302 float z = (float)(nz/2);
07303 if (params.has_key("z")) z=params["z"];
07304
07305 int ndim = image->get_ndim();
07306
07307 if(ndim==2) {
07308 for(int j=0; j<ny; ++j) {
07309 for(int i=0; i<nx; ++i) {
07310 #ifdef _WIN32
07311 float r=_hypotf(x-(float)i,y-(float)j);
07312 #else
07313 float r=hypot(x-(float)i,y-(float)j);
07314 #endif //_WIN32
07315 if (r<.5) continue;
07316 image->set_value_at(i,j,cos(2*(float)pi*r/wavelength+phase)/r);
07317 }
07318 }
07319 }
07320 else {
07321 for(int k=0; k<nz; ++k) {
07322 for(int j=0; j<ny; ++j) {
07323 for(int i=0; i<nx; ++i) {
07324 float r=Util::hypot3(x-(float)i,y-(float)j,z-(float)k);
07325 if (r<.5) continue;
07326 image->set_value_at(i,j,k,cos(2*(float)pi*r/wavelength+phase)/(r*r));
07327 }
07328 }
07329 }
07330 }
07331
07332 image->update();
07333 }
07334
07335
07336 void TestImageSinewave::process_inplace(EMData * image)
07337 {
07338 preprocess(image);
07339
07340 if(!params.has_key("wavelength")) {
07341 LOGERR("%s wavelength is required parameter", get_name().c_str());
07342 throw InvalidParameterException("wavelength parameter is required.");
07343 }
07344 float wavelength = params["wavelength"];
07345
07346 string axis = "";
07347 if(params.has_key("axis")) {
07348 axis = (const char*)params["axis"];
07349 }
07350
07351 float phase = 0;
07352 if(params.has_key("phase")) {
07353 phase = params["phase"];
07354 }
07355
07356 int ndim = image->get_ndim();
07357 float * dat = image->get_data();
07358
07359 if(ndim==1) {
07360 for(int i=0; i<nx; ++i, ++dat) {
07361 *dat = sin(i*(2.0f*M_PI/wavelength) + phase);
07362 }
07363 }
07364 else if(ndim==2) {
07365 float alpha = 0;
07366 if(params.has_key("az")) {
07367 alpha = params["az"];
07368 }
07369 for(int j=0; j<ny; ++j) {
07370 for(int i=0; i<nx; ++i, ++dat) {
07371 if(alpha != 0) {
07372 *dat = sin((i*sin((180-alpha)*M_PI/180)+j*cos((180-alpha)*M_PI/180))*(2.0f*M_PI/wavelength) + phase);
07373 }
07374 else if(axis.compare("y")==0 || axis.compare("Y")==0) {
07375 *dat = sin(j*(2.0f*M_PI/wavelength) + phase);
07376 }
07377 else {
07378 *dat = sin(i*(2.0f*M_PI/wavelength) + phase);
07379 }
07380 }
07381 }
07382 }
07383 else {
07384 float az = 0;
07385 if(params.has_key("az")) {
07386 az = params["az"];
07387 }
07388 float alt = 0;
07389 if(params.has_key("alt")) {
07390 alt = params["alt"];
07391 }
07392 float phi = 0;
07393 if(params.has_key("phi")) {
07394 phi = params["phi"];
07395 }
07396
07397 for(int k=0; k<nz; ++k) {
07398 for(int j=0; j<ny; ++j) {
07399 for(int i=0; i<nx; ++i, ++dat) {
07400 if(axis.compare("z")==0 || axis.compare("Z")==0) {
07401 *dat = sin(k*(2.0f*M_PI/wavelength) + phase);
07402 }
07403 else if(axis.compare("y")==0 || axis.compare("Y")==0) {
07404 *dat = sin(j*(2.0f*M_PI/wavelength) + phase);
07405 }
07406 else {
07407 *dat = sin(i*(2.0f*M_PI/wavelength) + phase);
07408 }
07409 }
07410 }
07411 }
07412
07413 if(az != 0 || alt != 0 || phi != 0) {
07414 Dict d("type","eman");
07415 d["az"] = az; d["phi"] = phi; d["alt"] = alt;
07416 image->transform(Transform(d));
07417 }
07418 }
07419
07420 image->update();
07421 }
07422
07423 void TestImageSinewaveCircular::process_inplace(EMData * image)
07424 {
07425 preprocess(image);
07426
07427 float wavelength = params["wavelength"];
07428 string axis = (const char*)params["axis"];
07429 float c = params["c"];
07430 float phase = params["phase"];
07431
07432 float *dat = image->get_data();
07433 float r;
07434 float x2, y2, z2;
07435 for (int k = 0; k < nz; ++k) {
07436 for (int j = 0; j < ny; ++j) {
07437 for (int i = 0; i < nx; ++i, ++dat) {
07438 x2 = (float)( i - nx/2 );
07439 y2 = (float)( j - ny/2 );
07440 z2 = (float)( k - nz/2 );
07441 if(axis == ""){
07442 r = (float)sqrt(x2*x2+y2*y2+z2*z2);
07443 }
07444 else if(axis == "x"){
07445 float lc = -c;
07446 float rc = c;
07447 r = ( (float)sqrt((x2-lc)*(x2-lc)+y2*y2+z2*z2) +
07448 (float)sqrt((x2-rc)*(x2-rc)+y2*y2+z2*z2) ) /2.0f - c;
07449 }
07450 else if(axis == "y"){
07451 float lc = -c;
07452 float rc = c;
07453 r = ( (float)sqrt(x2*x2+(y2-lc)*(y2-lc)+z2*z2) +
07454 (float)sqrt(x2*x2+(y2-rc)*(y2-rc)+z2*z2) ) /2.0f - c;
07455 }
07456 else if(axis == "z"){
07457 if( nz == 1 ){
07458 throw InvalidValueException(0, "This is a 2D image, no asymmetric feature for z axis");
07459 }
07460 float lc = -c;
07461 float rc = c;
07462 r = ( (float)sqrt(x2*x2+y2*y2+(z2-lc)*(z2-lc)) +
07463 (float)sqrt(x2*x2+y2*y2+(z2-rc)*(z2-rc)) ) /2.0f - c;
07464 }
07465 else{
07466 throw InvalidValueException(0, "please specify a valid axis for asymmetric features");
07467 }
07468 *dat = sin( r * (2.0f*M_PI/wavelength) - phase*180/M_PI);
07469 }
07470 }
07471 }
07472
07473 image->update();
07474 }
07475
07476 void TestImageSquarecube::process_inplace(EMData * image)
07477 {
07478 preprocess(image);
07479
07480 float edge_length = params["edge_length"];
07481 string axis = (const char*)params["axis"];
07482 float odd_edge = params["odd_edge"];
07483 int fill = (int)params["fill"];
07484
07485 float *dat = image->get_data();
07486 float x2, y2, z2;
07487 float xEdge, yEdge, zEdge;
07488 if(axis == ""){
07489 xEdge = edge_length/2.0f;
07490 yEdge = edge_length/2.0f;
07491 zEdge = edge_length/2.0f;
07492 }
07493 else if(axis == "x"){
07494 xEdge = odd_edge/2.0f;
07495 yEdge = edge_length/2.0f;
07496 zEdge = edge_length/2.0f;
07497 }
07498 else if(axis == "y"){
07499 xEdge = edge_length/2.0f;
07500 yEdge = odd_edge/2.0f;
07501 zEdge = edge_length/2.0f;
07502 }
07503 else if(axis == "z"){
07504 if( nz == 1 ){
07505 throw InvalidValueException(0, "This is a 2D image, no asymmetric feature for z axis");
07506 }
07507 xEdge = edge_length/2.0f;
07508 yEdge = edge_length/2.0f;
07509 zEdge = odd_edge/2.0f;
07510 }
07511 else{
07512 throw InvalidValueException(0, "please specify a valid axis for asymmetric features");
07513 }
07514 for (int k = 0; k < nz; ++k) {
07515 for (int j = 0; j < ny; ++j) {
07516 for (int i = 0; i < nx; ++i, ++dat) {
07517 x2 = (float)fabs((float)i - nx/2);
07518 y2 = (float)fabs((float)j - ny/2);
07519 z2 = (float)fabs((float)k - nz/2);
07520 if( x2<=xEdge && y2<=yEdge && z2<=zEdge ) {
07521 if( !fill) {
07522 *dat = 0;
07523 }
07524 else {
07525 *dat = 1;
07526 }
07527 }
07528 else {
07529 if( !fill ) {
07530 *dat = 1;
07531 }
07532 else {
07533 *dat = 0;
07534 }
07535 }
07536 }
07537 }
07538 }
07539
07540 image->update();
07541 }
07542
07543 void TestImageCirclesphere::process_inplace(EMData * image)
07544 {
07545 preprocess(image);
07546
07547 float radius = params.set_default("radius",nx/2.0f);
07548 string axis = (const char*)params["axis"];
07549 float c = params.set_default("c",nx/2.0f);
07550 int fill = params.set_default("fill",1);
07551
07552 float *dat = image->get_data();
07553 float x2, y2, z2;
07554 float r = 0.0f;
07555 float asy = 0.0f;
07556 if(axis == ""){
07557 asy = radius;
07558 }
07559 else if(axis == "x" || axis == "y"){
07560 asy = c;
07561 }
07562 else if(axis=="z"){
07563 if( nz == 1 ){
07564 throw InvalidValueException(0, "This is a 2D image, no asymmetric feature for z axis");
07565 }
07566 asy = c;
07567 }
07568 else{
07569 throw InvalidValueException(0, "please specify a valid axis for asymmetric features");
07570 }
07571
07572 for (int k = 0; k < nz; ++k) {
07573 for (int j = 0; j < ny; ++j) {
07574 for (int i = 0; i < nx; ++i, ++dat) {
07575 x2 = fabs((float)i - nx/2);
07576 y2 = fabs((float)j - ny/2);
07577 z2 = fabs((float)k - nz/2);
07578 if( axis == "" ){
07579 r = (x2*x2)/(radius*radius) + (y2*y2)/(radius*radius) + (z2*z2)/(radius*radius);
07580 }
07581 else if (axis == "x"){
07582 r = (x2*x2)/(asy*asy) + (y2*y2)/(radius*radius) + (z2*z2)/(radius*radius);
07583 }
07584 else if(axis == "y"){
07585 r = (x2*x2)/(radius*radius) + (y2*y2)/(asy*asy) + (z2*z2)/(radius*radius);
07586 }
07587 else if(axis=="z"){
07588 r = (x2*x2)/(radius*radius) + (y2*y2)/(radius*radius) + (z2*z2)/(asy*asy);
07589 }
07590 if( r<=1 ) {
07591 if( !fill) {
07592 *dat = 0;
07593 }
07594 else {
07595 *dat = 1;
07596 }
07597 }
07598 else {
07599 if( !fill ) {
07600 *dat = 1;
07601 }
07602 else {
07603 *dat = 0;
07604 }
07605 }
07606 }
07607 }
07608 }
07609
07610 image->update();
07611 }
07612
07613 void TestImageHollowEllipse::process_inplace(EMData * image)
07614 {
07615 preprocess(image);
07616
07617 float width = params.set_default("width",2.0f);
07618
07619 float a2 = params.set_default("a",nx/2.0f-1.0f);
07620 float b2 = params.set_default("b",ny/2.0f-1.0f);
07621 float c2 = params.set_default("c",nz/2.0f-1.0f);
07622
07623 float a1 = params.set_default("xwidth",a2-width);
07624 float b1 = params.set_default("ywidth",b2-width);
07625 float c1 = params.set_default("zwidth",c2-width);
07626
07627 float fill = params.set_default("fill",1.0f);
07628 Transform* t;
07629 if (params.has_key("transform")) {
07630 t = params["transform"];
07631 } else {
07632 t = new Transform;
07633 }
07634
07635
07636 int mz = 2*(int)c2+1;
07637 if ( nz < mz ) mz = nz;
07638 int my = 2*(int)b2+1;
07639 if ( ny < my ) my = ny;
07640 int mx = 2*(int)a2+1;
07641 if ( nx < mx ) mx = nx;
07642
07643 float ai1 = 1/(a1*a1);
07644 float bi1 = 1/(b1*b1);
07645 float ci1 = 1/(c1*c1);
07646
07647 float ai2 = 1/(a2*a2);
07648 float bi2 = 1/(b2*b2);
07649 float ci2 = 1/(c2*c2);
07650
07651 Vec3f origin(nx/2,ny/2,nz/2);
07652
07653 float x2, y2, z2, r1,r2;
07654 int xl, yl, zl;
07655 for (int k = 0; k < mz; ++k) {
07656 for (int j = 0; j < my; ++j) {
07657 for (int i = 0; i < mx; ++i) {
07658 x2 = (float)(i - mx/2);
07659 y2 = (float)(j - my/2);
07660 z2 = (float)(k - mz/2);
07661 r1 = (x2*x2)*ai1 + (y2*y2)*bi1 + (z2*z2)*ci1;
07662 r2 = (x2*x2)*ai2 + (y2*y2)*bi2 + (z2*z2)*ci2;
07663 if (r2 <= 1 && r1 >= 1) {
07664
07665 if (t != 0) {
07666 Vec3f v(x2,y2,z2);
07667 v = (*t)*v;
07668 v += origin;
07669
07670
07671
07672
07673 for( int kk = -1; kk <= 1; ++kk)
07674 for( int jj = -1; jj <= 1; ++jj)
07675 for( int ii = -1; ii <= 1; ++ii) {
07676 xl = (int)v[0]+ii;
07677 yl = (int)v[1]+jj;
07678 zl = (int)v[2]+kk;
07679 if (xl >= 0 && xl < nx && yl >= 0 && yl < ny && zl >= 0 && zl < nz)
07680 image->set_value_at(xl,yl,zl,1.0);
07681 }
07682 } else {
07683 image->set_value_at((int)x2+nx/2,(int)y2+ny/2,(int)z2+nz/2,fill);
07684 }
07685 }
07686 }
07687 }
07688 }
07689
07690 delete t;
07691
07692 image->update();
07693 }
07694
07695 void TestImageEllipse::process_inplace(EMData * image)
07696 {
07697 preprocess(image);
07698
07699
07700 float a = params.set_default("a",nx/2.0f-1.0f);
07701 float b = params.set_default("b",ny/2.0f-1.0f);
07702 float c = params.set_default("c",nz/2.0f-1.0f);
07703 float fill = params.set_default("fill",1.0f);
07704
07705 Transform* t;
07706 if (params.has_key("transform")) {
07707 t = params["transform"];
07708 } else {
07709 t = new Transform;
07710 }
07711
07712
07713 int mz = 2*(int)c+1;
07714 if ( nz < mz ) mz = nz;
07715 int my = 2*(int)b+1;
07716 if ( ny < my ) my = ny;
07717 int mx = 2*(int)a+1;
07718 if ( nx < mx ) mx = nx;
07719
07720
07721 float ai = 1/(a*a);
07722 float bi = 1/(b*b);
07723 float ci = 1/(c*c);
07724
07725 Vec3f origin(nx/2,ny/2,nz/2);
07726
07727 float x2, y2, z2, r;
07728 int xl, yl, zl;
07729 for (int k = 0; k < mz; ++k) {
07730 for (int j = 0; j < my; ++j) {
07731 for (int i = 0; i < mx; ++i) {
07732 x2 = (float)(i - mx/2);
07733 y2 = (float)(j - my/2);
07734 z2 = (float)(k - mz/2);
07735 r = (x2*x2)*ai + (y2*y2)*bi + (z2*z2)*ci;
07736 if (r <= 1) {
07737
07738 if (t != 0) {
07739 Vec3f v(x2,y2,z2);
07740 v = (*t)*v;
07741 v += origin;
07742
07743
07744
07745
07746 for( int kk = -1; kk <= 1; ++kk)
07747 for( int jj = -1; jj <= 1; ++jj)
07748 for( int ii = -1; ii <= 1; ++ii) {
07749 xl = (int)v[0]+ii;
07750 yl = (int)v[1]+jj;
07751 zl = (int)v[2]+kk;
07752 if (xl >= 0 && xl < nx && yl >= 0 && yl < ny && zl >= 0 && zl < nz)
07753 image->set_value_at(xl,yl,zl,fill);
07754 }
07755 } else {
07756 image->set_value_at((int)x2+nx/2,(int)y2+ny/2,(int)z2+nz/2,fill);
07757 }
07758 }
07759 }
07760 }
07761 }
07762
07763 delete t;
07764
07765 image->update();
07766 }
07767
07768 void TestImageNoiseUniformRand::process_inplace(EMData * image)
07769 {
07770 preprocess(image);
07771
07772 Randnum * r = Randnum::Instance();
07773 if(params.has_key("seed")) {
07774 r->set_seed((int)params["seed"]);
07775 }
07776
07777 float *dat = image->get_data();
07778 size_t size = nx*ny*nz;
07779 for (size_t i=0; i<size; ++i) {
07780 dat[i] = r->get_frand();
07781 }
07782
07783 image->update();
07784 }
07785
07786 void TestImageNoiseGauss::process_inplace(EMData * image)
07787 {
07788 preprocess(image);
07789
07790 float sigma = params["sigma"];
07791 if (sigma<=0) { sigma = 1.0; }
07792 float mean = params["mean"];
07793
07794 Randnum * r = Randnum::Instance();
07795 if (params.has_key("seed")) {
07796 r->set_seed((int)params["seed"]);
07797 }
07798
07799 float *dat = image->get_data();
07800 size_t size = nx*ny*nz;
07801 for (size_t i=0; i<size; ++i) {
07802 dat[i] = r->get_gauss_rand(mean, sigma);
07803 }
07804
07805 image->update();
07806 }
07807
07808 void TestImageCylinder::process_inplace(EMData * image)
07809 {
07810 preprocess(image);
07811
07812 int nx = image->get_xsize();
07813 int ny = image->get_ysize();
07814 int nz = image->get_zsize();
07815
07816 if(nz == 1) {
07817 throw ImageDimensionException("This processor only apply to 3D image");
07818 }
07819
07820 float radius = params["radius"];
07821 #ifdef _WIN32
07822 if(radius > _cpp_min(nx, ny)/2.0) {
07823 #else
07824 if(radius > std::min(nx, ny)/2.0) {
07825 #endif
07826 throw InvalidValueException(radius, "radius must be <= min(nx, ny)/2");
07827 }
07828
07829 float height;
07830 if(params.has_key("height")) {
07831 height = params["height"];
07832 if(height > nz) {
07833 throw InvalidValueException(radius, "height must be <= nz");
07834 }
07835 }
07836 else {
07837 height = static_cast<float>(nz);
07838 }
07839
07840 float *dat = image->get_data();
07841 float x2, y2;
07842 float r = 0.0f;
07843 for (int k = 0; k < nz; ++k) {
07844 for (int j = 0; j < ny; ++j) {
07845 for (int i = 0; i < nx; ++i, ++dat) {
07846 x2 = fabs((float)i - nx/2);
07847 y2 = fabs((float)j - ny/2);
07848 r = (x2*x2)/(radius*radius) + (y2*y2)/(radius*radius);
07849
07850 if(r<=1 && k>=(nz-height)/2 && k<=(nz+height)/2) {
07851 *dat = 1;
07852 }
07853 else {
07854 *dat = 0;
07855 }
07856 }
07857 }
07858 }
07859
07860 image->update();
07861 }
07862
07863 void RampProcessor::process_inplace(EMData * image)
07864 {
07865 if (!image) {
07866 return;
07867 }
07868
07869 int nz = image->get_zsize();
07870 if (nz > 1) {
07871 LOGERR("%s Processor doesn't support 3D model", get_name().c_str());
07872 throw ImageDimensionException("3D model not supported");
07873 }
07874
07875 int nsam = image->get_xsize();
07876 int nrow = image->get_ysize();
07877 int n1 = nsam / 2;
07878 double sx1 = double(n1)*double(nsam+1);
07879 if ( nsam % 2 == 1 )
07880 sx1 += 1 + n1;
07881 sx1 *= nrow;
07882 int n2 = nrow / 2;
07883 double sx2 = double(n2)*double(nrow+1);
07884 if ( nrow % 2 == 1 )
07885 sx2 += 1 + n2;
07886 sx2 *= nsam;
07887 float *data = image->get_data();
07888 float *row = NULL;
07889
07890 double syx1 = 0, syx2 = 0, sy = 0, sx1q = 0, sx2q = 0, syq = 0;
07891 for (int j=1; j <= nrow; j++) {
07892 row = data + (j-1)*nsam - 1;
07893 for (int i=1; i<=nsam; i++) {
07894 syx1 += row[i]*i;
07895 syx2 += row[i]*j;
07896 sy += row[i];
07897 sx1q += i*i;
07898 sx2q += j*j;
07899 syq += row[i]*double(row[i]);
07900 }
07901 }
07902
07903 float dn = float(nsam)*float(nrow);
07904 double qyx1 = syx1 - sx1*sy / dn;
07905 double qyx2 = syx2 - sx2*sy / dn;
07906 double qx1x2 = 0.0;
07907 double qx1 = sx1q - sx1*sx1 / dn;
07908 double qx2 = sx2q - sx2*sx2 / dn;
07909 double qy = syq - sy*sy / dn;
07910 double c = qx1*qx2 - qx1x2*qx1x2;
07911 if ( c > FLT_EPSILON ) {
07912 double b1 = (qyx1*qx2 - qyx2*qx1x2) / c;
07913 double b2 = (qyx2*qx1 - qyx1*qx1x2) / c;
07914 double a = (sy - b1*sx1 - b2*sx2) / dn;
07915 double d = a + b1 + b2;
07916 for (int i=1; i<=nrow; i++) {
07917 qy = d;
07918 row = data + (i-1)*nsam - 1;
07919 for (int k=1; k<=nsam; k++) {
07920 row[k] -= static_cast<float>(qy);
07921 qy += b1;
07922 }
07923 d += b2;
07924 }
07925 }
07926
07927 image->update();
07928 }
07929
07930
07931 void CCDNormProcessor::process_inplace(EMData * image)
07932 {
07933 if (!image) {
07934 Log::logger()->set_level(Log::ERROR_LOG);
07935 Log::logger()->error("Null image during call to CCDNorm\n");
07936 return;
07937 }
07938 if (image->get_zsize() > 1) {
07939 Log::logger()->set_level(Log::ERROR_LOG);
07940 Log::logger()->error("CCDNorm does not support 3d images\n");
07941 return;
07942 }
07943
07944 int xs = image->get_xsize();
07945 int ys = image->get_ysize();
07946
07947
07948 int width = params["width"];
07949
07950 width%=(xs > ys ? xs/2 : ys/2);
07951 if (width==0) {
07952 width=1;
07953 }
07954
07955
07956 float *left, *right, *top, *bottom;
07957
07958 double *temp;
07959 temp= (double*)malloc((xs > ys ? xs*width : ys*width)*sizeof(double));
07960 if (temp==NULL) {
07961 Log::logger()->set_level(Log::ERROR_LOG);
07962 Log::logger()->error("Could not allocate enough memory during call to CCDNorm\n");
07963 return;
07964 }
07965
07966 int x, y, z;
07967
07968
07969 double mL,mR,mT,mB;
07970
07971
07972 double nl,nr,nt,nb;
07973
07974
07975 double q1,q2,q3,q4;
07976
07977
07978 for (z=0; z<width; z++) {
07979 left = image->get_col(xs/2 -1-z)->get_data();
07980 for (y=0; y<ys; y++)
07981 temp[z*ys+y]=left[y];
07982 }
07983 mL=gsl_stats_mean(temp,1,ys*width);
07984
07985 for (z=0; z<width; z++) {
07986 right = image->get_col(xs/2 +z)->get_data();
07987 for (y=0; y<ys; y++)
07988 temp[z*ys+y]=right[y];
07989 }
07990 mR=gsl_stats_mean(temp,1,ys*width);
07991
07992 for (z=0; z<width; z++) {
07993 top = image->get_row(ys/2 -1-z)->get_data();
07994 for (x=0; x<xs; x++)
07995 temp[z*xs+x]=top[x];
07996 }
07997 mT=gsl_stats_mean(temp,1,xs*width);
07998
07999 for (z=0; z<width; z++) {
08000 bottom = image->get_row(ys/2 +z)->get_data();
08001 for (x=0; x<xs; x++)
08002 temp[z*xs+x]=bottom[x];
08003 }
08004 mB=gsl_stats_mean(temp,1,xs*width);
08005
08006 free(temp);
08007
08008 nl=(mL+mR)/2-mL;
08009 nr=(mL+mR)/2-mR;
08010 nt=(mT+mB)/2-mT;
08011 nb=(mT+mB)/2-mB;
08012
08013 q1=nl+nt;
08014 q2=nr+nt;
08015 q3=nr+nb;
08016 q4=nl+nb;
08017
08018
08019 for (x = 0; x < xs / 2; x++)
08020 for (y = 0; y < ys / 2; y++) {
08021 image->set_value_at_fast(x, y, image->get_value_at(x, y) + static_cast<float>(q1));
08022 }
08023 for (x = xs / 2; x < xs; x++)
08024 for (y = 0; y < ys / 2; y++) {
08025 image->set_value_at_fast(x, y, image->get_value_at(x, y) + static_cast<float>(q2));
08026 }
08027 for (x = xs / 2; x < xs; x++)
08028 for (y = ys / 2; y < ys; y++) {
08029 image->set_value_at_fast(x, y, image->get_value_at(x, y) + static_cast<float>(q3));
08030 }
08031 for (x = 0; x < xs / 2; x++)
08032 for (y = ys / 2; y < ys; y++) {
08033 image->set_value_at_fast(x, y, image->get_value_at(x, y) + static_cast<float>(q4));
08034 }
08035
08036 }
08037
08038 void WaveletProcessor::process_inplace(EMData *image)
08039 {
08040 if (image->get_zsize() != 1) {
08041 LOGERR("%s Processor doesn't support 3D", get_name().c_str());
08042 throw ImageDimensionException("3D model not supported");
08043 }
08044
08045 int i,nx,ny;
08046 const gsl_wavelet_type * T;
08047 nx=image->get_xsize();
08048 ny=image->get_ysize();
08049
08050 if (nx != ny && ny!=1) throw ImageDimensionException("Wavelet transform only supports square images");
08051
08052
08053 if( !Util::IsPower2(nx) ) throw ImageDimensionException("Wavelet transform size must be power of 2");
08054
08055
08056
08057
08058 double *cpy = (double *)malloc(nx*ny*sizeof(double));
08059
08060 for (i=0; i<nx*ny; i++) cpy[i]=image->get_value_at(i,0,0);
08061
08062 string tp = (const char*)params["type"];
08063 if (tp=="daub") T=gsl_wavelet_daubechies;
08064 else if (tp=="harr") T=gsl_wavelet_haar;
08065 else if (tp=="bspl") T=gsl_wavelet_bspline;
08066 else throw InvalidStringException(tp,"Invalid wavelet name, 'daub', 'harr' or 'bspl'");
08067
08068 int K=(int)params["ord"];
08069 gsl_wavelet_direction dir;
08070 if ((int)params["dir"]==1) dir=forward;
08071 else dir=backward;
08072
08073 gsl_wavelet *w = gsl_wavelet_alloc(T, K);
08074 gsl_wavelet_workspace *work = gsl_wavelet_workspace_alloc(nx);
08075
08076 if (ny==1) gsl_wavelet_transform (w,cpy, 1, nx, dir, work);
08077 else gsl_wavelet2d_transform (w, cpy, nx,nx,ny, dir, work);
08078
08079 gsl_wavelet_workspace_free (work);
08080 gsl_wavelet_free (w);
08081
08082 for (i=0; i<nx*ny; i++) image->set_value_at_fast(i,0,0,static_cast<float>(cpy[i]));
08083
08084 free(cpy);
08085 }
08086
08087 void FFTProcessor::process_inplace(EMData* image)
08088 {
08089 if( params.has_key("dir") ) {
08090 if ((int)params["dir"]==-1) {
08091 image->do_ift_inplace();
08092 }
08093 else {
08094 image->do_fft_inplace();
08095 }
08096 }
08097 }
08098
08099 void RadialProcessor::process_inplace(EMData * image)
08100 {
08101 if (!image) {
08102 LOGWARN("NULL Image");
08103 return;
08104 }
08105
08106
08107 if(image->is_complex()) {
08108 LOGERR("%s Processor only operates on real images", get_name().c_str());
08109 throw ImageFormatException("apply to real image only");
08110 }
08111
08112 vector<float> table = params["table"];
08113 vector<float>::size_type tsize = table.size();
08114
08115 int nx = image->get_xsize();
08116 int ny = image->get_ysize();
08117 int nz = image->get_zsize();
08118
08119 int nx2 = nx / 2;
08120 int ny2 = ny / 2;
08121 int nz2 = nz / 2;
08122 float sz[3];
08123 sz[0] = static_cast<float>(nx2);
08124 sz[1] = static_cast<float>(ny2);
08125 sz[2] = static_cast<float>(nz2);
08126 float szmax = *std::max_element(&sz[0], &sz[3]);
08127 float maxsize;
08128 if(nz>1) {
08129 maxsize = (float)(1.8f * szmax);
08130 }
08131 else{
08132 maxsize = (float)(1.5f * szmax);
08133 }
08134 for(int i=tsize+1; i<maxsize; i++) {
08135 table.push_back(0.0f);
08136 }
08137
08138 float dx = 1.0f / (float)nx;
08139 float dy = 1.0f / (float)ny;
08140 float dz = 1.0f / (float)nz;
08141 float dx2 = dx * dx;
08142 float dy2 = dy * dy;
08143 float dz2 = dz * dz;
08144 int iz, iy, ix, jz, jy, jx;
08145 float argx, argy, argz;
08146 float rf, df, f;
08147 int ir;
08148 for(iz=1; iz<=nz; iz++) {
08149 jz = iz - 1;
08150 if(jz > nz2) {
08151 jz -= nz;
08152 }
08153 argz = float(jz*jz) * dz2;
08154
08155 for(iy=1; iy<=ny; iy++) {
08156 jy = iy - 1;
08157 if(jy > ny2) {
08158 jy -= ny;
08159 }
08160 argy = argz + float(jy*jy) * dy2;
08161
08162 for(ix=1; ix<=nx; ix++) {
08163 jx = ix -1;
08164 argx = argy + float(jx*jx)*dx2;
08165
08166 rf = sqrt(argx)*2.0f*nx2;
08167 ir = int(rf);
08168 df = rf - float(ir);
08169 f = table[ir] + df*(table[ir+1]-table[ir]);
08170
08171 (*image)(ix-1,iy-1,iz-1) *= f;
08172 }
08173 }
08174 }
08175
08176 image->update();
08177 }
08178
08179 void MirrorProcessor::process_inplace(EMData *image)
08180 {
08181 if (!image) {
08182 LOGWARN("NULL Image");
08183 return;
08184 }
08185
08186 string axis = (const char*)params["axis"];
08187
08188 float* data = image->EMData::get_data();
08189
08190 int nx = image->get_xsize();
08191 int ny = image->get_ysize();
08192 int nz = image->get_zsize();
08193 size_t nxy = nx*ny;
08194
08195 int x_start = 1-nx%2;
08196 int y_start = 1-ny%2;
08197 int z_start = 1-nz%2;
08198
08199 if (axis == "x" || axis == "X") {
08200 for (int iz = 0; iz < nz; iz++)
08201 for (int iy = 0; iy < ny; iy++) {
08202 int offset = nx*iy + nxy*iz;
08203 reverse(&data[offset+x_start],&data[offset+nx]);
08204 }
08205 }
08206
08207 if (axis == "y" || axis == "Y") {
08208 float *tmp = new float[nx];
08209 int nhalf = ny/2;
08210 size_t beg = 0;
08211 for (int iz = 0; iz < nz; iz++) {
08212 beg = iz*nxy;
08213 for (int iy = y_start; iy < nhalf; iy++) {
08214 memcpy(tmp, &data[beg+iy*nx], nx*sizeof(float));
08215 memcpy(&data[beg+iy*nx], &data[beg+(ny-iy-1+y_start)*nx], nx*sizeof(float));
08216 memcpy(&data[beg+(ny-iy-1+y_start)*nx], tmp, nx*sizeof(float));
08217 }
08218 }
08219 delete[] tmp;
08220 }
08221
08222 if (axis == "z" || axis == "Z") {
08223 if(1-z_start){
08224 int nhalf = nz/2;
08225 float *tmp = new float[nxy];
08226 for(int iz = 0;iz<nhalf;iz++){
08227 memcpy(tmp,&data[iz*nxy],nxy*sizeof(float));
08228 memcpy(&data[iz*nxy],&data[(nz-iz-1)*nxy],nxy*sizeof(float));
08229 memcpy(&data[(nz-iz-1)*nxy],tmp,nxy*sizeof(float));
08230 }
08231 delete[] tmp;
08232 }
08233 else{
08234 float *tmp = new float[nx];
08235 int nhalf = nz/2;
08236 size_t beg = 0;
08237 for (int iy = 0; iy < ny; iy++) {
08238 beg = iy*nx;
08239 for (int iz = z_start; iz < nhalf; iz++) {
08240 memcpy(tmp, &data[beg+ iz*nxy], nx*sizeof(float));
08241 memcpy(&data[beg+iz*nxy], &data[beg+(nz-iz-1+z_start)*nxy], nx*sizeof(float));
08242 memcpy(&data[beg+(nz-iz-1+z_start)*nxy], tmp, nx*sizeof(float));
08243 }
08244 }
08245 delete[] tmp;
08246 }
08247 }
08248
08249 image->update();
08250 }
08251
08252
08253 int EMAN::multi_processors(EMData * image, vector < string > processornames)
08254 {
08255 Assert(image != 0);
08256 Assert(processornames.size() > 0);
08257
08258 for (size_t i = 0; i < processornames.size(); i++) {
08259 image->process_inplace(processornames[i]);
08260 }
08261 return 0;
08262 }
08263
08264
08265 float* TransformProcessor::transform(const EMData* const image, const Transform& t) const {
08266
08267 ENTERFUNC;
08268
08269 Transform inv = t.inverse();
08270 int nx = image->get_xsize();
08271 int ny = image->get_ysize();
08272 int nz = image->get_zsize();
08273 int nxy = nx*ny;
08274
08275 const float * const src_data = image->get_const_data();
08276 float *des_data = (float *) EMUtil::em_malloc(nx*ny*nz* sizeof(float));
08277
08278 if (nz == 1) {
08279 Vec2f offset(nx/2,ny/2);
08280 for (int j = 0; j < ny; j++) {
08281 for (int i = 0; i < nx; i++) {
08282 Vec2f coord(i-nx/2,j-ny/2);
08283 Vec2f soln = inv*coord;
08284 soln += offset;
08285
08286 float x2 = soln[0];
08287 float y2 = soln[1];
08288
08289 if (x2 < 0 || x2 >= nx || y2 < 0 || y2 >= ny ) {
08290 des_data[i + j * nx] = 0;
08291
08292 }
08293 else {
08294 int ii = Util::fast_floor(x2);
08295 int jj = Util::fast_floor(y2);
08296 int k0 = ii + jj * nx;
08297 int k1 = k0 + 1;
08298 int k2 = k0 + nx;
08299 int k3 = k0 + nx + 1;
08300
08301 if (ii == nx - 1) {
08302 k1--;
08303 k3--;
08304 }
08305 if (jj == ny - 1) {
08306 k2 -= nx;
08307 k3 -= nx;
08308 }
08309
08310 float t = x2 - ii;
08311 float u = y2 - jj;
08312
08313 des_data[i + j * nx] = Util::bilinear_interpolate(src_data[k0],src_data[k1], src_data[k2], src_data[k3],t,u);
08314 }
08315 }
08316 }
08317 }
08318 else {
08319 size_t l=0, ii, k0, k1, k2, k3, k4, k5, k6, k7;
08320 Vec3f offset(nx/2,ny/2,nz/2);
08321 float x2, y2, z2, tuvx, tuvy, tuvz;
08322 int ix, iy, iz;
08323 for (int k = 0; k < nz; ++k) {
08324 for (int j = 0; j < ny; ++j) {
08325 for (int i = 0; i < nx; ++i,++l) {
08326 Vec3f coord(i-nx/2,j-ny/2,k-nz/2);
08327 Vec3f soln = inv*coord;
08328 soln += offset;
08329
08330 x2 = soln[0];
08331 y2 = soln[1];
08332 z2 = soln[2];
08333
08334 if (x2 < 0 || y2 < 0 || z2 < 0 || x2 >= nx || y2 >= ny || z2>= nz ) {
08335 des_data[l] = 0;
08336 }
08337 else {
08338 ix = Util::fast_floor(x2);
08339 iy = Util::fast_floor(y2);
08340 iz = Util::fast_floor(z2);
08341 tuvx = x2-ix;
08342 tuvy = y2-iy;
08343 tuvz = z2-iz;
08344 ii = ix + iy * nx + iz * nxy;
08345
08346 k0 = ii;
08347 k1 = k0 + 1;
08348 k2 = k0 + nx;
08349 k3 = k0 + nx+1;
08350 k4 = k0 + nxy;
08351 k5 = k1 + nxy;
08352 k6 = k2 + nxy;
08353 k7 = k3 + nxy;
08354
08355 if (ix == nx - 1) {
08356 k1--;
08357 k3--;
08358 k5--;
08359 k7--;
08360 }
08361 if (iy == ny - 1) {
08362 k2 -= nx;
08363 k3 -= nx;
08364 k6 -= nx;
08365 k7 -= nx;
08366 }
08367 if (iz == nz - 1) {
08368 k4 -= nxy;
08369 k5 -= nxy;
08370 k6 -= nxy;
08371 k7 -= nxy;
08372 }
08373
08374 des_data[l] = Util::trilinear_interpolate(src_data[k0],
08375 src_data[k1], src_data[k2], src_data[k3], src_data[k4],
08376 src_data[k5], src_data[k6], src_data[k7], tuvx, tuvy, tuvz);
08377 }
08378 }
08379 }
08380 }
08381 }
08382
08383 EXITFUNC;
08384 return des_data;
08385 }
08386
08387 void TransformProcessor::assert_valid_aspect(const EMData* const image) const {
08388 int ndim = image->get_ndim();
08389 if (ndim != 2 && ndim != 3) throw ImageDimensionException("Transforming an EMData only works if it's 2D or 3D");
08390
08391 if (! params.has_key("transform") ) throw InvalidParameterException("You must specify a Transform in order to perform this operation");
08392 }
08393
08394
08395
08396
08397
08398
08399
08400
08411
08412
08413
08414
08415
08416
08417
08418
08419
08420
08421
08422
08423
08424
08425
08426 EMData* TransformProcessor::process(const EMData* const image) {
08427 ENTERFUNC;
08428
08429 assert_valid_aspect(image);
08430
08431 Transform* t = params["transform"];
08432
08433 EMData* p = 0;
08434 #ifdef EMAN2_USING_CUDA
08435 if (image->gpu_operation_preferred()) {
08436
08437 float * m = new float[12];
08438 Transform inv = t->inverse();
08439 inv.copy_matrix_into_array(m);
08440 image->bind_cuda_texture();
08441 EMDataForCuda* tmp = emdata_transform_cuda(m,image->get_xsize(),image->get_ysize(),image->get_zsize());
08442 image->unbind_cuda_texture();
08443 delete [] m;
08444 if (tmp == 0) throw;
08445
08446 p = new EMData();
08447 p->set_gpu_rw_data(tmp->data,tmp->nx,tmp->ny,tmp->nz);
08448 free(tmp);
08449 }
08450 #endif
08451 if ( p == 0 ) {
08452 float* des_data = transform(image,*t);
08453 p = new EMData(des_data,image->get_xsize(),image->get_ysize(),image->get_zsize(),image->get_attr_dict());
08454 }
08455
08456
08457
08458 float scale = t->get_scale();
08459 if (scale != 1.0) {
08460 p->scale_pixel(1.0f/scale);
08461
08462 }
08463
08464 if(t) {delete t; t=0;}
08465 EXITFUNC;
08466 return p;
08467 }
08468
08469 void TransformProcessor::process_inplace(EMData* image) {
08470 ENTERFUNC;
08471
08472 assert_valid_aspect(image);
08473
08474 Transform* t = params["transform"];
08475
08476
08477 bool use_cpu = true;
08478 #ifdef EMAN2_USING_CUDA
08479 if (image->gpu_operation_preferred()) {
08480 use_cpu = false;
08481 float * m = new float[12];
08482 Transform inv = t->inverse();
08483 inv.copy_matrix_into_array(m);
08484 image->bind_cuda_texture();
08485 EMDataForCuda* tmp = emdata_transform_cuda(m,image->get_xsize(),image->get_ysize(),image->get_zsize());
08486 image->unbind_cuda_texture();
08487 delete [] m;
08488 if (tmp == 0) throw;
08489 image->set_gpu_rw_data(tmp->data,tmp->nx,tmp->ny,tmp->nz);
08490 free(tmp);
08491 }
08492 #endif
08493 if ( use_cpu ) {
08494 float* des_data = transform(image,*t);
08495 image->set_data(des_data,image->get_xsize(),image->get_ysize(),image->get_zsize());
08496 image->update();
08497 }
08498 float scale = t->get_scale();
08499 if (scale != 1.0) {
08500 image->scale_pixel(1.0f/scale);
08501
08502 }
08503
08504 if(t) {delete t; t=0;}
08505
08506 EXITFUNC;
08507 }
08508
08509
08510 void IntTranslateProcessor::assert_valid_aspect(const vector<int>& translation, const EMData* const image) const {
08511 if (translation.size() == 0 ) throw InvalidParameterException("You must specify the trans argument");
08512 }
08513
08514 Region IntTranslateProcessor::get_clip_region(vector<int>& translation, const EMData* const image) const {
08515 unsigned int dim = static_cast<unsigned int> (image->get_ndim());
08516
08517 if ( translation.size() != dim ) {
08518 for(unsigned int i = translation.size(); i < dim; ++i ) translation.push_back(0);
08519 }
08520
08521 Region clip_region;
08522 if (dim == 1) {
08523 clip_region = Region(-translation[0],image->get_xsize());
08524 } else if ( dim == 2 ) {
08525 clip_region = Region(-translation[0],-translation[1],image->get_xsize(),image->get_ysize());
08526 } else if ( dim == 3 ) {
08527 clip_region = Region(-translation[0],-translation[1],-translation[2],image->get_xsize(),image->get_ysize(),image->get_zsize());
08528 } else throw ImageDimensionException("Only 1,2 and 3D images are supported");
08529
08530 return clip_region;
08531 }
08532
08533 void IntTranslateProcessor::process_inplace(EMData* image) {
08534
08535 vector<int> translation = params.set_default("trans",vector<int>() );
08536
08537
08538 assert_valid_aspect(translation,image);
08539
08540 Region clip_region = get_clip_region(translation,image);
08541
08542 image->clip_inplace(clip_region,0);
08543
08544 }
08545
08546 EMData* IntTranslateProcessor::process(const EMData* const image) {
08547
08548 vector<int> translation = params.set_default("trans",vector<int>() );
08549
08550 assert_valid_aspect(translation,image);
08551
08552 Region clip_region = get_clip_region(translation,image);
08553
08554 return image->get_clip(clip_region,0);
08555
08556 }
08557
08558
08559 void ScaleTransformProcessor::process_inplace(EMData* image) {
08560 int ndim = image->get_ndim();
08561 if (ndim != 2 && ndim != 3) throw UnexpectedBehaviorException("The Scale Transform processors only works for 2D and 3D images");
08562
08563 if ( image->get_xsize() != image->get_ysize()) {
08564 throw ImageDimensionException("x size and y size of image do not match. This processor only works for uniformly sized data");
08565 }
08566 if ( ndim == 3 ) {
08567 if ( image->get_xsize() != image->get_zsize()) {
08568 throw ImageDimensionException("x size and z size of image do not match. This processor only works for uniformly sized data");
08569 }
08570 }
08571
08572 float scale = params.set_default("scale",0.0f);
08573 if (scale <= 0.0f) throw InvalidParameterException("The scale parameter must be greater than 0");
08574
08575 int clip = 0;
08576
08577 if(params.has_key("clip"))
08578 {
08579 clip = params["clip"];
08580 if (clip < 0) throw InvalidParameterException("The clip parameter must be greater than 0");
08581 }
08582 else
08583 {
08584 clip = (int)(scale*image->get_xsize());
08585 }
08586
08587 Region r;
08588 if (ndim == 3) {
08589 r = Region( (image->get_xsize()-clip)/2, (image->get_xsize()-clip)/2, (image->get_xsize()-clip)/2,clip, clip,clip);
08590 } else {
08591 r = Region( (image->get_xsize()-clip)/2, (image->get_xsize()-clip)/2, clip, clip);
08592 }
08593
08594 if (scale > 1) {
08595 if ( clip != 0) {
08596 image->clip_inplace(r);
08597 }
08598 Transform t;
08599 t.set_scale(scale);
08600 image->process_inplace("xform",Dict("transform",&t));
08601 } else if (scale < 1) {
08602 Transform t;
08603 t.set_scale(scale);
08604 image->process_inplace("xform",Dict("transform",&t));
08605 if ( clip != 0) {
08606 image->clip_inplace(r);
08607 }
08608 } else {
08609 if ( clip != 0) {
08610 image->clip_inplace(r);
08611 }
08612 }
08613 }
08614
08615 EMData* ScaleTransformProcessor::process(const EMData* const image) {
08616 int ndim = image->get_ndim();
08617 if (ndim != 2 && ndim != 3) throw UnexpectedBehaviorException("The Scale Transform processors only works for 2D and 3D images");
08618
08619 if ( image->get_xsize() != image->get_ysize()) {
08620 throw ImageDimensionException("x size and y size of image do not match. This processor only works for uniformly sized data");
08621 }
08622 if ( ndim == 3 ) {
08623 if ( image->get_xsize() != image->get_zsize()) {
08624 throw ImageDimensionException("x size and z size of image do not match. This processor only works for uniformly sized data");
08625 }
08626 }
08627
08628 float scale = params.set_default("scale",0.0f);
08629 if (scale <= 0.0f) throw InvalidParameterException("The scale parameter must be greater than 0");
08630
08631 int clip = 0;
08632
08633 if(params.has_key("clip"))
08634 {
08635 clip = params["clip"];
08636 if (clip < 0) throw InvalidParameterException("The clip parameter must be greater than 0");
08637 }
08638 else
08639 {
08640 clip = (int)(scale*image->get_xsize());
08641 }
08642
08643 Region r;
08644 if (ndim == 3) {
08645 r = Region( (image->get_xsize()-clip)/2, (image->get_xsize()-clip)/2, (image->get_xsize()-clip)/2,clip, clip,clip);
08646 } else {
08647 r = Region( (image->get_xsize()-clip)/2, (image->get_xsize()-clip)/2, clip, clip);
08648 }
08649
08650 EMData* ret = 0;
08651 if (scale > 1) {
08652 if ( clip != 0) {
08653 ret = image->get_clip(r);
08654 }
08655 Transform t;
08656 t.set_scale(scale);
08657 if (ret != 0) {
08658 ret->process_inplace("xform",Dict("transform",&t));
08659 } else {
08660 ret = image->process("xform",Dict("transform",&t));
08661 }
08662 } else if (scale < 1) {
08663 Transform t;
08664 t.set_scale(scale);
08665 ret = image->process("xform",Dict("transform",&t));
08666 if ( clip != 0) {
08667 ret->clip_inplace(r);
08668 }
08669 } else {
08670 if ( clip != 0) {
08671 ret = image->get_clip(r);
08672 } else {
08673 ret = image->copy();
08674 }
08675 }
08676 return ret;
08677
08678 }
08679
08680 void Rotate180Processor::process_inplace(EMData* image) {
08681 ENTERFUNC;
08682
08683
08684 if (image->get_ndim() != 2) {
08685 throw ImageDimensionException("2D only");
08686 }
08687
08688 #ifdef EMAN2_USING_CUDA
08689 if (image->gpu_operation_preferred() ) {
08690 EMDataForCuda tmp = image->get_data_struct_for_cuda();
08691 emdata_rotate_180(&tmp);
08692 image->gpu_update();
08693 EXITFUNC;
08694 return;
08695 }
08696 #endif
08697
08698 float *d = image->get_data();
08699 int nx = image->get_xsize();
08700 int ny = image->get_ysize();
08701
08702
08703 int x_offset = 0;
08704 if (nx % 2 == 1) x_offset=1;
08705 int y_offset = 0;
08706 if (ny % 2 == 1) y_offset=1;
08707
08708 bool stop = false;
08709 for (int x = 1; x <= (nx/2+x_offset); x++) {
08710 int y = 0;
08711 for (y = 1; y < (ny+y_offset); y++) {
08712 if (x == (nx / 2+x_offset) && y == (ny / 2+y_offset)) {
08713 stop = true;
08714 break;
08715 }
08716 int i = (x-x_offset) + (y-y_offset) * nx;
08717 int k = nx - x + (ny - y) * nx;
08718
08719 float t = d[i];
08720 d[i] = d[k];
08721 d[k] = t;
08722 }
08723 if (stop) break;
08724 }
08725
08726
08727
08728
08729
08730
08731
08732
08733 if (x_offset == 0) {
08734 for (int y = 0; y < ny; y++) {
08735 image->set_value_at_fast(0,y,image->get_value_at(1,y));
08736 }
08737 }
08738
08739 if (y_offset == 0) {
08740 for (int x = 0; x < nx; x++) {
08741 image->set_value_at_fast(x,0,image->get_value_at(x,1));
08742 }
08743 }
08744
08745 if (y_offset == 0 && x_offset == 0) {
08746 image->set_value_at_fast(0,0,image->get_value_at(1,1));
08747 }
08748
08749 image->update();
08750 EXITFUNC;
08751 }
08752
08753
08754 void ClampingProcessor::process_inplace( EMData* image )
08755 {
08756
08757 if ( image->is_complex() ) throw ImageFormatException("Error: clamping processor does not work on complex images");
08758
08759 float min = params.set_default("minval",default_min);
08760 float max = params.set_default("maxval",default_max);
08761 bool tomean = params.set_default("tomean",false);
08762 float new_min_vals = min;
08763 float new_max_vals = max;
08764 if (tomean){
08765
08766 new_min_vals = image->get_attr("mean");
08767 new_max_vals = image->get_attr("mean");
08768 }
08769
08770
08771
08772 if ( max < min ) throw InvalidParameterException("Error: minval was greater than maxval, aborting");
08773
08774 size_t size = image->get_size();
08775 for(size_t i = 0; i < size; ++i )
08776 {
08777 float * data = &image->get_data()[i];
08778 if ( *data < min ) *data = new_min_vals;
08779 else if ( *data > max ) *data = new_max_vals;
08780 }
08781 image->update();
08782 }
08783
08784 void TestTomoImage::insert_rectangle( EMData* image, const Region& region, const float& value, const Transform& t3d )
08785 {
08786 int startx = (int)region.origin[0] - (int)region.size[0]/2;
08787 int starty = (int)region.origin[1] - (int)region.size[1]/2;
08788 int startz = (int)region.origin[2] - (int)region.size[2]/2;
08789
08790 int endx = (int)region.origin[0] + (int)region.size[0]/2;
08791 int endy = (int)region.origin[1] + (int)region.size[1]/2;
08792 int endz = (int)region.origin[2] + (int)region.size[2]/2;
08793
08794 if ( ! t3d.is_identity() ) {
08795 float xt, yt, zt;
08796 for ( float z = (float)startz; z < (float)endz; z += 0.25f ) {
08797 for ( float y = (float)starty; y < (float)endy; y += 0.25f ) {
08798 for ( float x = (float)startx; x < (float)endx; x += 0.25f ) {
08799 xt = (float) x - region.origin[0];
08800 yt = (float) y - region.origin[1];
08801 zt = (float) z - region.origin[2];
08802 Vec3f v((float)xt,(float)yt,(float)zt);
08803 v = t3d*v;
08804 image->set_value_at((int)(v[0]+region.origin[0]),(int)(v[1]+region.origin[1]),(int)(v[2]+region.origin[2]), value);
08805 }
08806 }
08807 }
08808 } else {
08809 for ( int z = startz; z < endz; ++z ) {
08810 for ( int y = starty; y < endy; ++y ) {
08811 for ( int x = startx; x < endx; ++x ) {
08812 image->set_value_at(x,y,z, value);
08813 }
08814 }
08815 }
08816 }
08817 }
08818
08819 void TestTomoImage::process_inplace( EMData* image )
08820 {
08821
08822
08823
08824
08825
08826 float nx = (float) image->get_xsize();
08827 float ny = (float) image->get_ysize();
08828 float nz = (float) image->get_zsize();
08829
08830
08831
08832
08833 float inc = 1.0f/22.0f;
08834 float xinc = inc;
08835 float yinc = inc;
08836 float zinc = inc;
08837
08838 Dict d;
08839 d["a"] = (float) .4*nx+3;
08840 d["b"] = (float) .4*ny+3;
08841 d["c"] = (float) .4*nz+3;
08842 d["fill"] = 0.2;
08843 image->process_inplace("testimage.ellipsoid",d);
08844
08845 d["a"] = (float) .4*nx;
08846 d["b"] = (float) .4*ny;
08847 d["c"] = (float) .4*nz;
08848 d["fill"] = 0.1;
08849 image->process_inplace("testimage.ellipsoid",d);
08850
08851
08852 {
08853 Transform t;
08854 t.set_trans(0.,ny*4.0f*yinc-ny/2,0);
08855 Dict d;
08856 d["transform"] = &t;
08857 d["a"] = (float) 2.*xinc*nx;
08858 d["b"] = (float)0.5*yinc*ny;
08859 d["c"] = (float) 1.*zinc*nz;
08860 d["fill"] = 0.3;
08861 image->process_inplace("testimage.ellipsoid",d);
08862 }
08863
08864 {
08865 Transform t;
08866 t.set_trans(0.,ny*5.5f*yinc-ny/2,0);
08867 Dict d;
08868 d["transform"] = &t;
08869 d["a"] = (float) 1.5*xinc*nx;
08870 d["b"] = (float)0.5*yinc*ny;
08871 d["c"] = (float) 1.*zinc*nz;
08872 d["fill"] = 0.0;
08873 image->process_inplace("testimage.ellipsoid",d);
08874 }
08875 {
08876 Transform t;
08877 t.set_trans(0.,ny*7*yinc-ny/2,0);
08878 Dict d;
08879 d["transform"] = &t;
08880 d["a"] = (float) 1.*xinc*nx;
08881 d["b"] = (float)0.5*yinc*ny;
08882 d["c"] = (float) 1.*zinc*nz;
08883 d["fill"] = 0.3;
08884 image->process_inplace("testimage.ellipsoid",d);
08885 }
08886
08887
08888 {
08889 Transform t;
08890 t.set_trans(0.,ny*8.5f*yinc-ny/2,0);
08891 Dict d;
08892 d["transform"] = &t;
08893 d["a"] = (float) .75*xinc*nx;
08894 d["b"] = (float)0.5*yinc*ny;
08895 d["c"] = (float) 1.*zinc*nz;
08896 d["fill"] = 0.0;
08897 image->process_inplace("testimage.ellipsoid",d);
08898 }
08899
08900
08901 {
08902 Transform t;
08903 t.set_trans(0.,ny*18*yinc-ny/2,0);
08904 Dict d;
08905 d["transform"] = &t;
08906 d["a"] = (float) 2*xinc*nx;
08907 d["b"] = (float)0.5*yinc*ny;
08908 d["c"] = (float) 1.*zinc*nz;
08909 d["fill"] = 0.3;
08910 image->process_inplace("testimage.ellipsoid",d);
08911 }
08912
08913 {
08914 Transform t;
08915 t.set_trans(0.,ny*16.5f*yinc-ny/2,0);
08916 Dict d;
08917 d["transform"] = &t;
08918 d["a"] = (float) 1.5*xinc*nx;
08919 d["b"] = (float)0.5*yinc*ny;
08920 d["c"] = (float) 1.*zinc*nz;
08921 d["fill"] = 0.3;
08922 image->process_inplace("testimage.ellipsoid",d);
08923 }
08924
08925 {
08926 Transform t;
08927 t.set_trans(0.,ny*15*yinc-ny/2,0);
08928 Dict d;
08929 d["transform"] = &t;
08930 d["a"] = (float) 1*xinc*nx;
08931 d["b"] = (float)0.5*yinc*ny;
08932 d["c"] = (float) 1.*zinc*nz;
08933 d["fill"] = 0.3f;
08934 image->process_inplace("testimage.ellipsoid",d);
08935 }
08936
08937 {
08938 Transform t;
08939 t.set_trans(0.,ny*13.5f*yinc-ny/2,0);
08940 Dict d;
08941 d["transform"] = &t;
08942 d["a"] = (float).75*xinc*nx;
08943 d["b"] = (float)0.5*yinc*ny;
08944 d["c"] = (float) 1.*zinc*nz;
08945 d["fill"] = 0.3;
08946 image->process_inplace("testimage.ellipsoid",d);
08947 }
08948
08949
08950 {
08951
08952 Transform t;
08953 t.set_trans(nx*6*xinc-nx/2,ny*5*yinc-ny/2,0);
08954 Dict d;
08955 d["transform"] = &t;
08956 d["a"] = (float)1*xinc*nx;
08957 d["b"] = (float).75*yinc*ny;
08958 d["c"] = (float) .75*zinc*nz;
08959 d["fill"] = 0.25;
08960 image->process_inplace("testimage.ellipsoid",d);
08961 }
08962
08963 {
08964 Transform t;
08965 t.set_trans(nx*6*xinc-nx/2,ny*7*yinc-ny/2,0);
08966 Dict d;
08967 d["transform"] = &t;
08968 d["a"] = (float)1.5*xinc*nx;
08969 d["b"] = (float).75*yinc*ny;
08970 d["c"] = (float) .75*zinc*nz;
08971 d["fill"] = 0.25;
08972 image->process_inplace("testimage.ellipsoid",d);
08973 }
08974
08975 {
08976 Transform t;
08977 t.set_trans(nx*6*xinc-nx/2,ny*9*yinc-ny/2,0);
08978 Dict d;
08979 d["transform"] = &t;
08980 d["a"] = (float)2*xinc*nx;
08981 d["b"] = (float).75*yinc*ny;
08982 d["c"] = (float) .75*zinc*nz;
08983 d["fill"] = 0.25;
08984 image->process_inplace("testimage.ellipsoid",d);
08985 }
08986
08987 {
08988 Transform t;
08989 t.set_trans(nx*6*xinc-nx/2,ny*11*yinc-ny/2,0);
08990 Dict d;
08991 d["transform"] = &t;
08992 d["a"] = (float)2.5*xinc*nx;
08993 d["b"] = (float).75*yinc*ny;
08994 d["c"] = (float) 1*zinc*nz;
08995 d["fill"] = 0.25;
08996 image->process_inplace("testimage.ellipsoid",d);
08997 }
08998
08999 {
09000 Transform t;
09001 t.set_trans(nx*6*xinc-nx/2,ny*13*yinc-ny/2,0);
09002 Dict d;
09003 d["transform"] = &t;
09004 d["a"] = (float) 3*xinc*nx;
09005 d["b"] = (float).75*yinc*ny;
09006 d["c"] = (float) 1*zinc*nz;
09007 d["fill"] = 0.25;
09008 image->process_inplace("testimage.ellipsoid",d);
09009 }
09010
09011
09012 {
09013 Region region(nx*15.*inc,ny*17.*inc,nz/2.,1.*inc*nx,1.5*inc*ny,1.5*inc*nz);
09014 insert_rectangle(image, region, 0.25);
09015 }
09016 {
09017 Region region(nx*15.*inc,ny*15.*inc,nz/2.,1.5*inc*nx,1.5*inc*ny,1.5*inc*nz);
09018 insert_rectangle(image, region, 0.25);
09019 }
09020 {
09021 Region region(nx*15.*inc,ny*13.*inc,nz/2.,2.*inc*nx,1.5*inc*ny,1.5*inc*nz);
09022 insert_rectangle(image, region, 0.25);
09023 }
09024 {
09025 Region region(nx*15.*inc,ny*11.*inc,nz/2.,2.5*inc*nx,1.5*inc*ny,1.5*inc*nz);
09026 insert_rectangle(image, region, 0.25);
09027 }
09028 {
09029 Region region(nx*15.*inc,ny*9.*inc,nz/2.,3.*inc*nx,1.5*inc*ny,1.5*inc*nz);
09030 insert_rectangle(image, region, 0.25);
09031 }
09032
09033
09034 {
09035 Region region(nx/2.,ny/2.,nz/2.,2.*inc*nx,2.5*inc*ny,1.*inc*nz);
09036 Transform t3d(Dict("type","eman","az",(float)-25.0));
09037 insert_rectangle(image, region, 0.4f, t3d);
09038 }
09039
09040
09041 {
09042 Transform t;
09043 t.set_trans(nx*6.8f*xinc-nx/2,ny*16*yinc-ny/2,0);
09044 Dict rot;
09045 rot["type"] = "eman";
09046 rot["az"] = 43.0f;
09047 t.set_rotation(rot);
09048 Dict d;
09049 d["transform"] = &t;
09050 d["a"] = (float) 1.5*xinc*nx;
09051 d["b"] = (float) .5*yinc*ny;
09052 d["c"] = (float) .5*zinc*nz;
09053 d["fill"] = 0.2;
09054 image->process_inplace("testimage.ellipsoid",d);
09055 }
09056 {
09057 Transform t;
09058 t.set_trans(nx*7.2f*xinc-nx/2,ny*16*yinc-ny/2,0);
09059 Dict rot;
09060 rot["type"] = "eman";
09061 rot["az"] = 135.0f;
09062 t.set_rotation(rot);
09063 Dict d;
09064 d["transform"] = &t;
09065 d["a"] = (float) 1.5*xinc*nx;
09066 d["b"] = (float) .5*yinc*ny;
09067 d["c"] = (float) .5*zinc*nz;
09068 d["fill"] = 0.3;
09069 image->process_inplace("testimage.ellipsoid",d);
09070 }
09071
09072
09073 {
09074 Transform t;
09075 t.set_trans(nx*3.5f*xinc-nx/2,ny*8*yinc-ny/2,0);
09076 Dict d;
09077 d["transform"] = &t;
09078 d["a"] = (float) .5*xinc*nx;
09079 d["b"] = (float) .5*yinc*ny;
09080 d["c"] = (float) .5*zinc*nz;
09081 d["fill"] = 2.05;
09082 image->process_inplace("testimage.ellipsoid",d);
09083
09084 t.set_trans(nx*8*xinc-nx/2,ny*18*yinc-ny/2,0);
09085 image->process_inplace("testimage.ellipsoid",d);
09086
09087 t.set_trans(nx*14*xinc-nx/2,ny*18.2f*yinc-ny/2,0);
09088 image->process_inplace("testimage.ellipsoid",d);
09089
09090 t.set_trans(nx*18*xinc-nx/2,ny*14*yinc-ny/2,0);
09091 image->process_inplace("testimage.ellipsoid",d);
09092
09093 t.set_trans(nx*17*xinc-nx/2,ny*7.5f*yinc-ny/2,0);
09094 image->process_inplace("testimage.ellipsoid",d);
09095 }
09096
09097
09098
09099 {
09100 Region region(nx*18.*inc,ny*11.5*inc,nz/2.,1.*inc*nx,1.*inc*ny,1.*inc*nz);
09101 Transform t3d(Dict("type","eman","az",(float)45.0));
09102 insert_rectangle(image, region, 1.45f, t3d);
09103 }
09104 {
09105 Region region(nx*3.*inc,ny*10.5*inc,nz/2.,1.*inc*nx,1.*inc*ny,1.*inc*nz);
09106 Transform t3d(Dict("type","eman","az",(float)45.0));
09107 insert_rectangle(image, region, 1.45f, t3d);
09108 }
09109
09110
09111 {
09112 Transform t;
09113 t.set_trans(nx*14*xinc-nx/2,ny*7.5f*yinc-ny/2,0);
09114 Dict d;
09115 d["transform"] = &t;
09116 d["a"] = (float) .5*xinc*nx;
09117 d["b"] = (float) .5*yinc*ny;
09118 d["c"] = (float) .5*zinc*nz;
09119 d["fill"] = .35;
09120 image->process_inplace("testimage.ellipsoid",d);
09121 }
09122 {
09123 Transform t;
09124 t.set_trans(nx*15*xinc-nx/2,ny*7.5f*yinc-ny/2,0);
09125 Dict d;
09126 d["transform"] = &t;
09127 d["a"] = (float) .25*xinc*nx;
09128 d["b"] = (float) .25*yinc*ny;
09129 d["c"] = (float) .25*zinc*nz;
09130 d["fill"] = .35;
09131 image->process_inplace("testimage.ellipsoid",d);
09132
09133 t.set_trans(nx*13.5f*xinc-nx/2,ny*6.5f*yinc-ny/2,0);
09134 image->process_inplace("testimage.ellipsoid",d);
09135
09136 t.set_trans(nx*14.5f*xinc-nx/2,ny*6.5f*yinc-ny/2,0);
09137 image->process_inplace("testimage.ellipsoid",d);
09138
09139 t.set_trans(nx*15.5f*xinc-nx/2,ny*6.5f*yinc-ny/2,0);
09140 image->process_inplace("testimage.ellipsoid",d);
09141
09142 t.set_trans(nx*14*xinc-nx/2,ny*5.5f*yinc-ny/2,0);
09143 image->process_inplace("testimage.ellipsoid",d);
09144
09145 t.set_trans(nx*14*xinc-nx/2,ny*5.5f*yinc-ny/2,0);
09146 image->process_inplace("testimage.ellipsoid",d);
09147
09148 t.set_trans(nx*15*xinc-nx/2,ny*5.5f*yinc-ny/2,0);
09149 image->process_inplace("testimage.ellipsoid",d);
09150
09151 t.set_trans(nx*16*xinc-nx/2,ny*5.5f*yinc-ny/2,0);
09152 image->process_inplace("testimage.ellipsoid",d);
09153
09154 t.set_trans(nx*14.5f*xinc-nx/2,ny*4.5f*yinc-ny/2,0);
09155 image->process_inplace("testimage.ellipsoid",d);
09156
09157 t.set_trans(nx*15.5f*xinc-nx/2,ny*4.5f*yinc-ny/2,0);
09158 image->process_inplace("testimage.ellipsoid",d);
09159 }
09160
09161
09162
09163
09164
09165
09166
09167
09168 }
09169
09170 void NSigmaClampingProcessor::process_inplace(EMData *image)
09171 {
09172 float nsigma = params.set_default("nsigma",default_sigma);
09173 float sigma = image->get_attr("sigma");
09174 float mean = image->get_attr("mean");
09175 params.set_default("minval",mean - nsigma*sigma);
09176 params.set_default("maxval",mean + nsigma*sigma);
09177
09178 ClampingProcessor::process_inplace(image);
09179 }
09180
09181 void HistogramBin::process_inplace(EMData *image)
09182 {
09183 float min = image->get_attr("minimum");
09184 float max = image->get_attr("maximum");
09185 float nbins = (float)params.set_default("nbins",default_bins);
09186 bool debug = params.set_default("debug",false);
09187
09188 vector<int> debugscores;
09189 if ( debug ) {
09190 debugscores = vector<int>((int)nbins, 0);
09191 }
09192
09193 if ( nbins < 0 ) throw InvalidParameterException("nbins must be greater than 0");
09194
09195 float bin_width = (max-min)/nbins;
09196 float bin_val_offset = bin_width/2.0f;
09197
09198 size_t size = image->get_size();
09199 float* dat = image->get_data();
09200
09201 for(size_t i = 0; i < size; ++i ) {
09202 float val = dat[i];
09203 val -= min;
09204 int bin = (int) (val/bin_width);
09205
09206
09207 if (bin == nbins) bin -= 1;
09208
09209 dat[i] = min + bin*bin_width + bin_val_offset;
09210 if ( debug ) {
09211 debugscores[bin]++;
09212 }
09213 }
09214
09215 if ( debug ) {
09216 int i = 0;
09217 for( vector<int>::const_iterator it = debugscores.begin(); it != debugscores.end(); ++it, ++i)
09218 cout << "Bin " << i << " has " << *it << " pixels in it" << endl;
09219 }
09220
09221 }
09222 void ConvolutionProcessor::process_inplace(EMData* image)
09223 {
09224
09225 EMData* null = 0;
09226 EMData* with = params.set_default("with", null);
09227 if ( with == NULL ) throw InvalidParameterException("Error - the image required for the convolution is null");
09228
09229 EMData* newimage = fourierproduct(image, with, CIRCULANT, CONVOLUTION, false);
09230
09231 float* orig = image->get_data();
09232 float* work = newimage->get_data();
09233 int nx = image->get_xsize();
09234 int ny = image->get_ysize();
09235 int nz = image->get_zsize();
09236 memcpy(orig,work,nx*ny*nz*sizeof(float));
09237 image->update();
09238
09239 delete newimage;
09240 }
09241
09242 void XGradientProcessor::process_inplace( EMData* image )
09243 {
09244 if (image->is_complex()) throw ImageFormatException("Cannot edge detect a complex image");
09245
09246 EMData* e = new EMData();
09247 int nx = image->get_xsize();
09248 int ny = image->get_ysize();
09249 int nz = image->get_zsize();
09250
09251 if ( nz == 1 && ny == 1 ) {
09252 if ( nx < 3 ) throw ImageDimensionException("Error - cannot edge detect an image with less than three pixels");
09253
09254 e->set_size(3,1,1);
09255 e->set_value_at(0,-1);
09256 e->set_value_at(2, 1);
09257
09258 Region r = Region(-nx/2+1,nx);
09259 e->clip_inplace(r);
09260 } else if ( nz == 1 ) {
09261 if ( nx < 3 || ny < 3 ) throw ImageDimensionException("Error - cannot edge detect an image with less than three pixels");
09262 e->set_size(3,3,1);
09263 e->set_value_at(0,0,-1);
09264 e->set_value_at(0,1,-2);
09265 e->set_value_at(0,2,-1);
09266
09267 e->set_value_at(2,0,1);
09268 e->set_value_at(2,1,2);
09269 e->set_value_at(2,2,1);
09270 Region r = Region(-nx/2+1,-ny/2+1,nx,ny);
09271 e->clip_inplace(r);
09272 } else {
09273 if ( nx < 3 || ny < 3 || nz < 3) throw ImageDimensionException("Error - cannot edge detect an image with less than three pixels");
09274 e->set_size(3,3,3);
09275 e->set_value_at(0,0,0,-1);
09276 e->set_value_at(0,1,0,-1);
09277 e->set_value_at(0,2,0,-1);
09278 e->set_value_at(0,0,1,-1);
09279 e->set_value_at(0,1,1,-8);
09280 e->set_value_at(0,2,1,-1);
09281 e->set_value_at(0,0,2,-1);
09282 e->set_value_at(0,1,2,-1);
09283 e->set_value_at(0,2,2,-1);
09284
09285 e->set_value_at(2,0,0,1);
09286 e->set_value_at(2,1,0,1);
09287 e->set_value_at(2,2,0,1);
09288 e->set_value_at(2,0,1,1);
09289 e->set_value_at(2,1,1,8);
09290 e->set_value_at(2,2,1,1);
09291 e->set_value_at(2,0,2,1);
09292 e->set_value_at(2,1,2,1);
09293 e->set_value_at(2,2,2,1);
09294
09295 Region r = Region(-nx/2+1,-ny/2+1,-nz/2+1,nx,ny,nz);
09296 e->clip_inplace(r);
09297 }
09298
09299 Dict conv_parms;
09300 conv_parms["with"] = e;
09301 image->process_inplace("math.convolution", conv_parms);
09302 image->process_inplace("xform.phaseorigin.tocenter");
09303
09304 delete e;
09305 }
09306
09307
09308 void TomoTiltAngleWeightProcessor::process_inplace( EMData* image )
09309 {
09310 bool fim = params.set_default("angle_fim", false);
09311 float alt;
09312 if ( fim ) {
09313 alt = image->get_attr("euler_alt");
09314 }
09315 else alt = params.set_default("angle", 0.0f);
09316
09317 float cosine = cos(alt*M_PI/180.0f);
09318 float mult_fac = 1.0f/(cosine);
09319 image->mult( mult_fac );
09320 }
09321
09322 void TomoTiltEdgeMaskProcessor::process_inplace( EMData* image )
09323 {
09324 bool biedgemean = params.set_default("biedgemean", false);
09325 bool edgemean = params.set_default("edgemean", false);
09326
09327 if (biedgemean && edgemean) throw InvalidParameterException("The edgemean and biedgemean options are mutually exclusive");
09328
09329 bool fim = params.set_default("angle_fim", false);
09330 float alt;
09331 if ( fim ) {
09332 Transform* t = (Transform*)image->get_attr("xform.projection");
09333 Dict d = t->get_params("eman");
09334 alt = (float) d["alt"];
09335 if(t) {delete t; t=0;}
09336 }
09337 else alt = params.set_default("angle", 0.0f);
09338
09339
09340 float cosine = cos(alt*M_PI/180.0f);
09341
09342
09343 int nx = image->get_xsize();
09344 int ny = image->get_ysize();
09345 int x_clip = static_cast<int>( (float) nx * ( 1.0 - cosine ) / 2.0);
09346
09347 float x1_edge_mean = 0.0;
09348 float x2_edge_mean = 0.0;
09349
09350 if ( biedgemean )
09351 {
09352 float edge_mean = 0.0;
09353
09354
09355 for ( int i = 0; i < ny; ++i ) {
09356 edge_mean += image->get_value_at(x_clip, i );
09357 edge_mean += image->get_value_at(nx - x_clip-1, i );
09358 }
09359
09360 edge_mean /= 2*ny;
09361
09362
09363 for ( int i = 0; i < ny; ++i ) {
09364 for ( int j = nx-1; j >= nx - x_clip; --j) {
09365 image->set_value_at(j,i,edge_mean);
09366 }
09367 for ( int j = 0; j < x_clip; ++j) {
09368 image->set_value_at(j,i,edge_mean);
09369 }
09370 }
09371 x1_edge_mean = edge_mean;
09372 x2_edge_mean = edge_mean;
09373 }
09374 else if (edgemean)
09375 {
09376 for ( int i = 0; i < ny; ++i ) {
09377 x1_edge_mean += image->get_value_at(x_clip, i );
09378 x2_edge_mean += image->get_value_at(nx - x_clip-1, i );
09379 }
09380 x1_edge_mean /= ny;
09381 x2_edge_mean /= ny;
09382
09383 for ( int i = 0; i < ny; ++i ) {
09384 for ( int j = 0; j < x_clip; ++j) {
09385 image->set_value_at(j,i,x1_edge_mean);
09386 }
09387 for ( int j = nx-1; j >= nx - x_clip; --j) {
09388 image->set_value_at(j,i,x2_edge_mean);
09389 }
09390 }
09391 }
09392 else
09393 {
09394
09395 Dict zero_dict;
09396 zero_dict["x0"] = x_clip;
09397 zero_dict["x1"] = x_clip;
09398 zero_dict["y0"] = 0;
09399 zero_dict["y1"] = 0;
09400 image->process_inplace( "mask.zeroedge2d", zero_dict );
09401 }
09402
09403 int gauss_rad = params.set_default("gauss_falloff", 0);
09404 if ( gauss_rad != 0)
09405 {
09406
09407
09408
09409 if ( gauss_rad > x_clip ) gauss_rad = x_clip;
09410
09411 float gauss_sigma = params.set_default("gauss_sigma", 3.0f);
09412 if ( gauss_sigma < 0 ) throw InvalidParameterException("Error - you must specify a positive, non-zero gauss_sigma");
09413 float sigma = (float) gauss_rad/gauss_sigma;
09414
09415 GaussianFunctoid gf(sigma);
09416
09417 for ( int i = 0; i < ny; ++i ) {
09418
09419 float left_value = image->get_value_at(x_clip, i );
09420 float scale1 = left_value-x1_edge_mean;
09421
09422 float right_value = image->get_value_at(nx - x_clip - 1, i );
09423 float scale2 = right_value-x2_edge_mean;
09424
09425 for ( int j = 1; j < gauss_rad; ++j )
09426 {
09427 image->set_value_at(x_clip-j, i, scale1*gf((float)j)+x1_edge_mean );
09428 image->set_value_at(nx - x_clip + j-1, i, scale2*gf((float)j)+x2_edge_mean);
09429 }
09430 }
09431 }
09432
09433 image->update();
09434 }
09435
09436 void YGradientProcessor::process_inplace( EMData* image )
09437 {
09438 if (image->is_complex()) throw ImageFormatException("Cannot edge detect a complex image");
09439
09440 EMData* e = new EMData();
09441 int nx = image->get_xsize();
09442 int ny = image->get_ysize();
09443 int nz = image->get_zsize();
09444
09445 if ( nz == 1 && ny == 1 ) {
09446 throw ImageDimensionException("Error - cannot detect Y edges for an image that that is 1D!");
09447 } else if ( nz == 1 ) {
09448 if ( nx < 3 || ny < 3 ) throw ImageDimensionException("Error - cannot edge detect an image with less than three pixels");
09449 e->set_size(3,3,1);
09450 e->set_value_at(0,0,-1);
09451 e->set_value_at(1,0,-2);
09452 e->set_value_at(2,0,-1);
09453
09454 e->set_value_at(0,2,1);
09455 e->set_value_at(1,2,2);
09456 e->set_value_at(2,2,1);
09457 Region r = Region(-nx/2+1,-ny/2+1,nx,ny);
09458 e->clip_inplace(r);
09459 } else {
09460 if ( nx < 3 || ny < 3 || nz < 3) throw ImageDimensionException("Error - cannot edge detect an image with less than three pixels");
09461 e->set_size(3,3,3);
09462 e->set_value_at(0,0,0,-1);
09463 e->set_value_at(1,0,0,-1);
09464 e->set_value_at(2,0,0,-1);
09465 e->set_value_at(0,0,1,-1);
09466 e->set_value_at(1,0,1,-8);
09467 e->set_value_at(2,0,1,-1);
09468 e->set_value_at(0,0,2,-1);
09469 e->set_value_at(1,0,2,-1);
09470 e->set_value_at(2,0,2,-1);
09471
09472 e->set_value_at(0,2,0,1);
09473 e->set_value_at(1,2,0,1);
09474 e->set_value_at(2,2,0,1);
09475 e->set_value_at(0,2,1,1);
09476 e->set_value_at(1,2,1,8);
09477 e->set_value_at(2,2,1,1);
09478 e->set_value_at(0,2,2,1);
09479 e->set_value_at(1,2,2,1);
09480 e->set_value_at(2,2,2,1);
09481
09482 Region r = Region(-nx/2+1,-ny/2+1,-nz/2+1,nx,ny,nz);
09483 e->clip_inplace(r);
09484 }
09485
09486 Dict conv_parms;
09487 conv_parms["with"] = e;
09488 image->process_inplace("math.convolution", conv_parms);
09489
09490 delete e;
09491 }
09492
09493
09494 void ZGradientProcessor::process_inplace( EMData* image )
09495 {
09496 if (image->is_complex()) throw ImageFormatException("Cannot edge detect a complex image");
09497
09498 EMData* e = new EMData();
09499 int nx = image->get_xsize();
09500 int ny = image->get_ysize();
09501 int nz = image->get_zsize();
09502
09503 if ( nx < 3 || ny < 3 || nz < 3) throw ImageDimensionException("Error - cannot edge detect in the z direction with any dimension being less than three pixels");
09504
09505 e->set_size(3,3,3);
09506 e->set_value_at(0,0,0,-1);
09507 e->set_value_at(1,0,0,-1);
09508 e->set_value_at(2,0,0,-1);
09509 e->set_value_at(0,1,0,-1);
09510 e->set_value_at(1,1,0,-8);
09511 e->set_value_at(2,1,0,-1);
09512 e->set_value_at(0,2,0,-1);
09513 e->set_value_at(1,2,0,-1);
09514 e->set_value_at(2,2,0,-1);
09515
09516 e->set_value_at(0,0,2,1);
09517 e->set_value_at(1,0,2,1);
09518 e->set_value_at(2,0,2,1);
09519 e->set_value_at(0,1,2,1);
09520 e->set_value_at(1,1,2,8);
09521 e->set_value_at(2,1,2,1);
09522 e->set_value_at(0,2,2,1);
09523 e->set_value_at(1,2,2,1);
09524 e->set_value_at(2,2,2,1);
09525
09526 Region r = Region(-nx/2+1,-ny/2+1,-nz/2+1,nx,ny,nz);
09527 e->clip_inplace(r);
09528
09529 Dict conv_parms;
09530 conv_parms["with"] = e;
09531 image->process_inplace("math.convolution", conv_parms);
09532
09533 delete e;
09534 }
09535
09536
09537 #ifdef EMAN2_USING_CUDA
09538
09539
09540
09541
09542 #include "sparx/cuda/cuda_mpi_kmeans.h"
09543 MPICUDA_kmeans::MPICUDA_kmeans() {
09544 h_IM = NULL;
09545 h_AVE = NULL;
09546 h_ASG = NULL;
09547 h_dist = NULL;
09548 h_AVE2 = NULL;
09549 h_im2 = NULL;
09550 h_NC = NULL;
09551 params = NULL;
09552 d_im = NULL;
09553 d_AVE = NULL;
09554 d_dist = NULL;
09555 }
09556
09557 MPICUDA_kmeans::~MPICUDA_kmeans() {
09558 if (h_IM) delete h_IM;
09559 if (h_ASG) delete h_ASG;
09560 if (h_AVE) delete h_AVE;
09561 if (h_dist) delete h_dist;
09562 if (h_AVE2) delete h_AVE2;
09563 if (h_im2) delete h_im2;
09564 if (h_NC) delete h_NC;
09565 if (params) delete params;
09566 }
09567
09568 #include "sparx/cuda/cuda_mpi_kmeans.h"
09569 int MPICUDA_kmeans::setup(int extm, int extN, int extn, int extK, int extn_start) {
09570 m = extm;
09571 N = extN;
09572 n = extn;
09573 K = extK;
09574 n_start = extn_start;
09575 size_IM = m * N;
09576 size_im = m * n;
09577 size_AVE = m * K;
09578 size_dist = n * K;
09579 ite = 0;
09580 BLOCK_SIZE = 512;
09581 NB = size_dist / BLOCK_SIZE;
09582 ins_BLOCK = NB * BLOCK_SIZE;
09583
09584 h_IM = (float*)malloc(size_IM * sizeof(float));
09585 if (h_IM == 0) return 1;
09586 h_im = &h_IM[n_start * m];
09587
09588 h_AVE = (float*)malloc(size_AVE * sizeof(float));
09589 if (h_AVE == 0) return 1;
09590
09591 h_ASG = (unsigned short int*)malloc(N * sizeof(unsigned short int));
09592 if (h_ASG == 0) return 1;
09593 h_asg = &h_ASG[n_start];
09594
09595 h_AVE2 = (float*)malloc(K * sizeof(float));
09596 if (h_AVE2 == 0) return 1;
09597
09598 h_im2 = (float*)malloc(n * sizeof(float));
09599 if (h_im2 == 0) return 1;
09600
09601 h_dist = (float*)malloc(size_dist * sizeof(float));
09602 if (h_dist == 0) return 1;
09603
09604 h_NC = (unsigned int*)malloc(K * sizeof(unsigned int));
09605 if (h_NC == 0) return 1;
09606
09607 params = (int*)malloc(8 * sizeof(int));
09608 if (params == 0) return 1;
09609 params[0] = n;
09610 params[1] = m;
09611 params[2] = K;
09612 params[3] = 0;
09613 params[4] = 0;
09614 params[5] = BLOCK_SIZE;
09615 params[6] = NB;
09616 params[7] = ins_BLOCK;
09617
09618 return 0;
09619 }
09620
09621
09622 void MPICUDA_kmeans::append_flat_image(EMData* im, int pos) {
09623 for (int i = 0; i < m ; ++i) h_IM[pos * m + i] = (*im)(i);
09624 }
09625
09626
09627 int MPICUDA_kmeans::init_mem(int numdev) {
09628 int stat = 1;
09629 float** hd_AVE = NULL;
09630 float** hd_im = NULL;
09631 float** hd_dist = NULL;
09632 hd_AVE = &d_AVE;
09633 hd_im = &d_im;
09634 hd_dist = &d_dist;
09635 stat = cuda_mpi_init(h_im, hd_im, hd_AVE, hd_dist, size_im, size_AVE, size_dist, numdev);
09636
09637
09638
09639 return stat;
09640 }
09641
09642
09643 void MPICUDA_kmeans::compute_im2() {
09644 for (int i = 0; i < n; i++) {
09645 h_im2[i] = 0.0f;
09646 for (int j = 0; j < m; j++) h_im2[i] += (h_im[i * m + j] * h_im[i * m + j]);
09647 }
09648 }
09649
09650
09651 int MPICUDA_kmeans::random_ASG(long int rnd) {
09652 srand(rnd);
09653 int ret = 20;
09654 int flag = 0;
09655 int i, k;
09656 for (k = 0; k < K; k++) h_NC[k] = 0;
09657 while (ret > 0) {
09658 ret--;
09659 for (i = 0; i < N; i++) {
09660 h_ASG[i] = rand() % K;
09661 h_NC[h_ASG[i]]++;
09662 }
09663 flag = 1;
09664 k = K;
09665 while (k > 0 && flag) {
09666 k--;
09667 if (h_NC[k] <= 1) {
09668 flag = 0;
09669 if (ret == 0) {
09670
09671 return -1;
09672 }
09673 for (k = 0; k < K; k++) h_NC[k] = 0;
09674 }
09675 if (flag == 1) ret = 0;
09676 }
09677 }
09678 return 0;
09679 }
09680
09681
09682 vector <int> MPICUDA_kmeans::get_ASG() {
09683 vector <int> ASG(h_ASG, &h_ASG[N]);
09684 return ASG;
09685 }
09686
09687
09688 vector <int> MPICUDA_kmeans::get_asg() {
09689 vector <int> asg(h_asg, &h_asg[n]);
09690 return asg;
09691 }
09692
09693
09694 void MPICUDA_kmeans::compute_NC() {
09695 for (int i = 0; i < K; ++i) h_NC[i] = 0;
09696 for (int i = 0; i < N; ++i) h_NC[h_ASG[i]]++;
09697 }
09698
09699
09700 vector <int> MPICUDA_kmeans::get_NC() {
09701 vector <int> NC(h_NC, &h_NC[K]);
09702 return NC;
09703 }
09704
09705
09706 void MPICUDA_kmeans::set_ASG(const vector <int>& ASG) {
09707 for (int i = 0; i < N ; ++i) h_ASG[i] = ASG[i];
09708 }
09709
09710
09711 void MPICUDA_kmeans::set_NC(const vector <int>& NC) {
09712 for (int i = 0; i < K; ++i) h_NC[i] = NC[i];
09713 }
09714
09715
09716 int MPICUDA_kmeans::get_ct_im_mv() {
09717 return params[4];
09718 }
09719
09720
09721 void MPICUDA_kmeans::set_T(float extT) {
09722 T = extT;
09723 }
09724
09725
09726 float MPICUDA_kmeans::get_T() {
09727 return T;
09728 }
09729
09730
09731 void MPICUDA_kmeans::compute_AVE() {
09732 float buf = 0.0f;
09733 int i, j, c, d, ind;
09734
09735 for (i = 0; i < size_AVE; ++i) h_AVE[i] = 0.0f;
09736 for (i = 0; i < N; ++i) {
09737 c = h_ASG[i] * m;
09738 d = i * m;
09739 for (j = 0; j < m; ++j) h_AVE[c + j] += h_IM[d + j];
09740 }
09741 for (i = 0; i < K; i++) {
09742 buf = 0.0f;
09743 for (j = 0 ; j < m; j++) {
09744 ind = i * m + j;
09745 h_AVE[ind] /= (float)h_NC[i];
09746 buf += (h_AVE[ind] * h_AVE[ind]);
09747 }
09748 h_AVE2[i] = buf;
09749 }
09750 }
09751
09752
09753 void MPICUDA_kmeans::set_AVE(EMData* im, int pos) {
09754 for (int i = 0; i < m ; ++i) h_AVE[pos * m + i] = (*im)(i);
09755 }
09756
09757
09758 vector<EMData*> MPICUDA_kmeans::get_AVE() {
09759 vector<EMData*> ave(K);
09760 for (int k = 0; k < K; ++k) {
09761 EMData* im = new EMData();
09762 im->set_size(m, 1, 1);
09763 float *ptr = im->get_data();
09764 for (int i = 0; i < m; ++i) {ptr[i] = h_AVE[k * m + i];}
09765 ave[k] = im->copy();
09766 delete im;
09767 }
09768 return ave;
09769 }
09770
09771
09772 int MPICUDA_kmeans::one_iter() {
09773 int status = cuda_mpi_kmeans(h_AVE, d_AVE, h_dist, d_dist, d_im, h_im2, h_AVE2, h_asg, h_NC, params);
09774 ite++;
09775 return status;
09776 }
09777
09778
09779 int MPICUDA_kmeans::one_iter_SA() {
09780 int status = cuda_mpi_kmeans_SA(h_AVE, d_AVE, h_dist, d_dist, d_im, h_im2, h_AVE2, h_asg, h_NC, T, params);
09781 ite++;
09782 return status;
09783 }
09784
09785
09786 vector <float> MPICUDA_kmeans::compute_ji() {
09787 int status = cuda_mpi_dist(h_AVE, d_AVE, h_dist, d_dist, d_im, n, K, m);
09788 vector <float> ji(K);
09789 int i;
09790 if (status != 0) {
09791 for (i = 0; i < K; ++i) ji[i] = -1.0;
09792 return ji;
09793 }
09794 for (i = 0; i < n; ++i) ji[h_asg[i]] += (h_im2[i] + h_AVE2[h_asg[i]] - 2 * h_dist[i * K + h_asg[i]]);
09795 return ji;
09796 }
09797
09798
09799 vector <float> MPICUDA_kmeans::compute_criterion(const vector <float>& Ji) {
09800 float buf = 0.0f;
09801 float Je = 0.0f;
09802 float Tr_AVE = 0.0f;
09803 float v_max = 0.0f;
09804 float* S_AVE2 = (float*)calloc(m, sizeof(float));
09805 float* S_AVE = (float*)calloc(m, sizeof(float));
09806 vector <float> crit(4);
09807 int i, j, k;
09808
09809 for (i = 0; i < K; ++i) Je += (Ji[i] / float(m));
09810 crit[0] = Je;
09811
09812 for (i = 0; i < K; ++i) {
09813 for (j = 0; j < m; ++j) {
09814 S_AVE[j] += h_AVE[i * m + j];
09815 S_AVE2[j] += (h_AVE[i * m + j] * h_AVE[i * m +j]);
09816 }
09817 }
09818 buf = 1 / (float)K;
09819 for (i = 0; i < m; ++i) Tr_AVE += (buf * (S_AVE2[i] - buf * S_AVE[i] * S_AVE[i]));
09820
09821 crit[1] = Tr_AVE * Je;
09822
09823 crit[2] = (Tr_AVE * (float)(N - K)) / (Je * (float)(K - 1));
09824
09825 for (i = 0; i < K; ++i) {
09826 v_max = 0.0f;
09827 for (j = 0; j < K; ++j) {
09828 if (j != i) {
09829 buf = 0.0f;
09830 for (k = 0; k < m; ++k) buf += ((h_AVE[j * m + k] - h_AVE[i * m + k]) * (h_AVE[j * m + k] - h_AVE[i * m + k]));
09831 buf = (Ji[i] / (float)h_NC[i] + Ji[j] / (float)h_NC[j]) * ((float)m / buf);
09832 }
09833 if (buf > v_max) v_max = buf;
09834 }
09835 crit[3] += v_max;
09836 }
09837 crit[3] /= (float)K;
09838 free(S_AVE);
09839 free(S_AVE2);
09840 return crit;
09841 }
09842
09843
09844 int MPICUDA_kmeans::shutdown() {
09845 return cuda_mpi_shutdown(d_im, d_AVE, d_dist);
09846 }
09848
09849 void CudaMultProcessor::process_inplace(EMData* image) {
09850 float val = params.set_default("scale",(float) 1.0);
09851 EMDataForCuda tmp = image->get_data_struct_for_cuda();
09852 emdata_processor_mult(&tmp,val);
09853 image->gpu_update();
09854 }
09855
09856
09857 void CudaCorrelationProcessor::process_inplace(EMData* image) {
09858 EMData* with = params.set_default("with",(EMData*)0);
09859 if (with == 0) throw InvalidParameterException("You must supply the with parameter, and it must be valid. It is NULL.");
09860
09861 EMDataForCuda left = image->get_data_struct_for_cuda();
09862 with->bind_cuda_texture(false);
09863 emdata_processor_correlation_texture(&left,1);
09864 image->gpu_update();
09865
09866 }
09867
09868 #endif //EMAN2_USING_CUDA
09869
09870 void EMAN::dump_processors()
09871 {
09872 dump_factory < Processor > ();
09873 }
09874
09875 map<string, vector<string> > EMAN::dump_processors_list()
09876 {
09877 return dump_factory_list < Processor > ();
09878 }
09879
09880 map<string, vector<string> > EMAN::group_processors()
09881 {
09882 map<string, vector<string> > processor_groups;
09883
09884 vector <string> processornames = Factory<Processor>::get_list();
09885
09886 for (size_t i = 0; i < processornames.size(); i++) {
09887 Processor * f = Factory<Processor>::get(processornames[i]);
09888 if (dynamic_cast<RealPixelProcessor*>(f) != 0) {
09889 processor_groups["RealPixelProcessor"].push_back(f->get_name());
09890 }
09891 else if (dynamic_cast<BoxStatProcessor*>(f) != 0) {
09892 processor_groups["BoxStatProcessor"].push_back(f->get_name());
09893 }
09894 else if (dynamic_cast<ComplexPixelProcessor*>(f) != 0) {
09895 processor_groups["ComplexPixelProcessor"].push_back(f->get_name());
09896 }
09897 else if (dynamic_cast<CoordinateProcessor*>(f) != 0) {
09898 processor_groups["CoordinateProcessor"].push_back(f->get_name());
09899 }
09900 else if (dynamic_cast<FourierProcessor*>(f) != 0) {
09901 processor_groups["FourierProcessor"].push_back(f->get_name());
09902 }
09903 else if (dynamic_cast<NewFourierProcessor*>(f) != 0) {
09904 processor_groups["FourierProcessor"].push_back(f->get_name());
09905 }
09906 else if (dynamic_cast<NormalizeProcessor*>(f) != 0) {
09907 processor_groups["NormalizeProcessor"].push_back(f->get_name());
09908 }
09909 else {
09910 processor_groups["Others"].push_back(f->get_name());
09911 }
09912 }
09913
09914 return processor_groups;
09915 }
09916
09917
09918
09919
09920
09921 float ModelHelixProcessor::radprofile(float r, int type)
09922
09923 {
09924
09925 double ret = 0;
09926 if (type == 0) {
09927 r /= 2;
09928 ret = exp(-r * r);
09929 } else if (type == 1) {
09930 r /= 2;
09931 ret = (1 - r * r / 4) * exp(-r * r / 4);
09932 } else if (type == 2) {
09933
09934
09935
09936
09937
09938 if (r >= 12.2)
09939 return 0;
09940 static float an[15] = { -3.9185246832229140e-16f,
09941 3.3957205298900993e-14f, 2.0343351971222658e-12f,
09942 -4.4935965816879751e-10f, 3.0668169835080933e-08f,
09943 -1.1904544689091790e-06f, 2.9753088549414953e-05f,
09944 -4.9802112876220150e-04f, 5.5900917825309360e-03f,
09945 -4.0823714462925299e-02f, 1.8021733669148599e-01f,
09946 -4.0992557296268717e-01f, 3.3980328566901458e-01f,
09947 -3.6062024812411908e-01f, 1.0000000000000000e+00f };
09948
09949 ret = an[0];
09950 for (int i = 1; i < 15; i++) {
09951 ret = ret * r + an[i];
09952 }
09953 }
09954 return (float)ret;
09955 }
09956
09957 void ModelEMCylinderProcessor::process_inplace(EMData * in)
09958
09959 {
09960
09961
09962 EMData * cyl = in;
09963 int nx = cyl->get_xsize();
09964 int ny = cyl->get_ysize();
09965 int nz = cyl->get_zsize();
09966
09967 int type = params.set_default("type", 2);
09968 float len = params.set_default("length", 16.2f);
09969 int x0 = params.set_default("x0", -1);
09970 int y0 = params.set_default("y0", -1);
09971 int z0 = params.set_default("z0", -1);
09972
09973
09974 if (x0 < 0 || x0 >= nx)
09975 x0 = nx / 2;
09976 if (y0 < 0 || y0 >= ny)
09977 y0 = ny / 2;
09978 if (z0 < 0 || z0 >= nz)
09979 z0 = nz / 2;
09980
09981 float apix_x = cyl->get_attr("apix_x");
09982 float apix_y = cyl->get_attr("apix_y");
09983 float apix_z = cyl->get_attr("apix_z");
09984
09985 float * dat = cyl->get_data();
09986 int cyl_voxel_len = (int) (len / apix_z);
09987 int cyl_k_min = z0 - cyl_voxel_len / 2;
09988 int cyl_k_max = z0 + cyl_voxel_len / 2;
09989
09990 int x, y;
09991 for (int k = 0; k < nz; k++) {
09992 for (int j = 0; j < ny; j++) {
09993 for (int i = 0; i < nx; i++, dat++) {
09994 x = i - x0;
09995 y = j - y0;
09996 float radius = (float)hypot(x * apix_x, y * apix_y);
09997 if ((k > cyl_k_min) && (k < cyl_k_max))
09998 *dat += radprofile(radius, type);
09999
10000
10001
10002 }
10003 }
10004 }
10005 }
10006
10007 void ApplyPolynomialProfileToHelix::process_inplace(EMData * in)
10008 {
10009 EMData * cyl = in;
10010 int nx = cyl->get_xsize();
10011 int ny = cyl->get_ysize();
10012 int nz = cyl->get_zsize();
10013 float apix_x = cyl->get_attr("apix_x");
10014 float apix_y = cyl->get_attr("apix_y");
10015 float apix_z = cyl->get_attr("apix_z");
10016 float lengthAngstroms = params["length"];
10017 int z0 = params.set_default("z0", -1);
10018
10019 if (z0 < 0 || z0 >= nz)
10020 z0 = nz / 2;
10021
10022 int z_start = Util::round( z0 - 0.5*lengthAngstroms/apix_z );
10023 int z_stop = Util::round( z0 + 0.5*lengthAngstroms/apix_z );
10024
10025 float * dat = cyl->get_data();
10026 double rho_x_sum, rho_y_sum, rho_sum, x_cm, y_cm, radius;
10027
10028 for (int k = 0; k < nz; k++)
10029 {
10030 rho_x_sum = rho_y_sum = rho_sum = 0;
10031
10032 if (k >= z_start && k <= z_stop)
10033
10034 {
10035
10036 for (int j = 0; j < ny; j++)
10037 {
10038 for (int i = 0; i < nx; i++, dat++)
10039 {
10040 rho_x_sum += (*dat)*i;
10041 rho_y_sum += (*dat)*j;
10042 rho_sum += *dat;
10043 }
10044 }
10045 if (rho_sum != 0)
10046 {
10047 dat -= nx*ny;
10048 x_cm = rho_x_sum/rho_sum;
10049 y_cm = rho_y_sum/rho_sum;
10050
10051
10052 for (int j=0; j<ny;j++)
10053 {
10054 for (int i=0;i<nx;i++,dat++)
10055 {
10056 radius = hypot( (i-x_cm)*apix_x, (j-y_cm)*apix_y );
10057 *dat = radprofile((float)radius, 2);
10058 }
10059 }
10060 }
10061 }
10062 else
10063
10064 {
10065 for (int j=0; j<ny; j++)
10066 for(int i=0; i<nx; i++)
10067 {
10068 *dat = 0;
10069 dat++;
10070 }
10071 }
10072
10073 }
10074 }
10075
10076 EMData* BinarySkeletonizerProcessor::process(EMData * image)
10077 {
10078 using namespace wustl_mm::GraySkeletonCPP;
10079 using namespace wustl_mm::SkeletonMaker;
10080
10081 Volume * vimage = new Volume(image);
10082 float threshold = params["threshold"];
10083 int min_curvew = params.set_default("min_curve_width", 4);
10084 int min_srfcw = params.set_default("min_surface_width", 4);
10085 bool mark_surfaces = params.set_default("mark_surfaces", true);
10086 Volume* vskel = VolumeSkeletonizer::PerformPureJuSkeletonization(vimage, "unused", static_cast<double>(threshold), min_curvew, min_srfcw);
10087
10088 if (mark_surfaces) {
10089 VolumeSkeletonizer::MarkSurfaces(vskel);
10090 }
10091
10092 vskel->getVolumeData()->owns_emdata = false;
10093 EMData* skel = vskel->get_emdata();
10094 skel->update();
10095 return skel;
10096 }
10097
10098 void BinarySkeletonizerProcessor::process_inplace(EMData * image)
10099 {
10100 EMData* em_skel = this->process(image);
10101
10102 *image = *em_skel;
10103 image->update();
10104 delete em_skel;
10105 em_skel = NULL;
10106 return;
10107 }