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