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