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