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