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