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