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