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