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