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 bool ignore_zero = params.set_default("ignore_zero",true);
03706
03707 float low_threshold = FLT_MIN;
03708 string low_thr_name = "low_threshold";
03709 if (params.has_key(low_thr_name)) {
03710 low_threshold = params[low_thr_name];
03711 }
03712
03713 float high_threshold = FLT_MAX;
03714 string high_thr_name = "high_threshold";
03715 if (params.has_key(high_thr_name)) {
03716 high_threshold = params[high_thr_name];
03717 }
03718
03719 float *rawp = image->get_data();
03720 float *refp = to->get_data();
03721
03722 int nx = image->get_xsize();
03723 int ny = image->get_ysize();
03724 int nz = image->get_zsize();
03725 size_t size = nx * ny * nz;
03726
03727 float sum_x = 0;
03728 float sum_y = 0;
03729 int count = 0;
03730
03731 float sum_x_mean = 0;
03732 float sum_tt = 0;
03733 float b = 0;
03734
03735
03736 if (ignore_zero) {
03737 for (size_t i = 0; i < size; i++) {
03738 if (refp[i] >= low_threshold && refp[i] <= high_threshold && refp[i] != 0.0 && rawp[i] != 0.0) {
03739 count++;
03740 sum_x += refp[i];
03741 sum_y += rawp[i];
03742 }
03743 }
03744
03745 sum_x_mean = sum_x / count;
03746 sum_tt = 0;
03747 b = 0;
03748
03749 float t;
03750 for (size_t i = 0; i < size; i++) {
03751 if (refp[i] >= low_threshold && refp[i] <= high_threshold && refp[i] != 0.0 && rawp[i] != 0.0) {
03752 t = refp[i] - sum_x_mean;
03753 sum_tt += t * t;
03754 b += t * rawp[i];
03755 }
03756 }
03757 }
03758 else {
03759 for (size_t i = 0; i < size; i++) {
03760 if (refp[i] >= low_threshold && refp[i] <= high_threshold) {
03761 count++;
03762 sum_x += refp[i];
03763 sum_y += rawp[i];
03764 }
03765 }
03766
03767 sum_x_mean = sum_x / count;
03768 sum_tt = 0;
03769 b = 0;
03770
03771 float t;
03772 for (size_t i = 0; i < size; i++) {
03773 if (refp[i] >= low_threshold && refp[i] <= high_threshold) {
03774 t = refp[i] - sum_x_mean;
03775 sum_tt += t * t;
03776 b += t * rawp[i];
03777 }
03778 }
03779 }
03780
03781 b /= sum_tt;
03782
03783 float a = (sum_y - sum_x * b) / count;
03784 float scale = 1 / b;
03785 float shift = -a / b;
03786
03787 for (size_t i = 0; i < size; i++) {
03788 rawp[i] = (rawp[i] - a) / b;
03789 }
03790
03791 image->update();
03792
03793 params["scale"] = scale;
03794 params["shift"] = shift;
03795
03796 image->set_attr("norm_mult",scale);
03797 image->set_attr("norm_add",shift);
03798
03799 }
03800
03801
03802 void BinarizeFourierProcessor::process_inplace(EMData* image) {
03803 ENTERFUNC;
03804 if (!image->is_complex()) throw ImageFormatException("Fourier binary thresholding processor only works for complex images");
03805
03806 float threshold = params.set_default("value",-1.0f);
03807 if (threshold < 0) throw InvalidParameterException("For fourier amplitude-based thresholding, the threshold must be greater than or equal to 0.");
03808
03809 image->ri2ap();
03810
03811 #ifdef EMAN2_USING_CUDA
03812 if (image->gpu_operation_preferred()) {
03813 EMDataForCuda tmp = image->get_data_struct_for_cuda();
03814 binarize_fourier_amp_processor(&tmp,threshold);
03815 image->set_ri(true);
03816 image->gpu_update();
03817 EXITFUNC;
03818 return;
03819 }
03820 #endif
03821
03822 float* d = image->get_data();
03823 for( size_t i = 0; i < image->get_size()/2; ++i, d+=2) {
03824 float v = *d;
03825 if ( v >= threshold ) {
03826 *d = 1;
03827 *(d+1) = 0;
03828 } else {
03829 *d = 0;
03830 *(d+1) = 0;
03831 }
03832 }
03833
03834
03835 image->set_ri(true);
03836 image->update();
03837 EXITFUNC;
03838 }
03839
03840
03841 void BilateralProcessor::process_inplace(EMData * image)
03842 {
03843 if (!image) {
03844 LOGWARN("NULL Image");
03845 return;
03846 }
03847
03848 float distance_sigma = params["distance_sigma"];
03849 float value_sigma = params["value_sigma"];
03850 int max_iter = params["niter"];
03851 int half_width = params["half_width"];
03852
03853 if (half_width < distance_sigma) {
03854 LOGWARN("localwidth(=%d) should be larger than distance_sigma=(%f)\n",
03855 half_width, distance_sigma);
03856 }
03857
03858 distance_sigma *= distance_sigma;
03859
03860 float image_sigma = image->get_attr("sigma");
03861 if (image_sigma > value_sigma) {
03862 LOGWARN("image sigma(=%f) should be smaller than value_sigma=(%f)\n",
03863 image_sigma, value_sigma);
03864 }
03865 value_sigma *= value_sigma;
03866
03867 int nx = image->get_xsize();
03868 int ny = image->get_ysize();
03869 int nz = image->get_zsize();
03870
03871 if(nz==1) {
03872 int width=nx, height=ny;
03873
03874 int i,j,m,n;
03875
03876 float tempfloat1,tempfloat2,tempfloat3;
03877 int index1,index2,index;
03878 int Iter;
03879 int tempint1,tempint3;
03880
03881 tempint1=width;
03882 tempint3=width+2*half_width;
03883
03884 float* mask=(float*)calloc((2*half_width+1)*(2*half_width+1),sizeof(float));
03885 float* OrgImg=(float*)calloc((2*half_width+width)*(2*half_width+height),sizeof(float));
03886 float* NewImg=image->get_data();
03887
03888 for(m=-(half_width);m<=half_width;m++)
03889 for(n=-(half_width);n<=half_width;n++) {
03890 index=(m+half_width)*(2*half_width+1)+(n+half_width);
03891 mask[index]=exp((float)(-(m*m+n*n)/distance_sigma/2.0));
03892 }
03893
03894
03895
03896 Iter=0;
03897 while(Iter<max_iter) {
03898 for(i=0;i<height;i++)
03899 for(j=0;j<width;j++) {
03900 index1=(i+half_width)*tempint3+(j+half_width);
03901 index2=i*tempint1+j;
03902 OrgImg[index1]=NewImg[index2];
03903 }
03904
03905
03906 for(i=0;i<height;i++){
03907 for(j=0;j<half_width;j++) OrgImg[(i+half_width)*tempint3+(j)]=OrgImg[(i+half_width)*tempint3+(2*half_width-j)];
03908 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)];
03909 }
03910 for(i=0;i<half_width;i++){
03911 for(j=0;j<(width+2*half_width);j++) OrgImg[i*tempint3+j]=OrgImg[(2*half_width-i)*tempint3+j];
03912 for(j=0;j<(width+2*half_width);j++) OrgImg[(i+height+half_width)*tempint3+j]=OrgImg[(height+half_width-2-i)*tempint3+j];
03913 }
03914
03915
03916
03917
03918 for(i=0;i<height;i++){
03919
03920 for(j=0;j<width;j++){
03921 tempfloat1=0.0; tempfloat2=0.0;
03922 for(m=-(half_width);m<=half_width;m++)
03923 for(n=-(half_width);n<=half_width;n++){
03924 index =(m+half_width)*(2*half_width+1)+(n+half_width);
03925 index1=(i+half_width)*tempint3+(j+half_width);
03926 index2=(i+half_width+m)*tempint3+(j+half_width+n);
03927 tempfloat3=(OrgImg[index1]-OrgImg[index2])*(OrgImg[index1]-OrgImg[index2]);
03928
03929 tempfloat3=mask[index]*(1.0f/(1+tempfloat3/value_sigma));
03930
03931 tempfloat1+=tempfloat3;
03932
03933 tempfloat2+=tempfloat3*OrgImg[(i+half_width+m)*tempint3+(j+half_width+n)];
03934 }
03935 NewImg[i*width+j]=tempfloat2/tempfloat1;
03936 }
03937 }
03938 Iter++;
03939 }
03940
03941
03942
03943 free(mask);
03944 free(OrgImg);
03945
03946
03947 }
03948 else {
03949 int width = nx;
03950 int height = ny;
03951 int slicenum = nz;
03952
03953 int slice_size = width * height;
03954 int new_width = width + 2 * half_width;
03955 int new_slice_size = (width + 2 * half_width) * (height + 2 * half_width);
03956
03957 int width1 = 2 * half_width + 1;
03958 int mask_size = width1 * width1;
03959 int old_img_size = (2 * half_width + width) * (2 * half_width + height);
03960
03961 int zstart = -half_width;
03962 int zend = -half_width;
03963 int is_3d = 0;
03964 if (nz > 1) {
03965 mask_size *= width1;
03966 old_img_size *= (2 * half_width + slicenum);
03967 zend = half_width;
03968 is_3d = 1;
03969 }
03970
03971 float *mask = (float *) calloc(mask_size, sizeof(float));
03972 float *old_img = (float *) calloc(old_img_size, sizeof(float));
03973
03974 float *new_img = image->get_data();
03975
03976 for (int p = zstart; p <= zend; p++) {
03977 int cur_p = (p + half_width) * (2 * half_width + 1) * (2 * half_width + 1);
03978
03979 for (int m = -half_width; m <= half_width; m++) {
03980 int cur_m = (m + half_width) * (2 * half_width + 1) + half_width;
03981
03982 for (int n = -half_width; n <= half_width; n++) {
03983 int l = cur_p + cur_m + n;
03984 mask[l] = exp((float) (-(m * m + n * n + p * p * is_3d) / distance_sigma / 2.0f));
03985 }
03986 }
03987 }
03988
03989 int iter = 0;
03990 while (iter < max_iter) {
03991 for (int k = 0; k < slicenum; k++) {
03992 int cur_k1 = (k + half_width) * new_slice_size * is_3d;
03993 int cur_k2 = k * slice_size;
03994
03995 for (int i = 0; i < height; i++) {
03996 int cur_i1 = (i + half_width) * new_width;
03997 int cur_i2 = i * width;
03998
03999 for (int j = 0; j < width; j++) {
04000 int k1 = cur_k1 + cur_i1 + (j + half_width);
04001 int k2 = cur_k2 + cur_i2 + j;
04002 old_img[k1] = new_img[k2];
04003 }
04004 }
04005 }
04006
04007 for (int k = 0; k < slicenum; k++) {
04008 int cur_k = (k + half_width) * new_slice_size * is_3d;
04009
04010 for (int i = 0; i < height; i++) {
04011 int cur_i = (i + half_width) * new_width;
04012
04013 for (int j = 0; j < half_width; j++) {
04014 int k1 = cur_k + cur_i + j;
04015 int k2 = cur_k + cur_i + (2 * half_width - j);
04016 old_img[k1] = old_img[k2];
04017 }
04018
04019 for (int j = 0; j < half_width; j++) {
04020 int k1 = cur_k + cur_i + (width + half_width + j);
04021 int k2 = cur_k + cur_i + (width + half_width - j - 2);
04022 old_img[k1] = old_img[k2];
04023 }
04024 }
04025
04026
04027 for (int i = 0; i < half_width; i++) {
04028 int i2 = i * new_width;
04029 int i3 = (2 * half_width - i) * new_width;
04030 for (int j = 0; j < (width + 2 * half_width); j++) {
04031 int k1 = cur_k + i2 + j;
04032 int k2 = cur_k + i3 + j;
04033 old_img[k1] = old_img[k2];
04034 }
04035
04036 i2 = (height + half_width + i) * new_width;
04037 i3 = (height + half_width - 2 - i) * new_width;
04038 for (int j = 0; j < (width + 2 * half_width); j++) {
04039 int k1 = cur_k + i2 + j;
04040 int k2 = cur_k + i3 + j;
04041 old_img[k1] = old_img[k2];
04042 }
04043 }
04044 }
04045
04046 size_t idx;
04047 for (int k = 0; k < slicenum; k++) {
04048 int cur_k = (k + half_width) * new_slice_size;
04049
04050 for (int i = 0; i < height; i++) {
04051 int cur_i = (i + half_width) * new_width;
04052
04053 for (int j = 0; j < width; j++) {
04054 float f1 = 0;
04055 float f2 = 0;
04056 int k1 = cur_k + cur_i + (j + half_width);
04057
04058 for (int p = zstart; p <= zend; p++) {
04059 int cur_p1 = (p + half_width) * (2 * half_width + 1) * (2 * half_width + 1);
04060 int cur_p2 = (k + half_width + p) * new_slice_size;
04061
04062 for (int m = -half_width; m <= half_width; m++) {
04063 int cur_m1 = (m + half_width) * (2 * half_width + 1);
04064 int cur_m2 = cur_p2 + cur_i + m * new_width + j + half_width;
04065
04066 for (int n = -half_width; n <= half_width; n++) {
04067 int k = cur_p1 + cur_m1 + (n + half_width);
04068 int k2 = cur_m2 + n;
04069 float f3 = Util::square(old_img[k1] - old_img[k2]);
04070
04071 f3 = mask[k] * (1.0f / (1 + f3 / value_sigma));
04072 f1 += f3;
04073 int l1 = cur_m2 + n;
04074 f2 += f3 * old_img[l1];
04075 }
04076
04077 idx = k * height * width + i * width + j;
04078 new_img[idx] = f2 / f1;
04079 }
04080 }
04081 }
04082 }
04083 }
04084 iter++;
04085 }
04086 if( mask ) {
04087 free(mask);
04088 mask = 0;
04089 }
04090
04091 if( old_img ) {
04092 free(old_img);
04093 old_img = 0;
04094 }
04095 }
04096
04097 image->update();
04098 }
04099
04100 void RotationalAverageProcessor::process_inplace(EMData * image)
04101 {
04102 if (!image || image->is_complex()) {
04103 LOGWARN("only works on real image. do nothing.");
04104 return;
04105 }
04106
04107 if (image->get_ndim() <= 0 || image->get_ndim() > 3) throw ImageDimensionException("radial average processor only works for 2D and 3D images");
04108
04109 float *rdata = image->get_data();
04110 int nx = image->get_xsize();
04111 int ny = image->get_ysize();
04112
04113 vector < float >dist = image->calc_radial_dist(nx / 2, 0, 1,0);
04114
04115 float midx = (float)((int)nx/2);
04116 float midy = (float)((int)ny/2);
04117
04118 size_t c = 0;
04119 if (image->get_ndim() == 2) {
04120 for (int y = 0; y < ny; y++) {
04121 for (int x = 0; x < nx; x++, c++) {
04122 #ifdef _WIN32
04123 float r = (float) _hypot(x - midx, y - midy);
04124 #else
04125 float r = (float) hypot(x - midx, y - midy);
04126 #endif //_WIN32
04127
04128
04129 int i = (int) floor(r);
04130 r -= i;
04131 if (i >= 0 && i < nx / 2 - 1) {
04132 rdata[c] = dist[i] * (1.0f - r) + dist[i + 1] * r;
04133 }
04134 else if (i < 0) {
04135 rdata[c] = dist[0];
04136 }
04137 else {
04138 rdata[c] = 0;
04139 }
04140 }
04141 }
04142 }
04143 else if (image->get_ndim() == 3) {
04144 int nz = image->get_zsize();
04145 float midz = (float)((int)nz/2);
04146 float r;
04147 int i;
04148 for (int z = 0; z < nz; ++z) {
04149 for (int y = 0; y < ny; ++y) {
04150 for (int x = 0; x < nx; ++x, ++c) {
04151
04152 r = (float) Util::hypot3(x - midx, y - midy, z - midz);
04153
04154 i = Util::fast_floor(r);
04155 r -= i;
04156 if (i >= 0 && i < nx / 2 - 1) {
04157 rdata[c] = dist[i] * (1.0f - r) + dist[i + 1] * r;
04158 }
04159 else if (i < 0) {
04160 rdata[c] = dist[0];
04161 }
04162 else {
04163 rdata[c] = 0;
04164 }
04165 }
04166 }
04167 }
04168 }
04169
04170 image->update();
04171 }
04172
04173
04174
04175 void RotationalSubstractProcessor::process_inplace(EMData * image)
04176 {
04177 if (!image || image->is_complex()) {
04178 LOGWARN("only works on real image. do nothing.");
04179 return;
04180 }
04181
04182 if (image->get_ndim() != 2) throw ImageDimensionException("This processor works only for 2D images");
04183
04184 float *rdata = image->get_data();
04185 int nx = image->get_xsize();
04186 int ny = image->get_ysize();
04187
04188 vector < float >dist = image->calc_radial_dist(nx / 2, 0, 1,0);
04189
04190 int c = 0;
04191 for (int y = 0; y < ny; y++) {
04192 for (int x = 0; x < nx; x++, c++) {
04193 #ifdef _WIN32
04194 float r = (float) _hypot(x - nx / 2, y - ny / 2);
04195 #else
04196 float r = (float) hypot(x - nx / 2, y - ny / 2);
04197 #endif
04198 int i = (int) floor(r);
04199 r -= i;
04200 if (i >= 0 && i < nx / 2 - 1) {
04201 rdata[c] -= dist[i] * (1.0f - r) + dist[i + 1] * r;
04202 }
04203 else {
04204 rdata[c] = 0;
04205 }
04206 }
04207 }
04208
04209 image->update();
04210 }
04211
04212
04213 EMData* TransposeProcessor::process(const EMData* const image) {
04214 if (image->get_ndim() != 2) throw UnexpectedBehaviorException("Transpose processor only works with 2D images");
04215 if (image->is_complex()) throw UnexpectedBehaviorException("Transpose processor only works with real images");
04216
04217 EMData* ret = new EMData(image->get_ysize(),image->get_xsize(),1);
04218
04219 for(int j = 0; j< image->get_ysize();++j) {
04220 for(int i = 0; i< image->get_xsize();++i) {
04221 ret->set_value_at(j,i,image->get_value_at(i,j));
04222 }
04223 }
04224
04225 return ret;
04226
04227 }
04228
04229 void TransposeProcessor::process_inplace(EMData* image) {
04230 if (image->get_ndim() != 2) throw UnexpectedBehaviorException("Transpose processor only works with 2D images");
04231 if (image->is_complex()) throw UnexpectedBehaviorException("Transpose processor only works with real images");
04232
04233 float* data = (float*)malloc(image->get_ysize()*image->get_xsize()*sizeof(float));
04234
04235 int nx = image->get_ysize();
04236 for(int j = 0; j< image->get_ysize();++j) {
04237 for(int i = 0; i< image->get_xsize();++i) {
04238 data[i*nx+j] = image->get_value_at(i,j);
04239 }
04240 }
04241
04242 image->set_data(data,image->get_ysize(),image->get_xsize(),1);
04243
04244 }
04245
04246 void FlipProcessor::process_inplace(EMData * image)
04247 {
04248 ENTERFUNC;
04249 if (!image) {
04250 LOGWARN("NULL Image");
04251 return;
04252 }
04253 string axis = (const char*)params["axis"];
04254 #ifdef EMAN2_USING_CUDA
04255 if (image->gpu_operation_preferred()) {
04256 float array[12] = {1.0, 0.0, 0.0, 0.0,
04257 0.0, 1.0, 0.0, 0.0,
04258 0.0, 0.0, 1.0, 0.0};
04259 if (axis == "x" || axis == "X") {
04260 array[0] = -1.0;
04261 }else if (axis == "y" || axis == "Y") {
04262 array[5] = -1.0;
04263 }
04264 else if (axis == "z" || axis == "Z") {
04265 array[10] = -1.0;
04266 }
04267 Transform t(array);
04268 Dict params("transform",(Transform*)&t);
04269 image->process_inplace("xform",params);
04270 EXITFUNC;
04271 return;
04272 }
04273 #endif
04274
04275
04276 float *d = image->get_data();
04277 int nx = image->get_xsize();
04278 int ny = image->get_ysize();
04279 int nz = image->get_zsize();
04280
04281 size_t nxy = nx * ny;
04282
04283
04284
04285
04286
04287
04288 if (axis == "x" || axis == "X") {
04289 int offset = (nx%2 == 0);
04290 size_t idx1, idx2;
04291 for(int z = 0; z < nz; ++z) {
04292 for(int y = 0; y < ny; ++y) {
04293 if (offset != 0 ) {
04294 idx1 = z*nxy + y*nx;
04295 d[idx1] = 0;
04296 }
04297 for(int x = offset; x < nx / 2; ++x) {
04298 idx1 = z*nxy + y*nx + x;
04299 idx2 = z*nxy + y*nx + (nx-x-1+offset);
04300 std::swap(d[idx1], d[idx2]);
04301 }
04302
04303 }
04304 }
04305 }
04306
04307 else if (axis == "y" || axis == "Y") {
04308 int offset = (ny%2 == 0);
04309 for(int z=0; z<nz; ++z) {
04310 if (offset != 0) {
04311 std::fill(d+z*nxy,d+z*nxy+nx,0);
04312 }
04313 for(int y=offset; y<ny/2; ++y) {
04314 for(int x=0; x<nx; ++x) {
04315 std::swap(d[z*nxy + y*nx +x], d[z*nxy + (ny -y -1+offset)*nx +x]);
04316 }
04317 }
04318 }
04319 }
04320 else if (axis == "z" || axis == "Z") {
04321 int offset = (nz%2 == 0);
04322 if (offset != 0) {
04323 std::fill(d,d+nxy,0);
04324 }
04325 size_t idx1, idx2;
04326 for(int z=offset; z<nz/2; ++z) {
04327 for(int y=0; y<ny; ++y) {
04328 for(int x=0; x<nx; ++x) {
04329 idx1 = z*nxy + y*nx + x;
04330 idx2 = (nz-z-1+offset)*nxy + y*nx + x;
04331 std::swap(d[idx1], d[idx2]);
04332 }
04333 }
04334 }
04335 }
04336
04337 image->update();
04338 EXITFUNC;
04339 }
04340
04341 void AddNoiseProcessor::process_inplace(EMData * image)
04342 {
04343 if (!image) {
04344 LOGWARN("NULL Image");
04345 return;
04346 }
04347
04348 Randnum * randnum = Randnum::Instance();
04349 if(params.has_key("seed")) {
04350 randnum->set_seed((int)params["seed"]);
04351 }
04352
04353 float addnoise = params["noise"];
04354 addnoise *= get_sigma(image);
04355 float *dat = image->get_data();
04356
04357 for (size_t j = 0; j < image->get_size(); ++j) {
04358 dat[j] += randnum->get_gauss_rand(addnoise, addnoise / 2);
04359 }
04360
04361 image->update();
04362 }
04363
04364 float AddSigmaNoiseProcessor::get_sigma(EMData * image)
04365 {
04366 if (!image) {
04367 LOGWARN("NULL Image");
04368 return 0;
04369 }
04370 return image->get_attr("sigma");
04371 }
04372
04373 void FourierToCornerProcessor::process_inplace(EMData * image)
04374 {
04375 if ( !image->is_complex() ) throw ImageFormatException("Can not Fourier origin shift an image that is not complex");
04376
04377 int nx=image->get_xsize();
04378 int ny=image->get_ysize();
04379 int nz=image->get_zsize();
04380
04381 int nxy = nx*ny;
04382
04383 if ( ny == 1 && nz == 1 ){
04384 cout << "Warning- attempted Fourier origin shift a 1D image - no action taken" << endl;
04385 return;
04386 }
04387 int yodd = (ny%2==1);
04388 int zodd = (nz%2==1);
04389
04390 float* rdata = image->get_data();
04391
04392 float tmp[2];
04393 float* p1;
04394 float* p2;
04395
04396 if (yodd){
04397
04398
04399
04400
04401 float prev[2];
04402 size_t idx;
04403 for( int s = 0; s < nz; s++ ) {
04404 for( int c =0; c < nx; c += 2 ) {
04405 idx = s*nxy+ny/2*nx+c;
04406 prev[0] = rdata[idx];
04407 prev[1] = rdata[idx+1];
04408 for( int r = 0; r <= ny/2; ++r ) {
04409 idx = s*nxy+r*nx+c;
04410 float* p1 = &rdata[idx];
04411 tmp[0] = p1[0];
04412 tmp[1] = p1[1];
04413
04414 p1[0] = prev[0];
04415 p1[1] = prev[1];
04416
04417 prev[0] = tmp[0];
04418 prev[1] = tmp[1];
04419 }
04420 }
04421 }
04422 }
04423
04424
04425 size_t idx1, idx2;
04426 for( int s = 0; s < nz; ++s ) {
04427 for( int r = 0 + yodd; r < ny/2+yodd; ++r ) {
04428 for( int c =0; c < nx; c += 2 ) {
04429 idx1 = s*nxy+r*nx+c;
04430 idx2 = s*nxy+(r+ny/2)*nx+c;
04431 p1 = &rdata[idx1];
04432 p2 = &rdata[idx2];
04433
04434 tmp[0] = p1[0];
04435 tmp[1] = p1[1];
04436
04437 p1[0] = p2[0];
04438 p1[1] = p2[1];
04439
04440 p2[0] = tmp[0];
04441 p2[1] = tmp[1];
04442 }
04443 }
04444 }
04445
04446 if ( nz != 1 )
04447 {
04448
04449 if (zodd){
04450
04451
04452
04453 float prev[2];
04454 size_t idx;
04455 for( int r = 0; r < ny; ++r ) {
04456 for( int c =0; c < nx; c += 2 ) {
04457 idx = nz/2*nxy+r*nx+c;
04458 prev[0] = rdata[idx];
04459 prev[1] = rdata[idx+1];
04460 for( int s = 0; s <= nz/2; ++s ) {
04461 idx = s*nxy+r*nx+c;
04462 float* p1 = &rdata[idx];
04463 tmp[0] = p1[0];
04464 tmp[1] = p1[1];
04465
04466 p1[0] = prev[0];
04467 p1[1] = prev[1];
04468
04469 prev[0] = tmp[0];
04470 prev[1] = tmp[1];
04471 }
04472 }
04473 }
04474 }
04475
04476
04477 size_t idx1, idx2;
04478 for( int s = 0+zodd; s < nz/2 + zodd; ++s ) {
04479 for( int r = 0; r < ny; ++r ) {
04480 for( int c =0; c < nx; c += 2 ) {
04481 idx1 = s*nxy+r*nx+c;
04482 idx2 = (s+nz/2)*nxy+r*nx+c;
04483 p1 = &rdata[idx1];
04484 p2 = &rdata[idx2];
04485
04486 tmp[0] = p1[0];
04487 tmp[1] = p1[1];
04488
04489 p1[0] = p2[0];
04490 p1[1] = p2[1];
04491
04492 p2[0] = tmp[0];
04493 p2[1] = tmp[1];
04494 }
04495 }
04496 }
04497 }
04498 image->set_shuffled(false);
04499 }
04500
04501 void FourierToCenterProcessor::process_inplace(EMData * image)
04502 {
04503
04504
04505 int nx=image->get_xsize();
04506 int ny=image->get_ysize();
04507 int nz=image->get_zsize();
04508
04509 int nxy = nx*ny;
04510
04511 if ( ny == 1 && nz == 1 ){
04512 cout << "Warning- attempted Fourier origin shift a 1D image - no action taken" << endl;
04513 return;
04514 }
04515
04516 int yodd = (ny%2==1);
04517 int zodd = (nz%2==1);
04518
04519 float* rdata = image->get_data();
04520
04521 float tmp[2];
04522 float* p1;
04523 float* p2;
04524
04525
04526
04527 if ( !image->is_complex() ) {
04528 if (nz!=1 && !yodd && !zodd) {
04529 for (int x=0; x<nx; x++) {
04530 for (int y=0; y<ny; y++) {
04531 for (int z=0; z<nz/2; z++) {
04532 int y2=(y+ny/2)%ny;
04533 int z2=(z+nz/2)%nz;
04534 size_t i=x+y*nx+z*nxy;
04535 size_t i2=x+y2*nx+z2*nxy;
04536 float swp=rdata[i];
04537 rdata[i]=rdata[i2];
04538 rdata[i2]=swp;
04539 }
04540 }
04541 }
04542
04543 return;
04544 }
04545 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");
04546 }
04547
04548 if (yodd){
04549
04550
04551 float prev[2];
04552 size_t idx;
04553 for( int s = 0; s < nz; s++ ) {
04554 for( int c =0; c < nx; c += 2 ) {
04555 idx = s*nxy+c;
04556 prev[0] = rdata[idx];
04557 prev[1] = rdata[idx+1];
04558 for( int r = ny/2; r >= 0; --r ) {
04559 idx = s*nxy+r*nx+c;
04560 float* p1 = &rdata[idx];
04561 tmp[0] = p1[0];
04562 tmp[1] = p1[1];
04563
04564 p1[0] = prev[0];
04565 p1[1] = prev[1];
04566
04567 prev[0] = tmp[0];
04568 prev[1] = tmp[1];
04569 }
04570 }
04571 }
04572 }
04573
04574
04575 size_t idx1, idx2;
04576 for( int s = 0; s < nz; ++s ) {
04577 for( int r = 0; r < ny/2; ++r ) {
04578 for( int c =0; c < nx; c += 2 ) {
04579 idx1 = s*nxy+r*nx+c;
04580 idx2 = s*nxy+(r+ny/2+yodd)*nx+c;
04581 p1 = &rdata[idx1];
04582 p2 = &rdata[idx2];
04583
04584 tmp[0] = p1[0];
04585 tmp[1] = p1[1];
04586
04587 p1[0] = p2[0];
04588 p1[1] = p2[1];
04589
04590 p2[0] = tmp[0];
04591 p2[1] = tmp[1];
04592 }
04593 }
04594 }
04595
04596 if ( nz != 1 ) {
04597 if (zodd){
04598
04599
04600 float prev[2];
04601 size_t idx;
04602 for( int r = 0; r < ny; ++r ) {
04603 for( int c =0; c < nx; c += 2 ) {
04604 prev[0] = rdata[r*nx+c];
04605 prev[1] = rdata[r*nx+c+1];
04606 for( int s = nz/2; s >= 0; --s ) {
04607 idx = s*nxy+r*nx+c;
04608 float* p1 = &rdata[idx];
04609 tmp[0] = p1[0];
04610 tmp[1] = p1[1];
04611
04612 p1[0] = prev[0];
04613 p1[1] = prev[1];
04614
04615 prev[0] = tmp[0];
04616 prev[1] = tmp[1];
04617 }
04618 }
04619 }
04620 }
04621
04622
04623 size_t idx1, idx2;
04624 for( int s = 0; s < nz/2; ++s ) {
04625 for( int r = 0; r < ny; ++r ) {
04626 for( int c =0; c < nx; c += 2 ) {
04627 idx1 = s*nxy+r*nx+c;
04628 idx2 = (s+nz/2+zodd)*nxy+r*nx+c;
04629 p1 = &rdata[idx1];
04630 p2 = &rdata[idx2];
04631
04632 tmp[0] = p1[0];
04633 tmp[1] = p1[1];
04634
04635 p1[0] = p2[0];
04636 p1[1] = p2[1];
04637
04638 p2[0] = tmp[0];
04639 p2[1] = tmp[1];
04640 }
04641 }
04642 }
04643 }
04644 image->set_shuffled(true);
04645 }
04646
04647 void Phase180Processor::fourier_phaseshift180(EMData * image)
04648 {
04649 if ( !image->is_complex() ) throw ImageFormatException("Can not handle images that are not complex in fourier phase shift 180");
04650
04651 int nx = image->get_xsize();
04652 int ny = image->get_ysize();
04653 int nz = image->get_zsize();
04654
04655 int nxy = nx * ny;
04656
04657 float *rdata = image->get_data();
04658
04659
04660
04661 int of=0;
04662 if (((ny/2)%2)+((nz/2)%2)==1) of=1;
04663
04664 for (int k = 0; k < nz; k++) {
04665 size_t k2 = k * nxy;
04666
04667 for (int j = 0; j < ny; j++) {
04668 int i = ((k+j)%2==of?2:0);
04669 size_t j2 = j * nx + k2;
04670
04671 for (; i < nx; i += 4) {
04672 rdata[i + j2] *= -1.0f;
04673 rdata[i + j2 + 1] *= -1.0f;
04674 }
04675 }
04676 }
04677 }
04678
04679 void Phase180Processor::swap_corners_180(EMData * image)
04680 {
04681 int nx = image->get_xsize();
04682 int ny = image->get_ysize();
04683 int nz = image->get_zsize();
04684
04685 int xodd = (nx % 2) == 1;
04686 int yodd = (ny % 2) == 1;
04687 int zodd = (nz % 2) == 1;
04688
04689 int nxy = nx * ny;
04690
04691 float *rdata = image->get_data();
04692
04693 if ( ny == 1 && nz == 1 ){
04694 throw ImageDimensionException("Error, cannot handle 1D images. This function should not have been called");
04695 }
04696 else if ( nz == 1 ) {
04697
04698
04699 for ( int r = 0; r < ny/2; ++r ) {
04700 for ( int c = 0; c < nx/2; ++c) {
04701 int idx1 = r*nx + c;
04702 int idx2 = (r+ny/2+yodd)*nx + c + nx/2+xodd;
04703 float tmp = rdata[idx1];
04704 rdata[idx1] = rdata[idx2];
04705 rdata[idx2] = tmp;
04706 }
04707 }
04708
04709
04710 for ( int r = ny-1; r >= (ny/2+yodd); --r ) {
04711 for ( int c = 0; c < nx/2; ++c) {
04712 int idx1 = r*nx + c;
04713 int idx2 = (r-ny/2-yodd)*nx + c + nx/2+xodd;
04714 float tmp = rdata[idx1];
04715 rdata[idx1] = rdata[idx2];
04716 rdata[idx2] = tmp;
04717 }
04718 }
04719 }
04720 else
04721 {
04722 float tmp;
04723
04724 size_t idx1, idx2;
04725
04726 for ( int s = 0; s < nz/2; ++s ) {
04727 for ( int r = 0; r < ny/2; ++r ) {
04728 for ( int c = 0; c < nx/2; ++ c) {
04729 idx1 = s*nxy+r*nx+c;
04730 idx2 = (s+nz/2+zodd)*nxy+(r+ny/2+yodd)*nx+c+nx/2+xodd;
04731 tmp = rdata[idx1];
04732 rdata[idx1] = rdata[idx2];
04733 rdata[idx2] = tmp;
04734 }
04735 }
04736 }
04737
04738 for ( int s = 0; s < nz/2; ++s ) {
04739 for ( int r = 0; r < ny/2; ++r ) {
04740 for ( int c = nx-1; c >= (nx/2+xodd); --c) {
04741 idx1 = s*nxy+r*nx+c;
04742 idx2 = (s+nz/2+zodd)*nxy+(r+ny/2+yodd)*nx+c-nx/2-xodd;
04743 tmp = rdata[idx1];
04744 rdata[idx1] = rdata[idx2];
04745 rdata[idx2] = tmp;
04746 }
04747 }
04748 }
04749
04750 for ( int s = 0; s < nz/2; ++s ) {
04751 for ( int r = ny-1; r >= (ny/2+yodd); --r ) {
04752 for ( int c = nx-1; c >= (nx/2+xodd); --c) {
04753 idx1 = s*nxy+r*nx+c;
04754 idx2 = (s+nz/2+zodd)*nxy+(r-ny/2-yodd)*nx+c-nx/2-xodd;
04755 tmp = rdata[idx1];
04756 rdata[idx1] = rdata[idx2];
04757 rdata[idx2] = tmp;
04758 }
04759 }
04760 }
04761
04762 for ( int s = 0; s < nz/2; ++s ) {
04763 for ( int r = ny-1; r >= (ny/2+yodd); --r ) {
04764 for ( int c = 0; c < nx/2; ++c) {
04765 idx1 = s*nxy+r*nx+c;
04766 idx2 = (s+nz/2+zodd)*nxy+(r-ny/2-yodd)*nx+c+nx/2+xodd;
04767 tmp = rdata[idx1];
04768 rdata[idx1] = rdata[idx2];
04769 rdata[idx2] = tmp;
04770 }
04771 }
04772 }
04773 }
04774 }
04775
04776 void Phase180Processor::swap_central_slices_180(EMData * image)
04777 {
04778 int nx = image->get_xsize();
04779 int ny = image->get_ysize();
04780 int nz = image->get_zsize();
04781
04782 int xodd = (nx % 2) == 1;
04783 int yodd = (ny % 2) == 1;
04784 int zodd = (nz % 2) == 1;
04785
04786 int nxy = nx * ny;
04787
04788 float *rdata = image->get_data();
04789
04790 if ( ny == 1 && nz == 1 ){
04791 throw ImageDimensionException("Error, cannot handle 1D images. This function should not have been called");
04792 }
04793 else if ( nz == 1 ) {
04794 float tmp;
04795 if ( yodd ) {
04796
04797 int r = ny/2;
04798 for ( int c = 0; c < nx/2; ++c ) {
04799 int idx1 = r*nx + c;
04800 int idx2 = r*nx + c + nx/2+ xodd;
04801 tmp = rdata[idx1];
04802 rdata[idx1] = rdata[idx2];
04803 rdata[idx2] = tmp;
04804 }
04805 }
04806
04807 if ( xodd ) {
04808
04809 int c = nx/2;
04810 for ( int r = 0; r < ny/2; ++r ) {
04811 int idx1 = r*nx + c;
04812 int idx2 = (r+ny/2+yodd)*nx + c;
04813 tmp = rdata[idx1];
04814 rdata[idx1] = rdata[idx2];
04815 rdata[idx2] = tmp;
04816 }
04817 }
04818 }
04819 else
04820 {
04821 float tmp;
04822 if ( xodd ) {
04823
04824 int c = nx/2;
04825 size_t idx1, idx2;
04826 for( int s = 0; s < nz/2; ++s ) {
04827 for ( int r = 0; r < ny/2; ++r ) {
04828 idx1 = s*nxy+r*nx+c;
04829 idx2 = (s+nz/2+zodd)*nxy+(r+ny/2+yodd)*nx+c;
04830 tmp = rdata[idx1];
04831 rdata[idx1] = rdata[idx2];
04832 rdata[idx2] = tmp;
04833 }
04834 }
04835
04836 for( int s = nz-1; s >= (nz/2+zodd); --s ) {
04837 for ( int r = 0; r < ny/2; ++r ) {
04838 idx1 = s*nxy+r*nx+c;
04839 idx2 = (s-nz/2-zodd)*nxy+(r+ny/2+yodd)*nx+c;
04840 tmp = rdata[idx1];
04841 rdata[idx1] = rdata[idx2];
04842 rdata[idx2] = tmp;
04843 }
04844 }
04845 }
04846 if ( yodd ) {
04847
04848 int r = ny/2;
04849 size_t idx1, idx2;
04850 for( int s = 0; s < nz/2; ++s ) {
04851 for ( int c = 0; c < nx/2; ++c ) {
04852 idx1 = s*nxy+r*nx+c;
04853 idx2 =(s+nz/2+zodd)*nxy+r*nx+c+nx/2+xodd;
04854 tmp = rdata[idx1];
04855 rdata[idx1] = rdata[idx2];
04856 rdata[idx2] = tmp;
04857 }
04858 }
04859
04860 for( int s = nz-1; s >= (nz/2+zodd); --s ) {
04861 for ( int c = 0; c < nx/2; ++c ) {
04862 idx1 = s*nxy+r*nx+c;
04863 idx2 = (s-nz/2-zodd)*nxy+r*nx+c+nx/2+xodd;
04864 tmp = rdata[idx1];
04865 rdata[idx1] = rdata[idx2];
04866 rdata[idx2] = tmp;
04867 }
04868 }
04869 }
04870 if ( zodd ) {
04871
04872 int s = nz/2;
04873 size_t idx1, idx2;
04874 for( int r = 0; r < ny/2; ++r ) {
04875 for ( int c = 0; c < nx/2; ++c ) {
04876 idx1 = s*nxy+r*nx+c;
04877 idx2 = s*nxy+(r+ny/2+yodd)*nx+c+nx/2+xodd;
04878 tmp = rdata[idx1];
04879 rdata[idx1] = rdata[idx2];
04880 rdata[idx2] = tmp;
04881 }
04882 }
04883
04884 for( int r = ny-1; r >= (ny/2+yodd); --r ) {
04885 for ( int c = 0; c < nx/2; ++c ) {
04886 idx1 = s*nxy+r*nx+c;
04887 idx2 = s*nxy+(r-ny/2-yodd)*nx+c+nx/2+xodd;
04888 tmp = rdata[idx1];
04889 rdata[idx1] = rdata[idx2];
04890 rdata[idx2] = tmp;
04891 }
04892 }
04893 }
04894 }
04895 }
04896
04897 void PhaseToCornerProcessor::process_inplace(EMData * image)
04898 {
04899 if (!image) throw NullPointerException("Error: attempt to phase shift a null image");
04900
04901 if (image->is_complex()) {
04902 fourier_phaseshift180(image);
04903 return;
04904 }
04905
04906 int nx = image->get_xsize();
04907 int ny = image->get_ysize();
04908 int nz = image->get_zsize();
04909
04910 if ( ny == 1 && nz == 1 && nx == 1) return;
04911
04912 int nxy = nx * ny;
04913
04914 float *rdata = image->get_data();
04915
04916 bool xodd = (nx % 2) == 1;
04917 bool yodd = (ny % 2) == 1;
04918 bool zodd = (nz % 2) == 1;
04919
04920 if ( ny == 1 && nz == 1 ){
04921 if (xodd){
04922
04923
04924 float in_x = rdata[nx-1];
04925 float tmp;
04926 for ( int i = nx/2; i < nx; ++i ) {
04927 tmp = rdata[i];
04928 rdata[i] = in_x;
04929 in_x = tmp;
04930 }
04931 }
04932
04933 for ( int i = 0; i < nx/2; ++i ) {
04934 int idx = i+nx/2+xodd;
04935 float tmp = rdata[i];
04936 rdata[i] = rdata[idx];
04937 rdata[idx] = tmp;
04938 }
04939
04940 }
04941 else if ( nz == 1 ) {
04942 if (yodd) {
04943
04944
04945 for ( int c = 0; c < nx; ++c ) {
04946
04947 float last_val = rdata[(ny-1)*nx + c];
04948 float tmp;
04949 for ( int r = ny/2; r < ny; ++r ){
04950 int idx =r*nx+c;
04951 tmp = rdata[idx];
04952 rdata[idx] = last_val;
04953 last_val = tmp;
04954 }
04955 }
04956 }
04957
04958 if (xodd) {
04959
04960
04961 for ( int r = 0; r < ny; ++r ) {
04962 float last_val = rdata[(r+1)*nx -1];
04963 float tmp;
04964 for ( int c = nx/2; c < nx; ++c ){
04965 int idx =r*nx+c;
04966 tmp = rdata[idx];
04967 rdata[idx] = last_val;
04968 last_val = tmp;
04969 }
04970 }
04971 }
04972
04973 swap_central_slices_180(image);
04974
04975 swap_corners_180(image);
04976
04977 }
04978 else
04979 {
04980 float tmp;
04981 if (zodd) {
04982
04983
04984 size_t idx = 0;
04985 for (int r = 0; r < ny; ++r){
04986 for (int c = 0; c < nx; ++c) {
04987 float last_val = rdata[(nz-1)*nxy+r*nx+c];
04988 for (int s = nz/2; s < nz; ++s) {
04989 idx = s*nxy+r*nx+c;
04990 tmp = rdata[idx];
04991 rdata[idx] = last_val;
04992 last_val = tmp;
04993 }
04994 }
04995 }
04996 }
04997 if (yodd) {
04998
04999
05000 size_t idx = 0;
05001 for (int s = 0; s < nz; ++s) {
05002 for (int c = 0; c < nx; ++c) {
05003 float last_val = rdata[s*nxy+(ny-1)*nx+c];
05004 for (int r = ny/2; r < ny; ++r){
05005 idx = s*nxy+r*nx+c;
05006 tmp = rdata[idx];
05007 rdata[idx] = last_val;
05008 last_val = tmp;
05009 }
05010 }
05011 }
05012 }
05013 if (xodd) {
05014
05015
05016 size_t idx = 0;
05017 for (int s = 0; s < nz; ++s) {
05018 for (int r = 0; r < ny; ++r) {
05019 float last_val = rdata[s*nxy+r*nx+nx-1];
05020 for (int c = nx/2; c < nx; ++c){
05021 idx = s*nxy+r*nx+c;
05022 tmp = rdata[idx];
05023 rdata[idx] = last_val;
05024 last_val = tmp;
05025 }
05026 }
05027 }
05028 }
05029
05030 swap_central_slices_180(image);
05031
05032 swap_corners_180(image);
05033 }
05034 }
05035
05036
05037 void PhaseToCenterProcessor::process_inplace(EMData * image)
05038 {
05039 if (!image) throw NullPointerException("Error: attempt to phase shift a null image");
05040 bool proceed = true;
05041
05042 #ifdef EMAN2_USING_CUDA
05043 bool cpu = image->cpu_rw_is_current();
05044 bool gpu = image->gpu_rw_is_current();
05045 if ( !cpu && !gpu )
05046 throw UnexpectedBehaviorException("Both the CPU and GPU data are not current");
05047 if (gpu && image->get_ndim() == 2) {
05048 EMDataForCuda tmp = image->get_data_struct_for_cuda();
05049 emdata_phaseorigin_to_center(&tmp);
05050 proceed = false;
05051 image->gpu_update();
05052 }
05053 #endif // EMAN2_USING_CUDA
05054 if (!proceed) return;
05055
05056 if (image->is_complex()) {
05057 fourier_phaseshift180(image);
05058 return;
05059 }
05060
05061 int nx = image->get_xsize();
05062 int ny = image->get_ysize();
05063 int nz = image->get_zsize();
05064
05065 if ( ny == 1 && nz == 1 && nx == 1) return;
05066
05067 int nxy = nx * ny;
05068
05069 float *rdata = image->get_data();
05070
05071 bool xodd = (nx % 2) == 1;
05072 bool yodd = (ny % 2) == 1;
05073 bool zodd = (nz % 2) == 1;
05074
05075 if ( ny == 1 && nz == 1 ){
05076 if (xodd) {
05077
05078
05079 float in_x = rdata[nx/2];
05080 float tmp;
05081 for ( int i = nx-1; i >= nx/2; --i ) {
05082 tmp = rdata[i];
05083 rdata[i] = in_x;
05084 in_x = tmp;
05085 }
05086 }
05087
05088 for ( int i = 0; i < nx/2; ++i ) {
05089 int idx = i + nx/2;
05090 float tmp = rdata[i];
05091 rdata[i] = rdata[idx];
05092 rdata[idx] = tmp;
05093 }
05094 }
05095 else if ( nz == 1 ){
05096
05097
05098
05099 swap_corners_180(image);
05100
05101 swap_central_slices_180(image);
05102
05103 float tmp;
05104
05105 if (xodd) {
05106
05107
05108 for ( int r = 0; r < ny; ++r ) {
05109 float last_val = rdata[r*nx+nx/2];
05110 for ( int c = nx-1; c >= nx/2; --c ){
05111 int idx = r*nx+c;
05112 tmp = rdata[idx];
05113 rdata[idx] = last_val;
05114 last_val = tmp;
05115 }
05116 }
05117 }
05118 if (yodd) {
05119
05120
05121 for ( int c = 0; c < nx; ++c ) {
05122
05123 float last_val = rdata[ny/2*nx + c];
05124 for ( int r = ny-1; r >= ny/2; --r ){
05125 int idx = r*nx+c;
05126 tmp = rdata[idx];
05127 rdata[idx] = last_val;
05128 last_val = tmp;
05129 }
05130 }
05131 }
05132 }
05133 else
05134 {
05135
05136
05137
05138 swap_corners_180(image);
05139
05140 swap_central_slices_180(image);
05141
05142 float tmp;
05143
05144 if (xodd) {
05145
05146
05147
05148 size_t idx = 0;
05149 for (int s = 0; s < nz; ++s) {
05150 for (int r = 0; r < ny; ++r) {
05151 float last_val = rdata[s*nxy+r*nx+nx/2];
05152 for (int c = nx-1; c >= nx/2; --c){
05153 idx = s*nxy+r*nx+c;
05154 tmp = rdata[idx];
05155 rdata[idx] = last_val;
05156 last_val = tmp;
05157 }
05158 }
05159 }
05160 }
05161 if (yodd) {
05162
05163
05164 size_t idx = 0;
05165 for (int s = 0; s < nz; ++s) {
05166 for (int c = 0; c < nx; ++c) {
05167 float last_val = rdata[s*nxy+ny/2*nx+c];
05168 for (int r = ny-1; r >= ny/2; --r){
05169 idx = s*nxy+r*nx+c;
05170 tmp = rdata[idx];
05171 rdata[idx] = last_val;
05172 last_val = tmp;
05173 }
05174 }
05175 }
05176 }
05177 if (zodd) {
05178
05179
05180 size_t idx = 0;
05181 for (int r = 0; r < ny; ++r){
05182 for (int c = 0; c < nx; ++c) {
05183 float last_val = rdata[nz/2*nxy+r*nx+c];
05184 for (int s = nz-1; s >= nz/2; --s) {
05185 idx = s*nxy+r*nx+c;
05186 tmp = rdata[idx];
05187 rdata[idx] = last_val;
05188 last_val = tmp;
05189 }
05190 }
05191 }
05192 }
05193
05194
05195 }
05196 }
05197
05198 void AutoMaskAsymUnit::process_inplace(EMData* image) {
05199 if (!image) {
05200 LOGWARN("NULL Image");
05201 return;
05202 }
05203
05204 int nx = image->get_xsize();
05205 int ny = image->get_ysize();
05206 int nz = image->get_zsize();
05207
05208 int ox = nx/2;
05209 int oy = ny/2;
05210 int oz = nz/2;
05211
05212 Symmetry3D* sym = Factory<Symmetry3D>::get((string)params["sym"]);
05213 int au = params.set_default("au",0);
05214
05215 float *d = image->get_data();
05216 for(int k = 0; k < nz; ++k ) {
05217 for(int j = 0; j < ny; ++j ) {
05218 for (int i = 0; i< nx; ++i, ++d) {
05219
05220 Vec3f v(i-ox,j-oy,k-oz);
05221
05222 int a = sym->point_in_which_asym_unit(v);
05223 if (au == -1) {
05224 *d = (float)a;
05225 } else {
05226 if ( a == au ) *d = 1;
05227 else *d = 0;
05228 }
05229 }
05230 }
05231 }
05232
05233 delete sym;
05234
05235 }
05236
05237 void AutoMask2DProcessor::process_inplace(EMData * image)
05238 {
05239 if (!image) {
05240 LOGWARN("NULL Image");
05241 return;
05242 }
05243
05244 if (image->get_ndim() != 2) {
05245 throw ImageDimensionException("This processor only supports 2D images.");
05246 }
05247
05248
05249
05250
05251
05252
05253
05254
05255
05256
05257
05258 int radius=0;
05259 if (params.has_key("radius")) {
05260 radius = params["radius"];
05261 }
05262 int nmaxseed=0;
05263 if (params.has_key("nmaxseed")) {
05264 nmaxseed = params["nmaxseed"];
05265 }
05266
05267 float threshold=0.0;
05268 if (params.has_key("sigma")) threshold=(float)(image->get_attr("mean"))+(float)(image->get_attr("sigma"))*(float)params["sigma"];
05269 else threshold=params["threshold"];
05270
05271
05272 int nshells = params["nshells"];
05273 int nshellsgauss = params["nshellsgauss"];
05274 int verbose=params.set_default("verbose",0);
05275
05276 int nx = image->get_xsize();
05277 int ny = image->get_ysize();
05278
05279 EMData *amask = new EMData();
05280 amask->set_size(nx, ny);
05281
05282 float *dat = image->get_data();
05283 float *dat2 = amask->get_data();
05284 int i,j,k;
05285 size_t l = 0;
05286
05287 if (verbose) printf("%f\t%f\t%f\n",(float)image->get_attr("mean"),(float)image->get_attr("sigma"),threshold);
05288
05289
05290 if (nmaxseed>0) {
05291 vector<Pixel> maxs=image->calc_n_highest_locations(nmaxseed);
05292
05293 for (vector<Pixel>::iterator i=maxs.begin(); i<maxs.end(); i++) {
05294 amask->set_value_at((*i).x,(*i).y,0,1.0);
05295 if (verbose) printf("Seed at %d,%d,%d (%1.3f)\n",(*i).x,(*i).y,(*i).z,(*i).value);
05296 }
05297 }
05298
05299
05300 if (radius>0) {
05301
05302 l=0;
05303 for (j = -ny / 2; j < ny / 2; ++j) {
05304 for (i = -nx / 2; i < nx / 2; ++i,++l) {
05305 if ( abs(j) > radius || abs(i) > radius) continue;
05306
05307 if ( (j * j + i * i) > (radius*radius) ) continue;
05308 dat2[l] = 1.0f;
05309 }
05310 }
05311 }
05312
05313
05314 int done=0;
05315 int iter=0;
05316 while (!done) {
05317 iter++;
05318 done=1;
05319 if (verbose && iter%10==0) printf("%d iterations\n",iter);
05320 for (j=1; j<ny-1; ++j) {
05321 for (i=1; i<nx-1; ++i) {
05322 l=i+j*nx;
05323 if (dat2[l]) continue;
05324 if (dat[l]>threshold && (dat2[l-1]||dat2[l+1]||dat2[l+nx]||dat2[l-nx])) {
05325 dat2[l]=1.0;
05326 done=0;
05327 }
05328 }
05329 }
05330 }
05331
05332 amask->update();
05333
05334 if (verbose) printf("extending mask\n");
05335 amask->process_inplace("mask.addshells.gauss", Dict("val1", nshells, "val2", nshellsgauss));
05336
05337 bool return_mask = params.set_default("return_mask",false);
05338 if (return_mask) {
05339
05340 memcpy(dat,dat2,image->get_size()*sizeof(float));
05341 } else {
05342 image->mult(*amask);
05343 }
05344
05345
05346
05347
05348
05349
05350
05351 delete amask;
05352 }
05353
05354
05355 void AddRandomNoiseProcessor::process_inplace(EMData * image)
05356 {
05357 if (!image) {
05358 LOGWARN("NULL Image");
05359 return;
05360 }
05361
05362 if (!image->is_complex()) {
05363 LOGERR("AddRandomNoise Processor only works for complex image");
05364 throw ImageFormatException("only work for complex image");
05365 }
05366
05367 int n = params["n"];
05368 float x0 = params["x0"];
05369 float dx = params["dx"];
05370 vector < float >y = params["y"];
05371
05372 int interpolation = 1;
05373 if (params.has_key("interpolation")) {
05374 interpolation = params["interpolation"];
05375 }
05376
05377 Randnum * randnum = Randnum::Instance();
05378 if(params.has_key("seed")) {
05379 randnum->set_seed((int)params["seed"]);
05380 }
05381
05382 int nx = image->get_xsize();
05383 int ny = image->get_ysize();
05384 int nz = image->get_zsize();
05385
05386 image->ap2ri();
05387 float *rdata = image->get_data();
05388
05389 size_t k = 0;
05390 float half_nz = 0;
05391 if (nz > 1) {
05392 half_nz = nz / 2.0f;
05393 }
05394
05395 const float sqrt_2 = sqrt((float) 2);
05396
05397 float r;
05398 for (int h = 0; h < nz; h++) {
05399 for (int j = 0; j < ny; j++) {
05400 for (int i = 0; i < nx; i += 2, k += 2) {
05401 r = (Util::hypot3(i / 2.0f, j - ny / 2.0f, h - half_nz));
05402
05403 r = (r - x0) / dx;
05404 int l = 0;
05405 if (interpolation) {
05406 l = Util::fast_floor(r);
05407 }
05408 else {
05409 l = Util::fast_floor(r + 0.5f);
05410 }
05411 r -= l;
05412 float f = 0;
05413 if (l >= n - 2) {
05414 f = y[n - 1];
05415 }
05416 else if (l < 0) {
05417 l = 0;
05418 }
05419 else {
05420 if (interpolation) {
05421 f = (y[l] * (1 - r) + y[l + 1] * r);
05422 }
05423 else {
05424 f = y[l];
05425 }
05426 }
05427 f = randnum->get_gauss_rand(sqrt(f), sqrt(f) / 3);
05428 float a = randnum->get_frand(0.0f, (float)(2 * M_PI));
05429 if (i == 0) {
05430 f *= sqrt_2;
05431 }
05432 rdata[k] += f * cos(a);
05433 rdata[k + 1] += f * sin(a);
05434 }
05435 }
05436 }
05437
05438 image->update();
05439 }
05440
05441 void AddMaskShellProcessor::process_inplace(EMData * image)
05442 {
05443 if (!image) {
05444 LOGWARN("NULL Image");
05445 return;
05446 }
05447
05448 int nx = image->get_xsize();
05449 int ny = image->get_ysize();
05450 int nz = image->get_zsize();
05451
05452 if (ny == 1) {
05453 LOGERR("Tried to add mask shell to 1d image");
05454 return;
05455 }
05456
05457 int num_shells = params["nshells"];
05458
05459 float *d = image->get_data();
05460 float k = 0.99999f;
05461 int nxy = nx * ny;
05462
05463 if (nz == 1) {
05464 for (int i = 0; i < num_shells; i++) {
05465 for (int y = 1; y < ny - 1; y++) {
05466 int cur_y = y * nx;
05467
05468 for (int x = 1; x < nx - 1; x++) {
05469 int j = x + cur_y;
05470 if (!d[j] && (d[j - 1] > k || d[j + 1] > k || d[j + nx] > k || d[j - nx] > k)) {
05471 d[j] = k;
05472 }
05473 }
05474 }
05475 k -= 0.00001f;
05476 }
05477 }
05478 else {
05479 for (int i = 0; i < num_shells; i++) {
05480 for (int z = 1; z < nz - 1; z++) {
05481 size_t cur_z = z * nx * ny;
05482
05483 for (int y = 1; y < ny - 1; y++) {
05484 size_t cur_y = y * nx + cur_z;
05485
05486 for (int x = 1; x < nx - 1; x++) {
05487 size_t j = x + cur_y;
05488
05489 if (!d[j] && (d[j - 1] > k || d[j + 1] > k || d[j + nx] > k ||
05490 d[j - nx] > k || d[j - nxy] > k || d[j + nxy] > k)) {
05491 d[j] = k;
05492 }
05493 }
05494 }
05495 }
05496
05497 k -= 0.00001f;
05498 }
05499 }
05500
05501 size_t size = nx * ny * nz;
05502 for (size_t i = 0; i < size; i++) {
05503 if (d[i]) {
05504 d[i] = 1;
05505 }
05506 else {
05507 d[i] = 0;
05508 }
05509 }
05510
05511 image->update();
05512 }
05513
05514 void ToMassCenterProcessor::process_inplace(EMData * image)
05515 {
05516 if (!image) {
05517 LOGWARN("NULL Image");
05518 return;
05519 }
05520
05521 int int_shift_only = params.set_default("int_shift_only",1);
05522
05523
05524 if ((float)image->get_attr("sigma")==0.0f) return;
05525
05526 FloatPoint com = image->calc_center_of_mass();
05527
05528 int nx = image->get_xsize();
05529 int ny = image->get_ysize();
05530 int nz = image->get_zsize();
05531
05532 if (int_shift_only) {
05533 int dx = -(int)(floor(com[0] + 0.5f) - nx / 2);
05534 int dy = -(int)(floor(com[1] + 0.5f) - ny / 2);
05535 int dz = 0;
05536 if (nz > 1) {
05537 dz = -(int)(floor(com[2] + 0.5f) - nz / 2);
05538 }
05539 image->translate(dx, dy, dz);
05540
05541 Transform t;
05542 t.set_trans((float)dx,(float)dy,(float)dz);
05543
05544 if (nz > 1) {
05545 image->set_attr("xform.align3d",&t);
05546 } else {
05547 image->set_attr("xform.align2d",&t);
05548 }
05549 }
05550 else {
05551 float dx = -(com[0] - nx / 2);
05552 float dy = -(com[1] - ny / 2);
05553 float dz = 0;
05554 if (nz > 1) {
05555 dz = -(com[2] - nz / 2);
05556 }
05557 image->translate(dx, dy, dz);
05558
05559 Transform t;
05560 t.set_trans(dx,dy,dz);
05561
05562 if (nz > 1) {
05563 image->set_attr("xform.align3d",&t);
05564 } else {
05565 image->set_attr("xform.align2d",&t);
05566 }
05567 }
05568 }
05569
05570 void PhaseToMassCenterProcessor::process_inplace(EMData * image)
05571 {
05572 if (!image) {
05573 LOGWARN("NULL Image");
05574 return;
05575 }
05576
05577 int int_shift_only = params.set_default("int_shift_only",1);
05578
05579 vector<float> pcog = image->phase_cog();
05580
05581 int dims = image->get_ndim();
05582
05583 if (int_shift_only) {
05584 int dx=-int(pcog[0]+0.5f),dy=0,dz=0;
05585 if ( dims >= 2 ) dy = -int(pcog[1]+0.5);
05586 if ( dims == 3 ) dz = -int(pcog[2]+0.5);
05587
05588 Transform t;
05589 t.set_trans((float)dx,(float)dy,(float)dz);
05590 if (dims == 3) image->set_attr("xform.align3d",&t);
05591 else if (dims == 2) image->set_attr("xform.align2d",&t);
05592
05593 image->translate(dx,dy,dz);
05594 } else {
05595 float dx=-pcog[0],dy=0.0,dz=0.0;
05596 if ( dims >= 2 ) dy = -pcog[1];
05597 if ( dims == 3 ) dz = -pcog[2];
05598 image->translate(dx,dy,dz);
05599
05600 Transform t;
05601 t.set_trans(dx,dy,dz);
05602 if (dims == 3) image->set_attr("xform.align3d",&t);
05603 else if (dims == 2) image->set_attr("xform.align2d",&t);
05604 }
05605 }
05606
05607 void ACFCenterProcessor::process_inplace(EMData * image)
05608 {
05609 if (!image) {
05610 LOGWARN("NULL Image");
05611 return;
05612 }
05613
05614 Dict params1;
05615 params1["intonly"] = 1;
05616 params1["maxshift"] = image->get_xsize() / 4;
05617 EMData* aligned = image->align("translational", 0, params1);
05618 if ( image->get_ndim() == 3 ) {
05619 Transform* t = aligned->get_attr("xform.align3d");
05620 image->translate(t->get_trans());
05621 image->set_attr("xform.align3d",t);
05622 delete t;
05623 }
05624 else {
05625
05626 Transform* t = aligned->get_attr("xform.align2d");
05627 image->translate(t->get_trans());
05628 image->set_attr("xform.align2d",t);
05629 delete t;
05630 }
05631
05632 delete aligned;
05633
05634 }
05635
05636 void SNRProcessor::process_inplace(EMData * image)
05637 {
05638 if (!image) {
05639 return;
05640 }
05641
05642 int wiener = params["wiener"];
05643 const char *snrfile = params["snrfile"];
05644
05645 XYData sf;
05646 int err = sf.read_file(snrfile);
05647 if (err) {
05648 LOGERR("couldn't read structure factor file!");
05649 return;
05650 }
05651
05652
05653 for (size_t i = 0; i < sf.get_size(); i++) {
05654 if (sf.get_y(i) <= 0) {
05655 sf.set_y(i, -4.0f);
05656 }
05657 else {
05658 sf.set_y(i, log10(sf.get_y(i)));
05659 }
05660 }
05661 sf.update();
05662
05663 Ctf *image_ctf = image->get_ctf();
05664
05665 vector < float >ctf;
05666 if (wiener) {
05667 ctf = image_ctf->compute_1d(image->get_ysize(),1.0f/(image_ctf->apix*image->get_ysize()), Ctf::CTF_WIENER_FILTER, &sf);
05668 }
05669 else {
05670 ctf = image_ctf->compute_1d(image->get_ysize(),1.0f/(image_ctf->apix*image->get_ysize()), Ctf::CTF_SNR, &sf);
05671 }
05672
05673 if(image_ctf) {delete image_ctf; image_ctf=0;}
05674
05675 image->process_inplace("normalize.circlemean");
05676
05677 int nx = image->get_xsize();
05678 int ny = image->get_ysize();
05679
05680 Region clip_r(-nx / 2, -ny / 2, nx * 2, ny * 2);
05681 EMData *d3 = image->get_clip(clip_r);
05682 EMData *d2 = d3->do_fft();
05683
05684 d2->apply_radial_func(0, 2.0f / Ctf::CTFOS, ctf, 0);
05685
05686 if( d3 )
05687 {
05688 delete d3;
05689 d3 = 0;
05690 }
05691
05692 if( image )
05693 {
05694 delete image;
05695 image = 0;
05696 }
05697
05698 EMData *d1 = d2->do_ift();
05699 int d1_nx = d1->get_xsize();
05700 int d1_ny = d1->get_ysize();
05701 Region d1_r(d1_nx / 4, d1_ny / 4, d1_nx / 2, d1_ny / 2);
05702
05703 image = d1->get_clip(d1_r);
05704
05705 if( d1 )
05706 {
05707 delete d1;
05708 d1 = 0;
05709 }
05710
05711 if( d2 )
05712 {
05713 delete d2;
05714 d2 = 0;
05715 }
05716 }
05717
05718 void FileFourierProcessor::process_inplace(EMData * image)
05719 {
05720 if (!image) {
05721 LOGWARN("NULL Image");
05722 return;
05723 }
05724 const char *filename = params["filename"];
05725 float apix = params["apix"];
05726
05727 FILE *in = fopen(filename, "rb");
05728 if (!in) {
05729 LOGERR("FileFourierProcessor: cannot open file '%s'", filename);
05730 return;
05731 }
05732
05733 float f = 0;
05734 int n = 0;
05735 while (fscanf(in, " %f %f", &f, &f) == 2) {
05736 n++;
05737 }
05738 rewind(in);
05739
05740 vector < float >xd(n);
05741 vector < float >yd(n);
05742
05743 float sf = apix * image->get_xsize();
05744
05745 for (int i = 0; fscanf(in, " %f %f", &xd[i], &yd[i]) == 2; i++) {
05746 xd[i] *= sf;
05747 }
05748
05749 if (xd[2] - xd[1] != xd[1] - xd[0]) {
05750 LOGWARN("Warning, x spacing appears nonuniform %g!=%g\n",
05751 xd[2] - xd[1], xd[1] - xd[0]);
05752 }
05753
05754 EMData *d2 = image->do_fft();
05755 if( image )
05756 {
05757 delete image;
05758 image = 0;
05759 }
05760
05761 d2->apply_radial_func(xd[0], xd[1] - xd[0], yd, 1);
05762 image = d2->do_ift();
05763 }
05764
05765 void LocalNormProcessor::process_inplace(EMData * image)
05766 {
05767 if (!image) {
05768 LOGWARN("NULL Image");
05769 return;
05770 }
05771 float apix = params["apix"];
05772 float threshold = params["threshold"];
05773 float radius = params["radius"];
05774
05775 if (apix > 0) {
05776 int ny = image->get_ysize();
05777 radius = ny * apix / radius;
05778
05779 }
05780
05781 EMData *blur = image->copy();
05782 EMData *maskblur = image->copy();
05783
05784 maskblur->process_inplace("threshold.binary", Dict("value", threshold));
05785 maskblur->process_inplace("eman1.filter.lowpass.gaussian", Dict("lowpass", radius));
05786 maskblur->process_inplace("eman1.filter.highpass.tanh", Dict("highpass", -10.0f));
05787 maskblur->process_inplace("threshold.belowtozero", Dict("minval", 0.001f));
05788 maskblur->process_inplace("threshold.belowtozero", Dict("minval", 0.001f));
05789
05790
05791 blur->process_inplace("threshold.belowtozero", Dict("minval", threshold));
05792 blur->process_inplace("eman1.filter.lowpass.gaussian", Dict("lowpass", radius));
05793 blur->process_inplace("eman1.filter.highpass.tanh", Dict("highpass", -10.0f));
05794
05795 maskblur->div(*blur);
05796 image->mult(*maskblur);
05797 maskblur->write_image("norm.mrc", 0, EMUtil::IMAGE_MRC);
05798
05799 if( maskblur )
05800 {
05801 delete maskblur;
05802 maskblur = 0;
05803 }
05804
05805 if( blur )
05806 {
05807 delete blur;
05808 blur = 0;
05809 }
05810 }
05811
05812
05813 void SymSearchProcessor::process_inplace(EMData * image)
05814 {
05815 if (!image) {
05816 LOGWARN("NULL Image");
05817 return;
05818 }
05819 float thresh = params["thresh"];
05820 int output_symlabel = params["output_symlabel"];
05821
05822
05823 const vector<string> sym_list = params["sym"];
05824 int sym_num = sym_list.size();
05825 vector< vector< Transform > > transforms(sym_num);
05826 vector< float* > symvals(sym_num);
05827 for (int i =0; i < sym_num; i++) {
05828 vector<Transform> sym_transform = Symmetry3D::get_symmetries(sym_list[i]);
05829 transforms[i] = sym_transform;
05830 symvals[i] = new float[sym_transform.size()];
05831 }
05832
05833 EMData *orig = image->copy();
05834
05835 image->to_zero();
05836
05837 int nx= image->get_xsize();
05838 int ny= image->get_ysize();
05839 int nz= image->get_zsize();
05840 int xy = nx * ny;
05841 float * data = image->get_data();
05842 float * sdata = orig->get_data();
05843
05844 EMData *symlabel = 0;
05845 float * ldata = symlabel->get_data();
05846 if (output_symlabel) {
05847 symlabel = image->copy();
05848 symlabel->to_zero();
05849 ldata = symlabel->get_data();
05850 }
05851
05852 for (int k = 0; k < nz; k++) {
05853 for (int j = 0; j < ny; j++) {
05854 for(int i = 0; i < nx; i++) {
05855 size_t index = k * nx * ny + j * nx + i;
05856 float val = sdata[ index ];
05857 float bestmean = val, bestsymlevel = FLT_MAX;
05858 int bestsym = 0;
05859 for( int sym = 0; sym< sym_num; sym++) {
05860 int cur_sym_num = transforms[sym].size();
05861 float *symval = symvals[sym];
05862
05863 for( int s = 0; s < cur_sym_num; s++){
05864 Transform r = transforms[sym][s];
05865 float x2 = (float)(r[0][0] * (i-nx/2) + r[0][1] * (j-ny/2) + r[0][2] * (k-nz/2) + nx / 2);
05866 float y2 = (float)(r[1][0] * (i-nx/2) + r[1][1] * (j-ny/2) + r[1][2] * (k-nz/2) + ny / 2);
05867 float z2 = (float)(r[2][0] * (i-nx/2) + r[2][1] * (j-ny/2) + r[2][2] * (k-nz/2) + nz / 2);
05868
05869 if (x2 >= 0 && y2 >= 0 && z2 >= 0 && x2 < (nx - 1) && y2 < (ny - 1)
05870 && z2 < (nz - 1)) {
05871 float x = (float)Util::fast_floor(x2);
05872 float y = (float)Util::fast_floor(y2);
05873 float z = (float)Util::fast_floor(z2);
05874
05875 float t = x2 - x;
05876 float u = y2 - y;
05877 float v = z2 - z;
05878
05879 int ii = (int) (x + y * nx + z * xy);
05880
05881 symval[s]=
05882 Util::trilinear_interpolate(sdata[ii], sdata[ii + 1], sdata[ii + nx],
05883 sdata[ii + nx + 1], sdata[ii + nx * ny],
05884 sdata[ii + xy + 1], sdata[ii + xy + nx],
05885 sdata[ii + xy + nx + 1], t, u, v);
05886 }
05887 else {
05888 symval[s] = 0.0 ;
05889 }
05890 }
05891 float tmean=0, tsigma=0;
05892 for( int s = 0; s < cur_sym_num; s++) {
05893 tmean += symval[s];
05894 tsigma += symval[s] * symval[s];
05895 }
05896 tmean /= cur_sym_num;
05897 tsigma = tsigma/cur_sym_num - tmean*tmean;
05898 if (tsigma < bestsymlevel ) {
05899 bestsymlevel = tsigma;
05900 bestmean = tmean;
05901 bestsym = sym;
05902 }
05903 }
05904 if ( bestsymlevel > thresh) {
05905 if (output_symlabel) ldata[index] = (float)bestsym;
05906 data[index] = bestmean;
05907 }
05908 else {
05909 if (output_symlabel) ldata[index] = -1;
05910 data[index] = val;
05911 }
05912 }
05913 }
05914 }
05915 if( orig )
05916 {
05917 delete orig;
05918 orig = 0;
05919 }
05920 for (int i =0; i < sym_num; i++) {
05921 if( symvals[i] )
05922 {
05923 delete symvals[i];
05924 symvals[i] = 0;
05925 }
05926 }
05927 if (symlabel) params.put("symlabel_map", EMObject(symlabel));
05928 }
05929
05930
05931 void IndexMaskFileProcessor::process_inplace(EMData * image)
05932 {
05933 if (!image) {
05934 LOGWARN("NULL Image");
05935 return;
05936 }
05937
05938 const char *filename = params["filename"];
05939 EMData *msk = new EMData();
05940 msk->read_image(filename);
05941 if (!EMUtil::is_same_size(image, msk)) {
05942 LOGERR("IndexMaskFileProcessor: Mask size different than image");
05943 return;
05944 }
05945
05946 if ((int) params["ismaskset"] != 0) {
05947 msk->process_inplace("threshold.binaryrange", Dict("low", 0.5f, "high", 1.5f));
05948 }
05949
05950 image->mult(*msk);
05951 if( msk )
05952 {
05953 delete msk;
05954 msk = 0;
05955 }
05956 }
05957
05958
05959 void CoordinateMaskFileProcessor::process_inplace(EMData * image)
05960 {
05961 if (!image) {
05962 LOGWARN("NULL Image");
05963 return;
05964 }
05965
05966 const char *filename = params["filename"];
05967 EMData *msk = new EMData();
05968 msk->read_image(filename);
05969
05970 int nx = image->get_xsize();
05971 int ny = image->get_ysize();
05972 int nz = image->get_zsize();
05973
05974 int xm = msk->get_xsize();
05975 int ym = msk->get_ysize();
05976 int zm = msk->get_zsize();
05977
05978 float apix = image->get_attr("apix_x");
05979 float apixm = msk->get_attr("apix_x");
05980
05981 float xo = image->get_attr("origin_x");
05982 float yo = image->get_attr("origin_y");
05983 float zo = image->get_attr("origin_z");
05984
05985 float xom = msk->get_attr("origin_x");
05986 float yom = msk->get_attr("origin_y");
05987 float zom = msk->get_attr("origin_z");
05988
05989 float *dp = image->get_data();
05990 float *dpm = msk->get_data();
05991 int nxy = nx * ny;
05992
05993 for (int k = 0; k < nz; k++) {
05994 float zc = zo + k * apix;
05995 if (zc <= zom || zc >= zom + zm * apixm) {
05996 memset(&(dp[k * nxy]), 0, sizeof(float) * nxy);
05997 }
05998 else {
05999 int km = (int) ((zc - zom) / apixm);
06000
06001 for (int j = 0; j < ny; j++) {
06002 float yc = yo + j * apix;
06003 if (yc <= yom || yc >= yom + ym * apixm) {
06004 memset(&(dp[k * nxy + j * nx]), 0, sizeof(float) * nx);
06005 }
06006 else {
06007 int jm = (int) ((yc - yom) / apixm);
06008 size_t idx = 0;
06009 float xc;
06010 int im;
06011 for (int i = 0; i < nx; i++) {
06012 xc = xo + i * apix;
06013 idx = k * nxy + j * nx + i;
06014 if (xc <= xom || xc >= xom + xm * apixm) {
06015 dp[idx] = 0;
06016 }
06017 else {
06018 im = (int) ((xc - xom) / apixm);
06019 if (dpm[km * xm * ym + jm * xm + im] <= 0) {
06020 dp[idx] = 0;
06021 }
06022 }
06023 }
06024 }
06025 }
06026 }
06027 }
06028
06029 image->update();
06030 msk->update();
06031 if( msk )
06032 {
06033 delete msk;
06034 msk = 0;
06035 }
06036 }
06037
06038 void MatchSFProcessor::create_radial_func(vector < float >&radial_mask,EMData *image) const {
06039
06040
06041
06042 EMData *to = params["to"];
06043 XYData *sf = new XYData();
06044 float apixto = to->get_attr("apix_x");
06045
06046
06047 if (to->is_complex()) {
06048 vector<float> rd=to->calc_radial_dist(to->get_ysize()/2.0,0,1.0,1);
06049 for (size_t i=0; i<rd.size(); i++) {
06050 sf->set_x(i,i/(apixto*2.0f*rd.size()));
06051 sf->set_y(i,rd[i]);
06052 }
06053 }
06054 else {
06055 EMData *tmp=to->do_fft();
06056 vector<float> rd=tmp->calc_radial_dist(to->get_ysize()/2,0,1.0,1);
06057 for (size_t i=0; i<rd.size(); i++) {
06058 sf->set_x(i,i/(apixto*2.0f*rd.size()));
06059 sf->set_y(i,rd[i]);
06060 }
06061 delete tmp;
06062 }
06063
06064 float apix=image->get_attr("apix_x");
06065
06066 sf->write_file("a.txt");
06067 Util::save_data(0,sf->get_x(1),radial_mask,"b.txt");
06068
06069 int n = radial_mask.size();
06070 for (int i=0; i<n; i++) {
06071 if (radial_mask[i]>0) radial_mask[i]= sqrt(sf->get_yatx(i/(apix*2.0f*n))/radial_mask[i]);
06072 else if (i>0) radial_mask[i]=radial_mask[i-1];
06073 }
06074
06075 Util::save_data(0,sf->get_x(1),radial_mask,"c.txt");
06076
06077 delete sf;
06078 }
06079
06080 void SetSFProcessor::create_radial_func(vector < float >&radial_mask,EMData *image) const {
06081
06082
06083
06084 XYData *sf = params["strucfac"];
06085 if(params.has_key("apix")) {
06086 image->set_attr("apix_x", (float)params["apix"]);
06087 image->set_attr("apix_y", (float)params["apix"]);
06088 image->set_attr("apix_z", (float)params["apix"]);
06089 }
06090
06091 float apix=image->get_attr("apix_x");
06092
06093 int n = radial_mask.size();
06094 for (int i=0; i<n; i++) {
06095 if (radial_mask[i]>0) radial_mask[i]= n*n*n*sqrt(sf->get_yatx(i/(apix*2.0f*n))/radial_mask[i]);
06096 else if (i>0) radial_mask[i]=radial_mask[i-1];
06097 }
06098
06099 }
06100
06101 void SmartMaskProcessor::process_inplace(EMData * image)
06102 {
06103 if (!image) {
06104 LOGWARN("NULL Image");
06105 return;
06106 }
06107
06108 float mask = params["mask"];
06109
06110 int nx = image->get_xsize();
06111 int ny = image->get_ysize();
06112 int nz = image->get_zsize();
06113
06114 float *dat = image->get_data();
06115 double sma = 0;
06116 int smn = 0;
06117 float r = 0.0f;
06118 for (int k = 0; k < nz; ++k) {
06119 for (int j = 0; j < ny; ++j) {
06120 for (int i = 0; i < nx; ++i, ++dat) {
06121 r =
06122 sqrt((float) Util::square(i - nx / 2) + Util::square(j - ny / 2) +
06123 Util::square(k - nz / 2));
06124 if (r > mask - 1.5f && r < mask - 0.5f) {
06125 sma += *dat;
06126 smn++;
06127 }
06128 }
06129 }
06130 }
06131
06132 float smask = (float) sma / smn;
06133 image->update();
06134
06135 dat = image->get_data();
06136 for (int k = 0; k < nz; ++k) {
06137 for (int j = 0; j < ny; ++j) {
06138 for (int i = 0; i < nx; ++i, ++dat) {
06139 r =
06140 sqrt((float) Util::square(i - nx / 2) + Util::square(j - ny / 2) +
06141 Util::square(k - nz / 2));
06142 if (r > mask - .5) {
06143 *dat = 0;
06144 }
06145 else {
06146 *dat -= smask;
06147 }
06148 }
06149 }
06150 }
06151
06152 image->update();
06153 }
06154
06155 void AutoMask3DProcessor::search_nearby(float *dat, float *dat2, int nx, int ny, int nz, float threshold)
06156 {
06157 Assert(dat != 0);
06158 Assert(dat2 != 0);
06159 Assert(nx > 0);
06160 Assert(ny > 0);
06161
06162 bool done = false;
06163 int nxy = nx * ny;
06164
06165 while (!done) {
06166 done = true;
06167 for (int k = 1; k < nz - 1; k++) {
06168 size_t k2 = k * nxy;
06169 for (int j = 1; j < ny - 1; j++) {
06170 size_t l = j * nx + k2 + 1;
06171
06172 for (int i = 1; i < nx - 1; i++) {
06173 if (dat[l] >= threshold || dat2[l]) {
06174 if (dat2[l - 1] || dat2[l + 1] ||
06175 dat2[l - nx] || dat2[l + nx] || dat2[l - nxy] || dat2[l + nxy]) {
06176 dat2[l] = 1.0f;
06177 done = false;
06178 }
06179 }
06180 ++l;
06181 }
06182 }
06183 }
06184 }
06185 }
06186
06187 void AutoMask3DProcessor::fill_nearby(float *dat2, int nx, int ny, int nz)
06188 {
06189 Assert(dat2 != 0);
06190 Assert(nx > 0);
06191 Assert(ny > 0);
06192 Assert(nz >= 0);
06193
06194 int nxy = nx * ny;
06195 size_t idx;
06196 for (int i = 0; i < nx; i++) {
06197 for (int j = 0; j < ny; j++) {
06198 int j2 = j * nx + i;
06199 int k0 = 0;
06200 for (int k = 0; k < nz; k++) {
06201 idx = j2 + k * nxy;
06202 if (dat2[idx]) {
06203 k0 = k;
06204 break;
06205 }
06206 }
06207
06208 if (k0 != nz) {
06209 int k1 = nz - 1;
06210 for (int k = nz - 1; k >= 0; k--) {
06211 idx = j2 + k * nxy;
06212 if (dat2[idx]) {
06213 k1 = k;
06214 break;
06215 }
06216 }
06217
06218 for (int k = k0 + 1; k < k1; k++) {
06219 idx = j2 + k * nxy;
06220 dat2[idx] = 1.0f;
06221 }
06222 }
06223 }
06224 }
06225
06226 for (int i = 0; i < nx; i++) {
06227 for (int j = 0; j < nz; j++) {
06228 size_t j2 = j * nxy + i;
06229 int k0 = 0;
06230 for (int k = 0; k < ny; k++) {
06231 idx = k * nx + j2;
06232 if (dat2[idx]) {
06233 k0 = k;
06234 break;
06235 }
06236 }
06237
06238 if (k0 != ny) {
06239 int k1 = ny - 1;
06240 for (int k = ny - 1; k >= 0; k--) {
06241 idx = k * nx + j2;
06242 if (dat2[idx]) {
06243 k1 = k;
06244 break;
06245 }
06246 }
06247
06248 for (int k = k0 + 1; k < k1; k++) {
06249 idx = k * nx + j2;
06250 dat2[idx] = 1.0f;
06251 }
06252 }
06253 }
06254 }
06255
06256 for (int i = 0; i < ny; i++) {
06257 for (int j = 0; j < nz; j++) {
06258 size_t j2 = i * nx + j * nxy;
06259 int k0 = 0;
06260 for (int k = 0; k < nx; k++) {
06261 if (dat2[k + j2]) {
06262 k0 = k;
06263 break;
06264 }
06265 }
06266 if (k0 != nx) {
06267 int k1 = nx - 1;
06268 for (int k = nx - 1; k >= 0; k--) {
06269 if (dat2[k + j2]) {
06270 k1 = k;
06271 break;
06272 }
06273 }
06274
06275 for (int k = k0 + 1; k < k1; k++) {
06276 dat2[k + j2] = 1.0f;
06277 }
06278 }
06279 }
06280 }
06281
06282 }
06283
06284 void AutoMask3DProcessor::process_inplace(EMData * image)
06285 {
06286 if (!image) {
06287 LOGWARN("NULL Image");
06288 return;
06289 }
06290
06291 int nx = image->get_xsize();
06292 int ny = image->get_ysize();
06293 int nz = image->get_zsize();
06294
06295 EMData *amask = new EMData();
06296 amask->set_size(nx, ny, nz);
06297
06298 float sig = 0;
06299 float mean = 0;
06300
06301 if (params.has_key("threshold1") && params.has_key("threshold2")) {
06302 sig = image->get_attr("sigma");
06303 mean = image->get_attr("mean");
06304 }
06305
06306 float *dat = image->get_data();
06307 float *dat2 = amask->get_data();
06308
06309 float t = 0;
06310 if (params.has_key("threshold1")) {
06311 t = params["threshold1"];
06312 }
06313 else {
06314 t = mean + sig * 2.5f;
06315 }
06316
06317 size_t l = 0;
06318 for (int k = 0; k < nz; ++k) {
06319 for (int j = 0; j < ny; ++j) {
06320 for (int i = 0; i < nx; ++i) {
06321 if (dat[l] > t) {
06322 dat2[l] = 1.0f;
06323 }
06324 ++l;
06325 }
06326 }
06327 }
06328
06329
06330 if (params.has_key("threshold2")) {
06331 t = params["threshold2"];
06332 }
06333 else {
06334 t = mean + sig * 0.5f;
06335 }
06336
06337 search_nearby(dat, dat2, nx, ny, nz, t);
06338
06339 int nxy = nx * ny;
06340
06341 for (int k = 1; k < nz - 1; ++k) {
06342 for (int j = 1; j < ny - 1; ++j) {
06343 size_t l = j * nx + k * nxy + 1;
06344 for (int i = 1; i < nx - 1; ++i, ++l) {
06345 if (dat2[l - 1] == 1.0f || dat2[l + 1] == 1.0f ||
06346 dat2[l - nx] == 1.0f || dat2[l + nx] == 1.0f ||
06347 dat2[l - nxy] == 1.0f || dat2[l + nxy] == 1.0f) {
06348 dat2[l] = 2.0f;
06349 }
06350 }
06351 }
06352 }
06353
06354 size_t size = nx * ny * nz;
06355 for (size_t i = 0; i < size; i++) {
06356 if (dat2[i] == 2.0f) {
06357 dat2[i] = 1.0f;
06358 }
06359 }
06360
06361 fill_nearby(dat2, nx, ny, nz);
06362
06363 image->update();
06364 amask->update();
06365
06366 image->mult(*amask);
06367 amask->write_image("mask.mrc", 0, EMUtil::IMAGE_MRC);
06368 if( amask )
06369 {
06370 delete amask;
06371 amask = 0;
06372 }
06373 }
06374
06375
06376 void AutoMask3D2Processor::process_inplace(EMData * image)
06377 {
06378 if (!image) {
06379 LOGWARN("NULL Image");
06380 return;
06381 }
06382
06383 if (image->get_ndim() != 3) {
06384 throw ImageDimensionException("This processor was only ever designed to work on 3D images.");
06385 }
06386
06387
06388
06389
06390
06391
06392
06393
06394
06395
06396
06397 int radius=0;
06398 if (params.has_key("radius")) {
06399 radius = params["radius"];
06400 }
06401 int nmaxseed=0;
06402 if (params.has_key("nmaxseed")) {
06403 nmaxseed = params["nmaxseed"];
06404 }
06405
06406 float threshold=0.0;
06407 if (params.has_key("sigma")) threshold=(float)(image->get_attr("mean"))+(float)(image->get_attr("sigma"))*(float)params["sigma"];
06408 else threshold=params["threshold"];
06409
06410 int nshells = params["nshells"];
06411 int nshellsgauss = params["nshellsgauss"];
06412 int verbose=params.set_default("verbose",0);
06413
06414 int nx = image->get_xsize();
06415 int ny = image->get_ysize();
06416 int nz = image->get_zsize();
06417 int nxy=nx*ny;
06418
06419 EMData *amask = new EMData();
06420 amask->set_size(nx, ny, nz);
06421
06422 float *dat = image->get_data();
06423 float *dat2 = amask->get_data();
06424 int i,j,k;
06425 size_t l = 0;
06426
06427
06428 if (nmaxseed>0) {
06429 vector<Pixel> maxs=image->calc_n_highest_locations(nmaxseed);
06430
06431 for (vector<Pixel>::iterator i=maxs.begin(); i<maxs.end(); i++) {
06432 amask->set_value_at((*i).x,(*i).y,(*i).z,1.0);
06433 if (verbose) printf("Seed at %d,%d,%d (%1.3f)\n",(*i).x,(*i).y,(*i).z,(*i).value);
06434 }
06435 }
06436
06437
06438 if (radius>0) {
06439
06440 for (k = -nz / 2; k < nz / 2; ++k) {
06441 for (j = -ny / 2; j < ny / 2; ++j) {
06442 for (i = -nx / 2; i < nx / 2; ++i,++l) {
06443 if (abs(k) > radius || abs(j) > radius || abs(i) > radius) continue;
06444 if ( (k * k + j * j + i * i) > (radius*radius) || dat[l] < threshold) continue;
06445 dat2[l] = 1.0f;
06446 }
06447 }
06448 }
06449 }
06450
06451
06452
06453 int done=0;
06454 int iter=0;
06455 while (!done) {
06456 iter++;
06457 done=1;
06458 if (verbose && iter%10==0) printf("%d iterations\n",iter);
06459 for (k=1; k<nz-1; ++k) {
06460 for (j=1; j<ny-1; ++j) {
06461 for (i=1; i<nx-1; ++i) {
06462 l=i+j*nx+k*nx*ny;
06463 if (dat2[l]) continue;
06464 if (dat[l]>threshold && (dat2[l-1]||dat2[l+1]||dat2[l+nx]||dat2[l-nx]||dat2[l-nxy]||dat2[l+nxy])) {
06465 dat2[l]=1.0;
06466 done=0;
06467 }
06468 }
06469 }
06470 }
06471 }
06472
06473 amask->update();
06474
06475 if (verbose) printf("extending mask\n");
06476 amask->process_inplace("mask.addshells.gauss", Dict("val1", nshells, "val2", nshellsgauss));
06477
06478 bool return_mask = params.set_default("return_mask",false);
06479 if (return_mask) {
06480
06481 memcpy(dat,dat2,image->get_size()*sizeof(float));
06482 } else {
06483 image->mult(*amask);
06484 }
06485
06486
06487
06488
06489
06490
06491
06492 delete amask;
06493 }
06494
06495 void IterBinMaskProcessor::process_inplace(EMData * image)
06496 {
06497 if (!image) {
06498 LOGWARN("NULL Image");
06499 return;
06500 }
06501
06502 float val1 = params["val1"];
06503 float val2 = params["val2"];
06504
06505 int nx = image->get_xsize();
06506 int ny = image->get_ysize();
06507 int nz = image->get_zsize();
06508 EMData *image2 = new EMData(nx,ny,nz);
06509
06510
06511
06512
06513
06514
06515 float *d = image->get_data();
06516 float *d2 = image2->get_data();
06517
06518 const int nxy = nx * ny;
06519 size_t size = nx * ny * nz;
06520
06521
06522 if (nz != 1) {
06523 for (int l = 1; l <= (int) val1+val2; ++l) {
06524 for (size_t i=0; i<size; i++) d2[i]=d[i];
06525 for (int k = 1; k < nz - 1; ++k) {
06526 for (int j = 1; j < ny - 1; ++j) {
06527 for (int i = 1; i < nx - 1; ++i) {
06528 size_t t = i + j*nx+k*nx*ny;
06529 if (d[t]) continue;
06530 if (d2[t - 1] || d2[t + 1] || d2[t + nx] || d2[t - nx] || d2[t + nxy] || d2[t - nxy]) d[t] = (float) l + 1;
06531 }
06532 }
06533 }
06534 }
06535 }
06536 else {
06537 for (int l = 1; l <= (int) val1+val2; ++l) {
06538 for (size_t i=0; i<size; i++) d2[i]=d[i];
06539 for (int j = 1; j < ny - 1; ++j) {
06540 for (int i = 1; i < nx - 1; ++i) {
06541 size_t t = i + j * nx;
06542 if (d[t]) continue;
06543 if (d2[t - 1] || d2[t + 1] || d2[t + nx] || d2[t - nx]) d[t] = (float) l + 1;
06544 }
06545 }
06546 }
06547 }
06548
06549 vector<float> vec;
06550 for (int i=0; i<val1+2; i++) vec.push_back(1.0);
06551 for (int i=0; i<val2; i++) {
06552 vec.push_back(exp(-pow(2.0f*i/(val2),2.0f)));
06553
06554 }
06555 for (size_t i = 0; i < size; i++) if (d[i]) d[i]=vec[(int)d[i]];
06556
06557 image->update();
06558 delete image2;
06559 }
06560
06561 EMData* DirectionalSumProcessor::process(const EMData* const image ) {
06562 string dir = params.set_default("direction", "");
06563 if ( dir == "" || ( dir != "x" && dir != "y" && dir != "z" ) )
06564 throw InvalidParameterException("The direction parameter must be either x, y, or z");
06565
06566 int nx = image->get_xsize();
06567 int ny = image->get_ysize();
06568 int nz = image->get_zsize();
06569
06570
06571 if ( dir == "x" ) nx = 1;
06572 else if ( dir == "y" ) ny = 1;
06573 else if ( dir == "z" ) nz = 1;
06574
06575 EMData* ret = new EMData;
06576 ret->set_size(nx,ny,nz);
06577 ret->to_zero();
06578
06579 float* d = image->get_data();
06580 for(int k = 0; k < image->get_zsize(); ++k ) {
06581 for(int j = 0; j < image->get_ysize(); ++j ) {
06582 for(int i = 0; i < image->get_xsize(); ++i, ++d ) {
06583 if ( dir == "x" ) {
06584 float v = ret->get_value_at(0,j,k);
06585 ret->set_value_at(0,j,k,*d+v);
06586 }else if ( dir == "y" ) {
06587 float v = ret->get_value_at(i,0,k);
06588 ret->set_value_at(i,0,k,*d+v);
06589 }
06590 else if ( dir == "z" ) {
06591 float v = ret->get_value_at(i,j,0);
06592 ret->set_value_at(i,j,0,*d+v);
06593 }
06594 }
06595 }
06596 }
06597 ret->update();
06598 return ret;
06599 }
06600
06601 void TestImageProcessor::preprocess(EMData * image)
06602 {
06603 if (!image) {
06604 LOGWARN("NULL Image");
06605 return;
06606 }
06607
06608 nx = image->get_xsize();
06609 ny = image->get_ysize();
06610 nz = image->get_zsize();
06611 }
06612
06613
06614 void TestImageFourierNoiseGaussian::process_inplace(EMData* image)
06615 {
06616 if (!image->is_complex()) {
06617 int nx = image->get_xsize();
06618 int offset = 2 - nx%2;
06619
06620 image->set_size(nx+offset,image->get_ysize(),image->get_zsize());
06621 image->set_complex(true);
06622 if (1 == offset) image->set_fftodd(true);
06623 else image->set_fftodd(false);
06624 image->set_fftpad(true);
06625 }
06626 image->ri2ap();
06627
06628 float sigma = params.set_default("sigma",.25f);
06629
06630 float * d = image->get_data();
06631 int nx = image->get_xsize();
06632 int ny = image->get_ysize();
06633 int nxy = image->get_ysize()*nx;
06634 int nzon2 = image->get_zsize()/2;
06635 int nyon2 = image->get_ysize()/2;
06636 float rx, ry, rz, length, amp, phase;
06637 int twox;
06638 for (int z = 0; z< image->get_zsize(); ++z) {
06639 for (int y = 0; y < image->get_ysize(); ++y) {
06640 for (int x = 0; x < image->get_xsize()/2; ++x) {
06641 rx = (float)x;
06642 ry = (float)nyon2 - (float)y;
06643 rz = (float)nzon2 - (float)z;
06644 length = sqrt(rx*rx + ry*ry + rz*rz);
06645 amp = exp(-sigma*length);
06646 phase = Util::get_frand(0,1)*2*M_PI;
06647
06648 twox = 2*x;
06649 size_t idx1 = twox + y*nx+z*nxy;
06650 size_t idx2 = idx1 + 1;
06651 d[idx1] = amp;
06652 d[idx2] = phase;
06653
06654 }
06655 }
06656 }
06657
06658 image->ap2ri();
06659 if (image->get_ndim() == 2) {
06660 bool yodd = image->get_ysize() % 2 == 1;
06661
06662 int yit = image->get_ysize()/2-1;
06663 int offset = 1;
06664 if (yodd) {
06665 offset = 0;
06666 }
06667 for (int y = 0; y < yit; ++y) {
06668 int bot_idx = (y+offset)*nx;
06669 int top_idx = (ny-1-y)*nx;
06670 float r1 = d[bot_idx];
06671 float i1 = d[bot_idx+1];
06672 float r2 = d[top_idx];
06673 float i2 = d[top_idx+1];
06674 float r = (r1 + r2)/2.0f;
06675 float i = (i1 + i2)/2.0f;
06676 d[bot_idx] = r;
06677 d[top_idx] = r;
06678 d[bot_idx+1] = i;
06679 d[top_idx+1] = -i;
06680
06681 bot_idx = (y+offset)*nx+nx-2;
06682 top_idx = (ny-1-y)*nx+nx-2;
06683 r1 = d[bot_idx];
06684 i1 = d[bot_idx+1];
06685 r2 = d[top_idx];
06686 i2 = d[top_idx+1];
06687 r = (r1 + r2)/2.0f;
06688 i = (i1 + i2)/2.0f;
06689 d[bot_idx] = r;
06690 d[top_idx] = r;
06691 d[bot_idx+1] = i;
06692 d[top_idx+1] = -i;
06693 }
06694
06695 d[1] = 0;
06696 d[nx-1] = 0;
06697 d[ny/2*nx+nx-1] = 0;
06698 d[ny/2*nx+1] = 0;
06699 }
06700
06701 if (image->get_ndim() != 1) image->process_inplace("xform.fourierorigin.tocorner");
06702 image->do_ift_inplace();
06703 image->depad();
06704 }
06705
06706 #include <iostream>
06707 using std::ostream_iterator;
06708
06709 void CTFSNRWeightProcessor::process_inplace(EMData* image) {
06710 if (params.has_key("noise")==false) throw InvalidParameterException("You must supply the noise argument");
06711 if (params.has_key("snr")==false) throw InvalidParameterException("You must supply the snr argument");
06712
06713 float boost = params.set_default("boost",1.0f);
06714
06715 if (!image->is_complex()) {
06716 image->do_fft_inplace();
06717 }
06718 EMData* cpy = image->copy();
06719 cpy->ri2inten();
06720 vector<float> sf = cpy->calc_radial_dist(cpy->get_ysize()/2,0.0,1.0,1);
06721 transform(sf.begin(),sf.end(),sf.begin(),sqrtf);
06722 delete cpy;
06723
06724 image->ri2ap();
06725
06726 vector<float> noise = params["noise"];
06727 vector<float> snr = params["snr"];
06728
06729
06730
06731
06732 for(vector<float>::iterator it = noise.begin(); it != noise.end(); ++it){
06733 if ((*it) == 0) *it = 1;
06734 }
06735 for(vector<float>::iterator it = snr.begin(); it != snr.end(); ++it){
06736 if ((*it) < 0) *it = 0;
06737 }
06738
06739 transform(snr.begin(),snr.end(),noise.begin(),snr.begin(),std::multiplies<float>());
06740 transform(snr.begin(),snr.end(),snr.begin(),sqrtf);
06741
06742
06743
06744 int i = static_cast<int>(snr.size());
06745
06746 float * d = image->get_data();
06747 int nx = image->get_xsize();
06748
06749 int nxy = image->get_ysize()*nx;
06750 int nzon2 = image->get_zsize()/2;
06751 int nyon2 = image->get_ysize()/2;
06752 float rx, ry, rz, amp;
06753 int length;
06754 int twox;
06755 image->process_inplace("xform.fourierorigin.tocenter");
06756 for (int z = 0; z< image->get_zsize(); ++z) {
06757 for (int y = 0; y < image->get_ysize(); ++y) {
06758 for (int x = 0; x < image->get_xsize()/2; ++x) {
06759 rx = (float)x;
06760 ry = (float)nyon2 - (float)y;
06761 rz = (float)nzon2 - (float)z;
06762 length = static_cast<int>(sqrt(rx*rx + ry*ry + rz*rz));
06763
06764 twox = 2*x;
06765 size_t idx1 = twox + y*nx+z*nxy;
06766 if (length >= i || length >= (int)sf.size()) {
06767 d[idx1] = 0;
06768 continue;
06769 } else {
06770 amp = boost*snr[length];
06771
06772
06773 }
06774
06775 if (sf[length] == 0) {
06776 d[idx1] = 0;
06777 continue;
06778 }
06779
06780
06781
06782 d[idx1] /= sf[length];
06783 if (d[idx1] < 0) {
06784 d[idx1] *= amp;
06785 }else {
06786 d[idx1] *= -amp;
06787 }
06788
06789
06790 }
06791 }
06792 }
06793
06794 image->ap2ri();
06795 if (image->get_ndim() != 1) image->process_inplace("xform.fourierorigin.tocorner");
06796 image->do_ift_inplace();
06797 image->depad();
06798 }
06799
06800 void TestImageFourierNoiseProfile::process_inplace(EMData * image) {
06801
06802 if (params.has_key("profile")==false) throw InvalidParameterException("You must supply the profile argument");
06803
06804 if (!image->is_complex()) {
06805 int nx = image->get_xsize();
06806 int offset = 2 - nx%2;
06807
06808 image->set_size(nx+offset,image->get_ysize(),image->get_zsize());
06809 image->set_complex(true);
06810 if (1 == offset) image->set_fftodd(true);
06811 else image->set_fftodd(false);
06812 image->set_fftpad(true);
06813 }
06814 image->to_zero();
06815 image->ri2ap();
06816
06817 vector<float> profile = params["profile"];
06818 transform(profile.begin(),profile.end(),profile.begin(),sqrtf);
06819
06820 int i = static_cast<int>(profile.size());
06821
06822 float * d = image->get_data();
06823 int nx = image->get_xsize();
06824 int ny = image->get_ysize();
06825 int nxy = image->get_ysize()*nx;
06826 int nzon2 = image->get_zsize()/2;
06827 int nyon2 = image->get_ysize()/2;
06828 float rx, ry, rz, amp, phase;
06829 int length;
06830 int twox;
06831 for (int z = 0; z< image->get_zsize(); ++z) {
06832 for (int y = 0; y < image->get_ysize(); ++y) {
06833 for (int x = 0; x < image->get_xsize()/2; ++x) {
06834 rx = (float)x;
06835 ry = (float)nyon2 - (float)y;
06836 rz = (float)nzon2 - (float)z;
06837 length = static_cast<int>(sqrt(rx*rx + ry*ry + rz*rz));
06838
06839 twox = 2*x;
06840 size_t idx1 = twox + y*nx+z*nxy;
06841 size_t idx2 = idx1 + 1;
06842
06843
06844 if (length >= i) {
06845 d[idx1] = 0;
06846 d[idx2] = 0;
06847 continue;
06848 }
06849 amp = profile[length];
06850 phase = Util::get_frand(0,1)*2*M_PI;
06851
06852
06853 d[idx1] = amp;
06854 d[idx2] = phase;
06855
06856 }
06857 }
06858 }
06859
06860 image->ap2ri();
06861 if (image->get_ndim() == 2) {
06862 bool yodd = image->get_ysize() % 2 == 1;
06863
06864 int yit = image->get_ysize()/2-1;
06865 int offset = 1;
06866 if (yodd) {
06867 offset = 0;
06868 }
06869 for (int y = 0; y < yit; ++y) {
06870 int bot_idx = (y+offset)*nx;
06871 int top_idx = (ny-1-y)*nx;
06872 float r1 = d[bot_idx];
06873 float i1 = d[bot_idx+1];
06874 float r2 = d[top_idx];
06875 float i2 = d[top_idx+1];
06876 float r = (r1 + r2)/2.0f;
06877 float i = (i1 + i2)/2.0f;
06878 d[bot_idx] = r;
06879 d[top_idx] = r;
06880 d[bot_idx+1] = i;
06881 d[top_idx+1] = -i;
06882
06883 bot_idx = (y+offset)*nx+nx-2;
06884 top_idx = (ny-1-y)*nx+nx-2;
06885 r1 = d[bot_idx];
06886 i1 = d[bot_idx+1];
06887 r2 = d[top_idx];
06888 i2 = d[top_idx+1];
06889 r = (r1 + r2)/2.0f;
06890 i = (i1 + i2)/2.0f;
06891 d[bot_idx] = r;
06892 d[top_idx] = r;
06893 d[bot_idx+1] = i;
06894 d[top_idx+1] = -i;
06895 }
06896
06897 d[1] = 0;
06898 d[nx-1] = 0;
06899 d[ny/2*nx+nx-1] = 0;
06900 d[ny/2*nx+1] = 0;
06901 }
06902
06903 if (image->get_ndim() != 1) image->process_inplace("xform.fourierorigin.tocorner");
06904 image->do_ift_inplace();
06905 image->depad();
06906 }
06907
06908 void TestImageLineWave::process_inplace(EMData * image)
06909 {
06910 preprocess(image);
06911
06912 float period = params.set_default("period",10.0f);
06913 int n = image->get_xsize()*image->get_ysize()*image->get_zsize();
06914
06915 for(int i = 0; i < n; ++i) {
06916 float x = fmod((float)i,period);
06917 x /= period;
06918 x = (float)sin(x*EMConsts::pi*2.0);
06919 image->set_value_at_fast(i,x);
06920 }
06921 }
06922
06923 void TestImageGaussian::process_inplace(EMData * image)
06924 {
06925 preprocess(image);
06926
06927 float sigma = params["sigma"];
06928 string axis = (const char*)params["axis"];
06929 float c = params["c"];
06930
06931 float *dat = image->get_data();
06932 float r;
06933 float x2, y2, z2;
06934 for (int k = 0; k < nz; ++k) {
06935 for (int j = 0; j < ny; ++j) {
06936 for (int i = 0; i < nx; ++i, ++dat) {
06937 x2 = (float)( i - nx/2 );
06938 y2 = (float)( j - ny/2 );
06939 z2 = (float)( k - nz/2 );
06940
06941 if(axis==""){
06942 r = (float)sqrt(x2*x2+y2*y2+z2*z2);
06943 }
06944 else if(axis == "x"){
06945 float lc = -c;
06946 float rc = c;
06947 r = ( (float)sqrt((x2-lc)*(x2-lc)+y2*y2+z2*z2) +
06948 (float)sqrt((x2-rc)*(x2-rc)+y2*y2+z2*z2) ) /2.0f - c;
06949 }
06950 else if(axis == "y"){
06951 float lc = -c;
06952 float rc = c;
06953 r = ( (float)sqrt(x2*x2+(y2-lc)*(y2-lc)+z2*z2) +
06954 (float)sqrt(x2*x2+(y2-rc)*(y2-rc)+z2*z2) ) /2.0f - c;
06955 }
06956 else if(axis == "z"){
06957 if( nz == 1 ){
06958 throw InvalidValueException(0, "This is a 2D image, no asymmetric feature for z axis");
06959 }
06960 float lc = -c;
06961 float rc = c;
06962 r = ( (float)sqrt(x2*x2+y2*y2+(z2-lc)*(z2-lc)) +
06963 (float)sqrt(x2*x2+y2*y2+(z2-rc)*(z2-rc)) ) /2.0f - c;
06964 }
06965 else{
06966 throw InvalidValueException(0, "please specify a valid axis for asymmetric features");
06967 }
06968
06969 *dat = (float)gsl_ran_gaussian_pdf((double)r,(double)sigma);
06970 }
06971 }
06972 }
06973
06974 image->update();
06975 }
06976
06977 void TestImageGradient::process_inplace(EMData * image)
06978 {
06979 string axis = params.set_default("axis", "x");
06980
06981 float m = params.set_default("m", 1.0f);
06982 float b = params.set_default("b", 0.0f);
06983
06984 if ( axis != "z" && axis != "y" && axis != "x") throw InvalidParameterException("Axis must be x,y or z");
06985
06986 preprocess(image);
06987
06988 if ( axis == "x")
06989 {
06990 for(int k=0; k<nz;++k) {
06991 for(int j=0; j<ny; ++j) {
06992 for(int i=0; i <nx; ++i) {
06993 image->set_value_at(i,j,k,m*i+b);
06994 }
06995 }
06996 }
06997 }
06998 else if ( axis == "y")
06999 {
07000 for(int k=0; k<nz;++k) {
07001 for(int j=0; j<ny; ++j) {
07002 for(int i=0; i <nx; ++i) {
07003 image->set_value_at(i,j,k,m*j+b);
07004 }
07005 }
07006 }
07007 }
07008 else if ( axis == "z")
07009 {
07010 for(int k=0; k<nz;++k) {
07011 for(int j=0; j<ny; ++j) {
07012 for(int i=0; i <nx; ++i) {
07013 image->set_value_at(i,j,k,m*k+b);
07014 }
07015 }
07016 }
07017 }
07018 image->update();
07019 }
07020
07021 void TestImageAxes::process_inplace(EMData * image)
07022 {
07023 preprocess(image);
07024
07025 float fill = params.set_default("fill", 1.0f);
07026
07027 int cx = nx/2;
07028 int cy = ny/2;
07029 int cz = nz/2;
07030
07031
07032
07033
07034
07035 int xoffset = (nx % 2 == 0? 1:0);
07036 int yoffset = (ny % 2 == 0? 1:0);
07037 int zoffset = (nz % 2 == 0? 1:0);
07038
07039
07040
07041
07042
07043
07044 if ( nx == 1 && ny == 1 && nz == 1 )
07045 {
07046 (*image)(0) = fill;
07047 }
07048 else if ( ny == 1 && nz == 1 )
07049 {
07050 int radius = params.set_default("radius", cx );
07051 if ( radius > cx ) radius = cx;
07052
07053 (*image)(cx) = fill;
07054 for ( int i = 1; i <= radius-xoffset; ++i ) (*image)(cx+i) = fill;
07055 for ( int i = 1; i <= radius; ++i ) (*image)(cx-i) = fill;
07056 }
07057 else if ( nz == 1 )
07058 {
07059 int min = ( nx < ny ? nx : ny );
07060 min /= 2;
07061
07062 int radius = params.set_default("radius", min );
07063 if ( radius > min ) radius = min;
07064
07065 (*image)(cx,cy) = fill;
07066
07067 for ( int i = 1; i <= radius-xoffset; ++i ) (*image)(cx+i,cy) = fill;
07068 for ( int i = 1; i <= radius-yoffset; ++i )(*image)(cx,cy+i) = fill;
07069
07070 for ( int i = 1; i <= radius; ++i )
07071 {
07072 (*image)(cx-i,cy) = fill;
07073 (*image)(cx,cy-i) = fill;
07074 }
07075
07076 }
07077 else
07078 {
07079
07080 int min = ( nx < ny ? nx : ny );
07081 if (nz < min ) min = nz;
07082 min /= 2;
07083
07084 int radius = params.set_default("radius", min);
07085 if ( radius > min ) radius = min;
07086
07087
07088 (*image)(cx,cy,cz) = fill;
07089 for ( int i = 1; i <=radius-xoffset; ++i ) (*image)(cx+i,cy,cz) = fill;
07090 for ( int i = 1; i <=radius-yoffset; ++i ) (*image)(cx,cy+i,cz) = fill;
07091 for ( int i = 1; i <=radius-zoffset; ++i ) (*image)(cx,cy,cz+i) = fill;
07092 for ( int i = 1; i <= radius; ++i )
07093 {
07094 (*image)(cx-i,cy,cz) = fill;
07095 (*image)(cx,cy-i,cz) = fill;
07096 (*image)(cx,cy,cz-i) = fill;
07097 }
07098 }
07099
07100 image->update();
07101 }
07102
07103 void TestImageScurve::process_inplace(EMData * image)
07104 {
07105 preprocess(image);
07106
07107 int dim_size = image->get_ndim();
07108 if( 2 != dim_size ) {
07109 throw ImageDimensionException("works for 2D images only");
07110 }
07111
07112 int nx = image->get_xsize();
07113 int ny = image->get_ysize();
07114 image->to_zero();
07115
07116 for (int i=0; i<100; i++) {
07117 int x=static_cast<int>( nx/2+nx/6.0*sin(i*2.0*3.14159/100.0) );
07118 int y=ny/4+i*ny/200;
07119 for (int xx=x-nx/10; xx<x+nx/10; xx++) {
07120 for (int yy=y-ny/10; yy<y+ny/10; yy++) {
07121 #ifdef _WIN32
07122 (*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);
07123 #else
07124 (*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);
07125 #endif
07126 }
07127 }
07128 }
07129
07130 image->update();
07131 }
07132
07133 void TestImagePureGaussian::process_inplace(EMData * image)
07134 {
07135 preprocess(image);
07136
07137 float x_sigma = params["x_sigma"];
07138 float y_sigma = params["y_sigma"];
07139 float z_sigma = params["z_sigma"];
07140
07141 float x_center = params["x_center"];
07142 float y_center = params["y_center"];
07143 float z_center = params["z_center"];
07144
07145 int nx = image->get_xsize();
07146 int ny = image->get_ysize();
07147 int nz = image->get_zsize();
07148
07149 float x_twosig2 = 2*x_sigma*x_sigma;
07150 float y_twosig2 = 2*y_sigma*y_sigma;
07151 float z_twosig2 = 2*z_sigma*z_sigma;
07152
07153 float sr2pi = sqrt( 2.0f*(float)pi );
07154 float norm = 1.0f/ ( x_sigma*sr2pi );
07155 if (ny > 1) {
07156 norm *= 1.0f/ ( y_sigma*sr2pi );
07157 if (nz > 1) norm *= 1.0f/ ( z_sigma*sr2pi );
07158 }
07159
07160 float z, y, x, sum, val;
07161 for (int iz=0; iz < nz; ++iz) {
07162 z = static_cast<float>(iz) - z_center;
07163 for (int iy=0; iy < ny; ++iy) {
07164 y = static_cast<float>(iy) - y_center;
07165 for (int ix=0; ix < nx; ++ix) {
07166 x = static_cast<float>(ix) - x_center;
07167 sum = x*x/x_twosig2 + y*y/y_twosig2 + z*z/z_twosig2;
07168 val = norm*exp(-sum);
07169 (*image)(ix,iy,iz) = val;
07170 }
07171 }
07172 }
07173 image->update();
07174 }
07175
07176 void TestImageSphericalWave::process_inplace(EMData * image)
07177 {
07178 preprocess(image);
07179
07180 if(!params.has_key("wavelength")) {
07181 LOGERR("%s wavelength is required parameter", get_name().c_str());
07182 throw InvalidParameterException("wavelength parameter is required.");
07183 }
07184 float wavelength = params["wavelength"];
07185
07186 float phase = 0;
07187 if(params.has_key("phase")) {
07188 phase = params["phase"];
07189 }
07190
07191 float x = (float)(nx/2);
07192 if (params.has_key("x")) x=params["x"];
07193 float y = (float)(ny/2);
07194 if (params.has_key("y")) y=params["y"];
07195 float z = (float)(nz/2);
07196 if (params.has_key("z")) z=params["z"];
07197
07198 int ndim = image->get_ndim();
07199
07200 if(ndim==2) {
07201 for(int j=0; j<ny; ++j) {
07202 for(int i=0; i<nx; ++i) {
07203 #ifdef _WIN32
07204 float r=_hypotf(x-(float)i,y-(float)j);
07205 #else
07206 float r=hypot(x-(float)i,y-(float)j);
07207 #endif //_WIN32
07208 if (r<.5) continue;
07209 image->set_value_at(i,j,cos(2*(float)pi*r/wavelength+phase)/r);
07210 }
07211 }
07212 }
07213 else {
07214 for(int k=0; k<nz; ++k) {
07215 for(int j=0; j<ny; ++j) {
07216 for(int i=0; i<nx; ++i) {
07217 float r=Util::hypot3(x-(float)i,y-(float)j,z-(float)k);
07218 if (r<.5) continue;
07219 image->set_value_at(i,j,k,cos(2*(float)pi*r/wavelength+phase)/(r*r));
07220 }
07221 }
07222 }
07223 }
07224
07225 image->update();
07226 }
07227
07228
07229 void TestImageSinewave::process_inplace(EMData * image)
07230 {
07231 preprocess(image);
07232
07233 if(!params.has_key("wavelength")) {
07234 LOGERR("%s wavelength is required parameter", get_name().c_str());
07235 throw InvalidParameterException("wavelength parameter is required.");
07236 }
07237 float wavelength = params["wavelength"];
07238
07239 string axis = "";
07240 if(params.has_key("axis")) {
07241 axis = (const char*)params["axis"];
07242 }
07243
07244 float phase = 0;
07245 if(params.has_key("phase")) {
07246 phase = params["phase"];
07247 }
07248
07249 int ndim = image->get_ndim();
07250 float * dat = image->get_data();
07251
07252 if(ndim==1) {
07253 for(int i=0; i<nx; ++i, ++dat) {
07254 *dat = sin(i*(2.0f*M_PI/wavelength) + phase);
07255 }
07256 }
07257 else if(ndim==2) {
07258 float alpha = 0;
07259 if(params.has_key("az")) {
07260 alpha = params["az"];
07261 }
07262 for(int j=0; j<ny; ++j) {
07263 for(int i=0; i<nx; ++i, ++dat) {
07264 if(alpha != 0) {
07265 *dat = sin((i*sin((180-alpha)*M_PI/180)+j*cos((180-alpha)*M_PI/180))*(2.0f*M_PI/wavelength) + phase);
07266 }
07267 else if(axis.compare("y")==0 || axis.compare("Y")==0) {
07268 *dat = sin(j*(2.0f*M_PI/wavelength) + phase);
07269 }
07270 else {
07271 *dat = sin(i*(2.0f*M_PI/wavelength) + phase);
07272 }
07273 }
07274 }
07275 }
07276 else {
07277 float az = 0;
07278 if(params.has_key("az")) {
07279 az = params["az"];
07280 }
07281 float alt = 0;
07282 if(params.has_key("alt")) {
07283 alt = params["alt"];
07284 }
07285 float phi = 0;
07286 if(params.has_key("phi")) {
07287 phi = params["phi"];
07288 }
07289
07290 for(int k=0; k<nz; ++k) {
07291 for(int j=0; j<ny; ++j) {
07292 for(int i=0; i<nx; ++i, ++dat) {
07293 if(axis.compare("z")==0 || axis.compare("Z")==0) {
07294 *dat = sin(k*(2.0f*M_PI/wavelength) + phase);
07295 }
07296 else if(axis.compare("y")==0 || axis.compare("Y")==0) {
07297 *dat = sin(j*(2.0f*M_PI/wavelength) + phase);
07298 }
07299 else {
07300 *dat = sin(i*(2.0f*M_PI/wavelength) + phase);
07301 }
07302 }
07303 }
07304 }
07305
07306 if(az != 0 || alt != 0 || phi != 0) {
07307 Dict d("type","eman");
07308 d["az"] = az; d["phi"] = phi; d["alt"] = alt;
07309 image->transform(Transform(d));
07310 }
07311 }
07312
07313 image->update();
07314 }
07315
07316 void TestImageSinewaveCircular::process_inplace(EMData * image)
07317 {
07318 preprocess(image);
07319
07320 float wavelength = params["wavelength"];
07321 string axis = (const char*)params["axis"];
07322 float c = params["c"];
07323 float phase = params["phase"];
07324
07325 float *dat = image->get_data();
07326 float r;
07327 float x2, y2, z2;
07328 for (int k = 0; k < nz; ++k) {
07329 for (int j = 0; j < ny; ++j) {
07330 for (int i = 0; i < nx; ++i, ++dat) {
07331 x2 = (float)( i - nx/2 );
07332 y2 = (float)( j - ny/2 );
07333 z2 = (float)( k - nz/2 );
07334 if(axis == ""){
07335 r = (float)sqrt(x2*x2+y2*y2+z2*z2);
07336 }
07337 else if(axis == "x"){
07338 float lc = -c;
07339 float rc = c;
07340 r = ( (float)sqrt((x2-lc)*(x2-lc)+y2*y2+z2*z2) +
07341 (float)sqrt((x2-rc)*(x2-rc)+y2*y2+z2*z2) ) /2.0f - c;
07342 }
07343 else if(axis == "y"){
07344 float lc = -c;
07345 float rc = c;
07346 r = ( (float)sqrt(x2*x2+(y2-lc)*(y2-lc)+z2*z2) +
07347 (float)sqrt(x2*x2+(y2-rc)*(y2-rc)+z2*z2) ) /2.0f - c;
07348 }
07349 else if(axis == "z"){
07350 if( nz == 1 ){
07351 throw InvalidValueException(0, "This is a 2D image, no asymmetric feature for z axis");
07352 }
07353 float lc = -c;
07354 float rc = c;
07355 r = ( (float)sqrt(x2*x2+y2*y2+(z2-lc)*(z2-lc)) +
07356 (float)sqrt(x2*x2+y2*y2+(z2-rc)*(z2-rc)) ) /2.0f - c;
07357 }
07358 else{
07359 throw InvalidValueException(0, "please specify a valid axis for asymmetric features");
07360 }
07361 *dat = sin( r * (2.0f*M_PI/wavelength) - phase*180/M_PI);
07362 }
07363 }
07364 }
07365
07366 image->update();
07367 }
07368
07369 void TestImageSquarecube::process_inplace(EMData * image)
07370 {
07371 preprocess(image);
07372
07373 float edge_length = params["edge_length"];
07374 string axis = (const char*)params["axis"];
07375 float odd_edge = params["odd_edge"];
07376 int fill = (int)params["fill"];
07377
07378 float *dat = image->get_data();
07379 float x2, y2, z2;
07380 float xEdge, yEdge, zEdge;
07381 if(axis == ""){
07382 xEdge = edge_length/2.0f;
07383 yEdge = edge_length/2.0f;
07384 zEdge = edge_length/2.0f;
07385 }
07386 else if(axis == "x"){
07387 xEdge = odd_edge/2.0f;
07388 yEdge = edge_length/2.0f;
07389 zEdge = edge_length/2.0f;
07390 }
07391 else if(axis == "y"){
07392 xEdge = edge_length/2.0f;
07393 yEdge = odd_edge/2.0f;
07394 zEdge = edge_length/2.0f;
07395 }
07396 else if(axis == "z"){
07397 if( nz == 1 ){
07398 throw InvalidValueException(0, "This is a 2D image, no asymmetric feature for z axis");
07399 }
07400 xEdge = edge_length/2.0f;
07401 yEdge = edge_length/2.0f;
07402 zEdge = odd_edge/2.0f;
07403 }
07404 else{
07405 throw InvalidValueException(0, "please specify a valid axis for asymmetric features");
07406 }
07407 for (int k = 0; k < nz; ++k) {
07408 for (int j = 0; j < ny; ++j) {
07409 for (int i = 0; i < nx; ++i, ++dat) {
07410 x2 = (float)fabs((float)i - nx/2);
07411 y2 = (float)fabs((float)j - ny/2);
07412 z2 = (float)fabs((float)k - nz/2);
07413 if( x2<=xEdge && y2<=yEdge && z2<=zEdge ) {
07414 if( !fill) {
07415 *dat = 0;
07416 }
07417 else {
07418 *dat = 1;
07419 }
07420 }
07421 else {
07422 if( !fill ) {
07423 *dat = 1;
07424 }
07425 else {
07426 *dat = 0;
07427 }
07428 }
07429 }
07430 }
07431 }
07432
07433 image->update();
07434 }
07435
07436 void TestImageCirclesphere::process_inplace(EMData * image)
07437 {
07438 preprocess(image);
07439
07440 float radius = params.set_default("radius",nx/2.0f);
07441 string axis = (const char*)params["axis"];
07442 float c = params.set_default("c",nx/2.0f);
07443 int fill = params.set_default("fill",1);
07444
07445 float *dat = image->get_data();
07446 float x2, y2, z2;
07447 float r = 0.0f;
07448 float asy = 0.0f;
07449 if(axis == ""){
07450 asy = radius;
07451 }
07452 else if(axis == "x" || axis == "y"){
07453 asy = c;
07454 }
07455 else if(axis=="z"){
07456 if( nz == 1 ){
07457 throw InvalidValueException(0, "This is a 2D image, no asymmetric feature for z axis");
07458 }
07459 asy = c;
07460 }
07461 else{
07462 throw InvalidValueException(0, "please specify a valid axis for asymmetric features");
07463 }
07464
07465 for (int k = 0; k < nz; ++k) {
07466 for (int j = 0; j < ny; ++j) {
07467 for (int i = 0; i < nx; ++i, ++dat) {
07468 x2 = fabs((float)i - nx/2);
07469 y2 = fabs((float)j - ny/2);
07470 z2 = fabs((float)k - nz/2);
07471 if( axis == "" ){
07472 r = (x2*x2)/(radius*radius) + (y2*y2)/(radius*radius) + (z2*z2)/(radius*radius);
07473 }
07474 else if (axis == "x"){
07475 r = (x2*x2)/(asy*asy) + (y2*y2)/(radius*radius) + (z2*z2)/(radius*radius);
07476 }
07477 else if(axis == "y"){
07478 r = (x2*x2)/(radius*radius) + (y2*y2)/(asy*asy) + (z2*z2)/(radius*radius);
07479 }
07480 else if(axis=="z"){
07481 r = (x2*x2)/(radius*radius) + (y2*y2)/(radius*radius) + (z2*z2)/(asy*asy);
07482 }
07483 if( r<=1 ) {
07484 if( !fill) {
07485 *dat = 0;
07486 }
07487 else {
07488 *dat = 1;
07489 }
07490 }
07491 else {
07492 if( !fill ) {
07493 *dat = 1;
07494 }
07495 else {
07496 *dat = 0;
07497 }
07498 }
07499 }
07500 }
07501 }
07502
07503 image->update();
07504 }
07505
07506 void TestImageHollowEllipse::process_inplace(EMData * image)
07507 {
07508 preprocess(image);
07509
07510 float width = params.set_default("width",2.0f);
07511
07512 float a2 = params.set_default("a",nx/2.0f-1.0f);
07513 float b2 = params.set_default("b",ny/2.0f-1.0f);
07514 float c2 = params.set_default("c",nz/2.0f-1.0f);
07515
07516 float a1 = params.set_default("xwidth",a2-width);
07517 float b1 = params.set_default("ywidth",b2-width);
07518 float c1 = params.set_default("zwidth",c2-width);
07519
07520 float fill = params.set_default("fill",1.0f);
07521 Transform* t;
07522 if (params.has_key("transform")) {
07523 t = params["transform"];
07524 } else {
07525 t = new Transform;
07526 }
07527
07528
07529 int mz = 2*(int)c2+1;
07530 if ( nz < mz ) mz = nz;
07531 int my = 2*(int)b2+1;
07532 if ( ny < my ) my = ny;
07533 int mx = 2*(int)a2+1;
07534 if ( nx < mx ) mx = nx;
07535
07536 float ai1 = 1/(a1*a1);
07537 float bi1 = 1/(b1*b1);
07538 float ci1 = 1/(c1*c1);
07539
07540 float ai2 = 1/(a2*a2);
07541 float bi2 = 1/(b2*b2);
07542 float ci2 = 1/(c2*c2);
07543
07544 Vec3f origin(nx/2,ny/2,nz/2);
07545
07546 float x2, y2, z2, r1,r2;
07547 int xl, yl, zl;
07548 for (int k = 0; k < mz; ++k) {
07549 for (int j = 0; j < my; ++j) {
07550 for (int i = 0; i < mx; ++i) {
07551 x2 = (float)(i - mx/2);
07552 y2 = (float)(j - my/2);
07553 z2 = (float)(k - mz/2);
07554 r1 = (x2*x2)*ai1 + (y2*y2)*bi1 + (z2*z2)*ci1;
07555 r2 = (x2*x2)*ai2 + (y2*y2)*bi2 + (z2*z2)*ci2;
07556 if (r2 <= 1 && r1 >= 1) {
07557
07558 if (t != 0) {
07559 Vec3f v(x2,y2,z2);
07560 v = (*t)*v;
07561 v += origin;
07562
07563
07564
07565
07566 for( int kk = -1; kk <= 1; ++kk)
07567 for( int jj = -1; jj <= 1; ++jj)
07568 for( int ii = -1; ii <= 1; ++ii) {
07569 xl = (int)v[0]+ii;
07570 yl = (int)v[1]+jj;
07571 zl = (int)v[2]+kk;
07572 if (xl >= 0 && xl < nx && yl >= 0 && yl < ny && zl >= 0 && zl < nz)
07573 image->set_value_at(xl,yl,zl,1.0);
07574 }
07575 } else {
07576 image->set_value_at((int)x2+nx/2,(int)y2+ny/2,(int)z2+nz/2,fill);
07577 }
07578 }
07579 }
07580 }
07581 }
07582
07583 delete t;
07584
07585 image->update();
07586 }
07587
07588 void TestImageEllipse::process_inplace(EMData * image)
07589 {
07590 preprocess(image);
07591
07592
07593 float a = params.set_default("a",nx/2.0f-1.0f);
07594 float b = params.set_default("b",ny/2.0f-1.0f);
07595 float c = params.set_default("c",nz/2.0f-1.0f);
07596 float fill = params.set_default("fill",1.0f);
07597
07598 Transform* t;
07599 if (params.has_key("transform")) {
07600 t = params["transform"];
07601 } else {
07602 t = new Transform;
07603 }
07604
07605
07606 int mz = 2*(int)c+1;
07607 if ( nz < mz ) mz = nz;
07608 int my = 2*(int)b+1;
07609 if ( ny < my ) my = ny;
07610 int mx = 2*(int)a+1;
07611 if ( nx < mx ) mx = nx;
07612
07613
07614 float ai = 1/(a*a);
07615 float bi = 1/(b*b);
07616 float ci = 1/(c*c);
07617
07618 Vec3f origin(nx/2,ny/2,nz/2);
07619
07620 float x2, y2, z2, r;
07621 int xl, yl, zl;
07622 for (int k = 0; k < mz; ++k) {
07623 for (int j = 0; j < my; ++j) {
07624 for (int i = 0; i < mx; ++i) {
07625 x2 = (float)(i - mx/2);
07626 y2 = (float)(j - my/2);
07627 z2 = (float)(k - mz/2);
07628 r = (x2*x2)*ai + (y2*y2)*bi + (z2*z2)*ci;
07629 if (r <= 1) {
07630
07631 if (t != 0) {
07632 Vec3f v(x2,y2,z2);
07633 v = (*t)*v;
07634 v += origin;
07635
07636
07637
07638
07639 for( int kk = -1; kk <= 1; ++kk)
07640 for( int jj = -1; jj <= 1; ++jj)
07641 for( int ii = -1; ii <= 1; ++ii) {
07642 xl = (int)v[0]+ii;
07643 yl = (int)v[1]+jj;
07644 zl = (int)v[2]+kk;
07645 if (xl >= 0 && xl < nx && yl >= 0 && yl < ny && zl >= 0 && zl < nz)
07646 image->set_value_at(xl,yl,zl,fill);
07647 }
07648 } else {
07649 image->set_value_at((int)x2+nx/2,(int)y2+ny/2,(int)z2+nz/2,fill);
07650 }
07651 }
07652 }
07653 }
07654 }
07655
07656 delete t;
07657
07658 image->update();
07659 }
07660
07661 void TestImageNoiseUniformRand::process_inplace(EMData * image)
07662 {
07663 preprocess(image);
07664
07665 Randnum * r = Randnum::Instance();
07666 if(params.has_key("seed")) {
07667 r->set_seed((int)params["seed"]);
07668 }
07669
07670 float *dat = image->get_data();
07671 size_t size = nx*ny*nz;
07672 for (size_t i=0; i<size; ++i) {
07673 dat[i] = r->get_frand();
07674 }
07675
07676 image->update();
07677 }
07678
07679 void TestImageNoiseGauss::process_inplace(EMData * image)
07680 {
07681 preprocess(image);
07682
07683 float sigma = params["sigma"];
07684 if (sigma<=0) { sigma = 1.0; }
07685 float mean = params["mean"];
07686
07687 Randnum * r = Randnum::Instance();
07688 if (params.has_key("seed")) {
07689 r->set_seed((int)params["seed"]);
07690 }
07691
07692 float *dat = image->get_data();
07693 size_t size = nx*ny*nz;
07694 for (size_t i=0; i<size; ++i) {
07695 dat[i] = r->get_gauss_rand(mean, sigma);
07696 }
07697
07698 image->update();
07699 }
07700
07701 void TestImageCylinder::process_inplace(EMData * image)
07702 {
07703 preprocess(image);
07704
07705 int nx = image->get_xsize();
07706 int ny = image->get_ysize();
07707 int nz = image->get_zsize();
07708
07709 if(nz == 1) {
07710 throw ImageDimensionException("This processor only apply to 3D image");
07711 }
07712
07713 float radius = params["radius"];
07714 #ifdef _WIN32
07715 if(radius > _cpp_min(nx, ny)/2.0) {
07716 #else
07717 if(radius > std::min(nx, ny)/2.0) {
07718 #endif
07719 throw InvalidValueException(radius, "radius must be <= min(nx, ny)/2");
07720 }
07721
07722 float height;
07723 if(params.has_key("height")) {
07724 height = params["height"];
07725 if(height > nz) {
07726 throw InvalidValueException(radius, "height must be <= nz");
07727 }
07728 }
07729 else {
07730 height = static_cast<float>(nz);
07731 }
07732
07733 float *dat = image->get_data();
07734 float x2, y2;
07735 float r = 0.0f;
07736 for (int k = 0; k < nz; ++k) {
07737 for (int j = 0; j < ny; ++j) {
07738 for (int i = 0; i < nx; ++i, ++dat) {
07739 x2 = fabs((float)i - nx/2);
07740 y2 = fabs((float)j - ny/2);
07741 r = (x2*x2)/(radius*radius) + (y2*y2)/(radius*radius);
07742
07743 if(r<=1 && k>=(nz-height)/2 && k<=(nz+height)/2) {
07744 *dat = 1;
07745 }
07746 else {
07747 *dat = 0;
07748 }
07749 }
07750 }
07751 }
07752
07753 image->update();
07754 }
07755
07756 void RampProcessor::process_inplace(EMData * image)
07757 {
07758 if (!image) {
07759 return;
07760 }
07761
07762 int nz = image->get_zsize();
07763 if (nz > 1) {
07764 LOGERR("%s Processor doesn't support 3D model", get_name().c_str());
07765 throw ImageDimensionException("3D model not supported");
07766 }
07767
07768 int nsam = image->get_xsize();
07769 int nrow = image->get_ysize();
07770 int n1 = nsam / 2;
07771 double sx1 = double(n1)*double(nsam+1);
07772 if ( nsam % 2 == 1 )
07773 sx1 += 1 + n1;
07774 sx1 *= nrow;
07775 int n2 = nrow / 2;
07776 double sx2 = double(n2)*double(nrow+1);
07777 if ( nrow % 2 == 1 )
07778 sx2 += 1 + n2;
07779 sx2 *= nsam;
07780 float *data = image->get_data();
07781 float *row = NULL;
07782
07783 double syx1 = 0, syx2 = 0, sy = 0, sx1q = 0, sx2q = 0, syq = 0;
07784 for (int j=1; j <= nrow; j++) {
07785 row = data + (j-1)*nsam - 1;
07786 for (int i=1; i<=nsam; i++) {
07787 syx1 += row[i]*i;
07788 syx2 += row[i]*j;
07789 sy += row[i];
07790 sx1q += i*i;
07791 sx2q += j*j;
07792 syq += row[i]*double(row[i]);
07793 }
07794 }
07795
07796 float dn = float(nsam)*float(nrow);
07797 double qyx1 = syx1 - sx1*sy / dn;
07798 double qyx2 = syx2 - sx2*sy / dn;
07799 double qx1x2 = 0.0;
07800 double qx1 = sx1q - sx1*sx1 / dn;
07801 double qx2 = sx2q - sx2*sx2 / dn;
07802 double qy = syq - sy*sy / dn;
07803 double c = qx1*qx2 - qx1x2*qx1x2;
07804 if ( c > FLT_EPSILON ) {
07805 double b1 = (qyx1*qx2 - qyx2*qx1x2) / c;
07806 double b2 = (qyx2*qx1 - qyx1*qx1x2) / c;
07807 double a = (sy - b1*sx1 - b2*sx2) / dn;
07808 double d = a + b1 + b2;
07809 for (int i=1; i<=nrow; i++) {
07810 qy = d;
07811 row = data + (i-1)*nsam - 1;
07812 for (int k=1; k<=nsam; k++) {
07813 row[k] -= static_cast<float>(qy);
07814 qy += b1;
07815 }
07816 d += b2;
07817 }
07818 }
07819
07820 image->update();
07821 }
07822
07823
07824 void CCDNormProcessor::process_inplace(EMData * image)
07825 {
07826 if (!image) {
07827 Log::logger()->set_level(Log::ERROR_LOG);
07828 Log::logger()->error("Null image during call to CCDNorm\n");
07829 return;
07830 }
07831 if (image->get_zsize() > 1) {
07832 Log::logger()->set_level(Log::ERROR_LOG);
07833 Log::logger()->error("CCDNorm does not support 3d images\n");
07834 return;
07835 }
07836
07837 int xs = image->get_xsize();
07838 int ys = image->get_ysize();
07839
07840
07841 int width = params["width"];
07842
07843 width%=(xs > ys ? xs/2 : ys/2);
07844 if (width==0) {
07845 width=1;
07846 }
07847
07848
07849 float *left, *right, *top, *bottom;
07850
07851 double *temp;
07852 temp= (double*)malloc((xs > ys ? xs*width : ys*width)*sizeof(double));
07853 if (temp==NULL) {
07854 Log::logger()->set_level(Log::ERROR_LOG);
07855 Log::logger()->error("Could not allocate enough memory during call to CCDNorm\n");
07856 return;
07857 }
07858
07859 int x, y, z;
07860
07861
07862 double mL,mR,mT,mB;
07863
07864
07865 double nl,nr,nt,nb;
07866
07867
07868 double q1,q2,q3,q4;
07869
07870
07871 for (z=0; z<width; z++) {
07872 left = image->get_col(xs/2 -1-z)->get_data();
07873 for (y=0; y<ys; y++)
07874 temp[z*ys+y]=left[y];
07875 }
07876 mL=gsl_stats_mean(temp,1,ys*width);
07877
07878 for (z=0; z<width; z++) {
07879 right = image->get_col(xs/2 +z)->get_data();
07880 for (y=0; y<ys; y++)
07881 temp[z*ys+y]=right[y];
07882 }
07883 mR=gsl_stats_mean(temp,1,ys*width);
07884
07885 for (z=0; z<width; z++) {
07886 top = image->get_row(ys/2 -1-z)->get_data();
07887 for (x=0; x<xs; x++)
07888 temp[z*xs+x]=top[x];
07889 }
07890 mT=gsl_stats_mean(temp,1,xs*width);
07891
07892 for (z=0; z<width; z++) {
07893 bottom = image->get_row(ys/2 +z)->get_data();
07894 for (x=0; x<xs; x++)
07895 temp[z*xs+x]=bottom[x];
07896 }
07897 mB=gsl_stats_mean(temp,1,xs*width);
07898
07899 free(temp);
07900
07901 nl=(mL+mR)/2-mL;
07902 nr=(mL+mR)/2-mR;
07903 nt=(mT+mB)/2-mT;
07904 nb=(mT+mB)/2-mB;
07905
07906 q1=nl+nt;
07907 q2=nr+nt;
07908 q3=nr+nb;
07909 q4=nl+nb;
07910
07911
07912 for (x = 0; x < xs / 2; x++)
07913 for (y = 0; y < ys / 2; y++) {
07914 image->set_value_at_fast(x, y, image->get_value_at(x, y) + static_cast<float>(q1));
07915 }
07916 for (x = xs / 2; x < xs; x++)
07917 for (y = 0; y < ys / 2; y++) {
07918 image->set_value_at_fast(x, y, image->get_value_at(x, y) + static_cast<float>(q2));
07919 }
07920 for (x = xs / 2; x < xs; x++)
07921 for (y = ys / 2; y < ys; y++) {
07922 image->set_value_at_fast(x, y, image->get_value_at(x, y) + static_cast<float>(q3));
07923 }
07924 for (x = 0; x < xs / 2; x++)
07925 for (y = ys / 2; y < ys; y++) {
07926 image->set_value_at_fast(x, y, image->get_value_at(x, y) + static_cast<float>(q4));
07927 }
07928
07929 }
07930
07931 void WaveletProcessor::process_inplace(EMData *image)
07932 {
07933 if (image->get_zsize() != 1) {
07934 LOGERR("%s Processor doesn't support 3D", get_name().c_str());
07935 throw ImageDimensionException("3D model not supported");
07936 }
07937
07938 int i,nx,ny;
07939 const gsl_wavelet_type * T;
07940 nx=image->get_xsize();
07941 ny=image->get_ysize();
07942
07943 if (nx != ny && ny!=1) throw ImageDimensionException("Wavelet transform only supports square images");
07944
07945
07946 if( !Util::IsPower2(nx) ) throw ImageDimensionException("Wavelet transform size must be power of 2");
07947
07948
07949
07950
07951 double *cpy = (double *)malloc(nx*ny*sizeof(double));
07952
07953 for (i=0; i<nx*ny; i++) cpy[i]=image->get_value_at(i,0,0);
07954
07955 string tp = (const char*)params["type"];
07956 if (tp=="daub") T=gsl_wavelet_daubechies;
07957 else if (tp=="harr") T=gsl_wavelet_haar;
07958 else if (tp=="bspl") T=gsl_wavelet_bspline;
07959 else throw InvalidStringException(tp,"Invalid wavelet name, 'daub', 'harr' or 'bspl'");
07960
07961 int K=(int)params["ord"];
07962 gsl_wavelet_direction dir;
07963 if ((int)params["dir"]==1) dir=forward;
07964 else dir=backward;
07965
07966 gsl_wavelet *w = gsl_wavelet_alloc(T, K);
07967 gsl_wavelet_workspace *work = gsl_wavelet_workspace_alloc(nx);
07968
07969 if (ny==1) gsl_wavelet_transform (w,cpy, 1, nx, dir, work);
07970 else gsl_wavelet2d_transform (w, cpy, nx,nx,ny, dir, work);
07971
07972 gsl_wavelet_workspace_free (work);
07973 gsl_wavelet_free (w);
07974
07975 for (i=0; i<nx*ny; i++) image->set_value_at_fast(i,0,0,static_cast<float>(cpy[i]));
07976
07977 free(cpy);
07978 }
07979
07980 void FFTProcessor::process_inplace(EMData* image)
07981 {
07982 if( params.has_key("dir") ) {
07983 if ((int)params["dir"]==-1) {
07984 image->do_ift_inplace();
07985 }
07986 else {
07987 image->do_fft_inplace();
07988 }
07989 }
07990 }
07991
07992 void RadialProcessor::process_inplace(EMData * image)
07993 {
07994 if (!image) {
07995 LOGWARN("NULL Image");
07996 return;
07997 }
07998
07999
08000 if(image->is_complex()) {
08001 LOGERR("%s Processor only operates on real images", get_name().c_str());
08002 throw ImageFormatException("apply to real image only");
08003 }
08004
08005 vector<float> table = params["table"];
08006 vector<float>::size_type tsize = table.size();
08007
08008 int nx = image->get_xsize();
08009 int ny = image->get_ysize();
08010 int nz = image->get_zsize();
08011
08012 int nx2 = nx / 2;
08013 int ny2 = ny / 2;
08014 int nz2 = nz / 2;
08015 float sz[3];
08016 sz[0] = static_cast<float>(nx2);
08017 sz[1] = static_cast<float>(ny2);
08018 sz[2] = static_cast<float>(nz2);
08019 float szmax = *std::max_element(&sz[0], &sz[3]);
08020 float maxsize;
08021 if(nz>1) {
08022 maxsize = (float)(1.8f * szmax);
08023 }
08024 else{
08025 maxsize = (float)(1.5f * szmax);
08026 }
08027 for(int i=tsize+1; i<maxsize; i++) {
08028 table.push_back(0.0f);
08029 }
08030
08031 float dx = 1.0f / (float)nx;
08032 float dy = 1.0f / (float)ny;
08033 float dz = 1.0f / (float)nz;
08034 float dx2 = dx * dx;
08035 float dy2 = dy * dy;
08036 float dz2 = dz * dz;
08037 int iz, iy, ix, jz, jy, jx;
08038 float argx, argy, argz;
08039 float rf, df, f;
08040 int ir;
08041 for(iz=1; iz<=nz; iz++) {
08042 jz = iz - 1;
08043 if(jz > nz2) {
08044 jz -= nz;
08045 }
08046 argz = float(jz*jz) * dz2;
08047
08048 for(iy=1; iy<=ny; iy++) {
08049 jy = iy - 1;
08050 if(jy > ny2) {
08051 jy -= ny;
08052 }
08053 argy = argz + float(jy*jy) * dy2;
08054
08055 for(ix=1; ix<=nx; ix++) {
08056 jx = ix -1;
08057 argx = argy + float(jx*jx)*dx2;
08058
08059 rf = sqrt(argx)*2.0f*nx2;
08060 ir = int(rf);
08061 df = rf - float(ir);
08062 f = table[ir] + df*(table[ir+1]-table[ir]);
08063
08064 (*image)(ix-1,iy-1,iz-1) *= f;
08065 }
08066 }
08067 }
08068
08069 image->update();
08070 }
08071
08072 void MirrorProcessor::process_inplace(EMData *image)
08073 {
08074 if (!image) {
08075 LOGWARN("NULL Image");
08076 return;
08077 }
08078
08079 string axis = (const char*)params["axis"];
08080
08081 float* data = image->EMData::get_data();
08082
08083 int nx = image->get_xsize();
08084 int ny = image->get_ysize();
08085 int nz = image->get_zsize();
08086 size_t nxy = nx*ny;
08087
08088 int x_start = 1-nx%2;
08089 int y_start = 1-ny%2;
08090 int z_start = 1-nz%2;
08091
08092 if (axis == "x" || axis == "X") {
08093 for (int iz = 0; iz < nz; iz++)
08094 for (int iy = 0; iy < ny; iy++) {
08095 int offset = nx*iy + nxy*iz;
08096 reverse(&data[offset+x_start],&data[offset+nx]);
08097 }
08098 }
08099
08100 if (axis == "y" || axis == "Y") {
08101 float *tmp = new float[nx];
08102 int nhalf = ny/2;
08103 size_t beg = 0;
08104 for (int iz = 0; iz < nz; iz++) {
08105 beg = iz*nxy;
08106 for (int iy = y_start; iy < nhalf; iy++) {
08107 memcpy(tmp, &data[beg+iy*nx], nx*sizeof(float));
08108 memcpy(&data[beg+iy*nx], &data[beg+(ny-iy-1+y_start)*nx], nx*sizeof(float));
08109 memcpy(&data[beg+(ny-iy-1+y_start)*nx], tmp, nx*sizeof(float));
08110 }
08111 }
08112 delete[] tmp;
08113 }
08114
08115 if (axis == "z" || axis == "Z") {
08116 if(1-z_start){
08117 int nhalf = nz/2;
08118 float *tmp = new float[nxy];
08119 for(int iz = 0;iz<nhalf;iz++){
08120 memcpy(tmp,&data[iz*nxy],nxy*sizeof(float));
08121 memcpy(&data[iz*nxy],&data[(nz-iz-1)*nxy],nxy*sizeof(float));
08122 memcpy(&data[(nz-iz-1)*nxy],tmp,nxy*sizeof(float));
08123 }
08124 delete[] tmp;
08125 }
08126 else{
08127 float *tmp = new float[nx];
08128 int nhalf = nz/2;
08129 size_t beg = 0;
08130 for (int iy = 0; iy < ny; iy++) {
08131 beg = iy*nx;
08132 for (int iz = z_start; iz < nhalf; iz++) {
08133 memcpy(tmp, &data[beg+ iz*nxy], nx*sizeof(float));
08134 memcpy(&data[beg+iz*nxy], &data[beg+(nz-iz-1+z_start)*nxy], nx*sizeof(float));
08135 memcpy(&data[beg+(nz-iz-1+z_start)*nxy], tmp, nx*sizeof(float));
08136 }
08137 }
08138 delete[] tmp;
08139 }
08140 }
08141
08142 image->update();
08143 }
08144
08145
08146 int EMAN::multi_processors(EMData * image, vector < string > processornames)
08147 {
08148 Assert(image != 0);
08149 Assert(processornames.size() > 0);
08150
08151 for (size_t i = 0; i < processornames.size(); i++) {
08152 image->process_inplace(processornames[i]);
08153 }
08154 return 0;
08155 }
08156
08157
08158 float* TransformProcessor::transform(const EMData* const image, const Transform& t) const {
08159
08160 ENTERFUNC;
08161
08162 Transform inv = t.inverse();
08163 int nx = image->get_xsize();
08164 int ny = image->get_ysize();
08165 int nz = image->get_zsize();
08166 int nxy = nx*ny;
08167
08168 const float * const src_data = image->get_const_data();
08169 float *des_data = (float *) EMUtil::em_malloc(nx*ny*nz* sizeof(float));
08170
08171 if (nz == 1) {
08172 Vec2f offset(nx/2,ny/2);
08173 for (int j = 0; j < ny; j++) {
08174 for (int i = 0; i < nx; i++) {
08175 Vec2f coord(i-nx/2,j-ny/2);
08176 Vec2f soln = inv*coord;
08177 soln += offset;
08178
08179 float x2 = soln[0];
08180 float y2 = soln[1];
08181
08182 if (x2 < 0 || x2 >= nx || y2 < 0 || y2 >= ny ) {
08183 des_data[i + j * nx] = 0;
08184
08185 }
08186 else {
08187 int ii = Util::fast_floor(x2);
08188 int jj = Util::fast_floor(y2);
08189 int k0 = ii + jj * nx;
08190 int k1 = k0 + 1;
08191 int k2 = k0 + nx;
08192 int k3 = k0 + nx + 1;
08193
08194 if (ii == nx - 1) {
08195 k1--;
08196 k3--;
08197 }
08198 if (jj == ny - 1) {
08199 k2 -= nx;
08200 k3 -= nx;
08201 }
08202
08203 float t = x2 - ii;
08204 float u = y2 - jj;
08205
08206 des_data[i + j * nx] = Util::bilinear_interpolate(src_data[k0],src_data[k1], src_data[k2], src_data[k3],t,u);
08207 }
08208 }
08209 }
08210 }
08211 else {
08212 size_t l=0, ii, k0, k1, k2, k3, k4, k5, k6, k7;
08213 Vec3f offset(nx/2,ny/2,nz/2);
08214 float x2, y2, z2, tuvx, tuvy, tuvz;
08215 int ix, iy, iz;
08216 for (int k = 0; k < nz; ++k) {
08217 for (int j = 0; j < ny; ++j) {
08218 for (int i = 0; i < nx; ++i,++l) {
08219 Vec3f coord(i-nx/2,j-ny/2,k-nz/2);
08220 Vec3f soln = inv*coord;
08221 soln += offset;
08222
08223 x2 = soln[0];
08224 y2 = soln[1];
08225 z2 = soln[2];
08226
08227 if (x2 < 0 || y2 < 0 || z2 < 0 || x2 >= nx || y2 >= ny || z2>= nz ) {
08228 des_data[l] = 0;
08229 }
08230 else {
08231 ix = Util::fast_floor(x2);
08232 iy = Util::fast_floor(y2);
08233 iz = Util::fast_floor(z2);
08234 tuvx = x2-ix;
08235 tuvy = y2-iy;
08236 tuvz = z2-iz;
08237 ii = ix + iy * nx + iz * nxy;
08238
08239 k0 = ii;
08240 k1 = k0 + 1;
08241 k2 = k0 + nx;
08242 k3 = k0 + nx+1;
08243 k4 = k0 + nxy;
08244 k5 = k1 + nxy;
08245 k6 = k2 + nxy;
08246 k7 = k3 + nxy;
08247
08248 if (ix == nx - 1) {
08249 k1--;
08250 k3--;
08251 k5--;
08252 k7--;
08253 }
08254 if (iy == ny - 1) {
08255 k2 -= nx;
08256 k3 -= nx;
08257 k6 -= nx;
08258 k7 -= nx;
08259 }
08260 if (iz == nz - 1) {
08261 k4 -= nxy;
08262 k5 -= nxy;
08263 k6 -= nxy;
08264 k7 -= nxy;
08265 }
08266
08267 des_data[l] = Util::trilinear_interpolate(src_data[k0],
08268 src_data[k1], src_data[k2], src_data[k3], src_data[k4],
08269 src_data[k5], src_data[k6], src_data[k7], tuvx, tuvy, tuvz);
08270 }
08271 }
08272 }
08273 }
08274 }
08275
08276 EXITFUNC;
08277 return des_data;
08278 }
08279
08280 void TransformProcessor::assert_valid_aspect(const EMData* const image) const {
08281 int ndim = image->get_ndim();
08282 if (ndim != 2 && ndim != 3) throw ImageDimensionException("Transforming an EMData only works if it's 2D or 3D");
08283
08284 if (! params.has_key("transform") ) throw InvalidParameterException("You must specify a Transform in order to perform this operation");
08285 }
08286
08287
08288
08289
08290
08291
08292
08293
08304
08305
08306
08307
08308
08309
08310
08311
08312
08313
08314
08315
08316
08317
08318
08319 EMData* TransformProcessor::process(const EMData* const image) {
08320 ENTERFUNC;
08321
08322 assert_valid_aspect(image);
08323
08324 Transform* t = params["transform"];
08325
08326 EMData* p = 0;
08327 #ifdef EMAN2_USING_CUDA
08328 if (image->gpu_operation_preferred()) {
08329
08330 float * m = new float[12];
08331 Transform inv = t->inverse();
08332 inv.copy_matrix_into_array(m);
08333 image->bind_cuda_texture();
08334 EMDataForCuda* tmp = emdata_transform_cuda(m,image->get_xsize(),image->get_ysize(),image->get_zsize());
08335 image->unbind_cuda_texture();
08336 delete [] m;
08337 if (tmp == 0) throw;
08338
08339 p = new EMData();
08340 p->set_gpu_rw_data(tmp->data,tmp->nx,tmp->ny,tmp->nz);
08341 free(tmp);
08342 }
08343 #endif
08344 if ( p == 0 ) {
08345 float* des_data = transform(image,*t);
08346 p = new EMData(des_data,image->get_xsize(),image->get_ysize(),image->get_zsize(),image->get_attr_dict());
08347 }
08348
08349
08350
08351 float scale = t->get_scale();
08352 if (scale != 1.0) {
08353 p->scale_pixel(1.0f/scale);
08354
08355 }
08356
08357 if(t) {delete t; t=0;}
08358 EXITFUNC;
08359 return p;
08360 }
08361
08362 void TransformProcessor::process_inplace(EMData* image) {
08363 ENTERFUNC;
08364
08365 assert_valid_aspect(image);
08366
08367 Transform* t = params["transform"];
08368
08369
08370 bool use_cpu = true;
08371 #ifdef EMAN2_USING_CUDA
08372 if (image->gpu_operation_preferred()) {
08373 use_cpu = false;
08374 float * m = new float[12];
08375 Transform inv = t->inverse();
08376 inv.copy_matrix_into_array(m);
08377 image->bind_cuda_texture();
08378 EMDataForCuda* tmp = emdata_transform_cuda(m,image->get_xsize(),image->get_ysize(),image->get_zsize());
08379 image->unbind_cuda_texture();
08380 delete [] m;
08381 if (tmp == 0) throw;
08382 image->set_gpu_rw_data(tmp->data,tmp->nx,tmp->ny,tmp->nz);
08383 free(tmp);
08384 }
08385 #endif
08386 if ( use_cpu ) {
08387 float* des_data = transform(image,*t);
08388 image->set_data(des_data,image->get_xsize(),image->get_ysize(),image->get_zsize());
08389 image->update();
08390 }
08391 float scale = t->get_scale();
08392 if (scale != 1.0) {
08393 image->scale_pixel(1.0f/scale);
08394
08395 }
08396
08397 if(t) {delete t; t=0;}
08398
08399 EXITFUNC;
08400 }
08401
08402
08403 void IntTranslateProcessor::assert_valid_aspect(const vector<int>& translation, const EMData* const image) const {
08404 if (translation.size() == 0 ) throw InvalidParameterException("You must specify the trans argument");
08405 }
08406
08407 Region IntTranslateProcessor::get_clip_region(vector<int>& translation, const EMData* const image) const {
08408 unsigned int dim = static_cast<unsigned int> (image->get_ndim());
08409
08410 if ( translation.size() != dim ) {
08411 for(unsigned int i = translation.size(); i < dim; ++i ) translation.push_back(0);
08412 }
08413
08414 Region clip_region;
08415 if (dim == 1) {
08416 clip_region = Region(-translation[0],image->get_xsize());
08417 } else if ( dim == 2 ) {
08418 clip_region = Region(-translation[0],-translation[1],image->get_xsize(),image->get_ysize());
08419 } else if ( dim == 3 ) {
08420 clip_region = Region(-translation[0],-translation[1],-translation[2],image->get_xsize(),image->get_ysize(),image->get_zsize());
08421 } else throw ImageDimensionException("Only 1,2 and 3D images are supported");
08422
08423 return clip_region;
08424 }
08425
08426 void IntTranslateProcessor::process_inplace(EMData* image) {
08427
08428 vector<int> translation = params.set_default("trans",vector<int>() );
08429
08430
08431 assert_valid_aspect(translation,image);
08432
08433 Region clip_region = get_clip_region(translation,image);
08434
08435 image->clip_inplace(clip_region,0);
08436
08437 }
08438
08439 EMData* IntTranslateProcessor::process(const EMData* const image) {
08440
08441 vector<int> translation = params.set_default("trans",vector<int>() );
08442
08443 assert_valid_aspect(translation,image);
08444
08445 Region clip_region = get_clip_region(translation,image);
08446
08447 return image->get_clip(clip_region,0);
08448
08449 }
08450
08451
08452 void ScaleTransformProcessor::process_inplace(EMData* image) {
08453 int ndim = image->get_ndim();
08454 if (ndim != 2 && ndim != 3) throw UnexpectedBehaviorException("The Scale Transform processors only works for 2D and 3D images");
08455
08456 if ( image->get_xsize() != image->get_ysize()) {
08457 throw ImageDimensionException("x size and y size of image do not match. This processor only works for uniformly sized data");
08458 }
08459 if ( ndim == 3 ) {
08460 if ( image->get_xsize() != image->get_zsize()) {
08461 throw ImageDimensionException("x size and z size of image do not match. This processor only works for uniformly sized data");
08462 }
08463 }
08464
08465 float scale = params.set_default("scale",0.0f);
08466 if (scale <= 0.0f) throw InvalidParameterException("The scale parameter must be greater than 0");
08467
08468 int clip = 0;
08469
08470 if(params.has_key("clip"))
08471 {
08472 clip = params["clip"];
08473 if (clip < 0) throw InvalidParameterException("The clip parameter must be greater than 0");
08474 }
08475 else
08476 {
08477 clip = (int)(scale*image->get_xsize());
08478 }
08479
08480 Region r;
08481 if (ndim == 3) {
08482 r = Region( (image->get_xsize()-clip)/2, (image->get_xsize()-clip)/2, (image->get_xsize()-clip)/2,clip, clip,clip);
08483 } else {
08484 r = Region( (image->get_xsize()-clip)/2, (image->get_xsize()-clip)/2, clip, clip);
08485 }
08486
08487 if (scale > 1) {
08488 if ( clip != 0) {
08489 image->clip_inplace(r);
08490 }
08491 Transform t;
08492 t.set_scale(scale);
08493 image->process_inplace("xform",Dict("transform",&t));
08494 } else if (scale < 1) {
08495 Transform t;
08496 t.set_scale(scale);
08497 image->process_inplace("xform",Dict("transform",&t));
08498 if ( clip != 0) {
08499 image->clip_inplace(r);
08500 }
08501 } else {
08502 if ( clip != 0) {
08503 image->clip_inplace(r);
08504 }
08505 }
08506 }
08507
08508 EMData* ScaleTransformProcessor::process(const EMData* const image) {
08509 int ndim = image->get_ndim();
08510 if (ndim != 2 && ndim != 3) throw UnexpectedBehaviorException("The Scale Transform processors only works for 2D and 3D images");
08511
08512 if ( image->get_xsize() != image->get_ysize()) {
08513 throw ImageDimensionException("x size and y size of image do not match. This processor only works for uniformly sized data");
08514 }
08515 if ( ndim == 3 ) {
08516 if ( image->get_xsize() != image->get_zsize()) {
08517 throw ImageDimensionException("x size and z size of image do not match. This processor only works for uniformly sized data");
08518 }
08519 }
08520
08521 float scale = params.set_default("scale",0.0f);
08522 if (scale <= 0.0f) throw InvalidParameterException("The scale parameter must be greater than 0");
08523
08524 int clip = 0;
08525
08526 if(params.has_key("clip"))
08527 {
08528 clip = params["clip"];
08529 if (clip < 0) throw InvalidParameterException("The clip parameter must be greater than 0");
08530 }
08531 else
08532 {
08533 clip = (int)(scale*image->get_xsize());
08534 }
08535
08536 Region r;
08537 if (ndim == 3) {
08538 r = Region( (image->get_xsize()-clip)/2, (image->get_xsize()-clip)/2, (image->get_xsize()-clip)/2,clip, clip,clip);
08539 } else {
08540 r = Region( (image->get_xsize()-clip)/2, (image->get_xsize()-clip)/2, clip, clip);
08541 }
08542
08543 EMData* ret = 0;
08544 if (scale > 1) {
08545 if ( clip != 0) {
08546 ret = image->get_clip(r);
08547 }
08548 Transform t;
08549 t.set_scale(scale);
08550 if (ret != 0) {
08551 ret->process_inplace("xform",Dict("transform",&t));
08552 } else {
08553 ret = image->process("xform",Dict("transform",&t));
08554 }
08555 } else if (scale < 1) {
08556 Transform t;
08557 t.set_scale(scale);
08558 ret = image->process("xform",Dict("transform",&t));
08559 if ( clip != 0) {
08560 ret->clip_inplace(r);
08561 }
08562 } else {
08563 if ( clip != 0) {
08564 ret = image->get_clip(r);
08565 } else {
08566 ret = image->copy();
08567 }
08568 }
08569 return ret;
08570
08571 }
08572
08573 void Rotate180Processor::process_inplace(EMData* image) {
08574 ENTERFUNC;
08575
08576
08577 if (image->get_ndim() != 2) {
08578 throw ImageDimensionException("2D only");
08579 }
08580
08581 #ifdef EMAN2_USING_CUDA
08582 if (image->gpu_operation_preferred() ) {
08583 EMDataForCuda tmp = image->get_data_struct_for_cuda();
08584 emdata_rotate_180(&tmp);
08585 image->gpu_update();
08586 EXITFUNC;
08587 return;
08588 }
08589 #endif
08590
08591 float *d = image->get_data();
08592 int nx = image->get_xsize();
08593 int ny = image->get_ysize();
08594
08595
08596 int x_offset = 0;
08597 if (nx % 2 == 1) x_offset=1;
08598 int y_offset = 0;
08599 if (ny % 2 == 1) y_offset=1;
08600
08601 bool stop = false;
08602 for (int x = 1; x <= (nx/2+x_offset); x++) {
08603 int y = 0;
08604 for (y = 1; y < (ny+y_offset); y++) {
08605 if (x == (nx / 2+x_offset) && y == (ny / 2+y_offset)) {
08606 stop = true;
08607 break;
08608 }
08609 int i = (x-x_offset) + (y-y_offset) * nx;
08610 int k = nx - x + (ny - y) * nx;
08611
08612 float t = d[i];
08613 d[i] = d[k];
08614 d[k] = t;
08615 }
08616 if (stop) break;
08617 }
08618
08619
08620
08621
08622
08623
08624
08625
08626 if (x_offset == 0) {
08627 for (int y = 0; y < ny; y++) {
08628 image->set_value_at_fast(0,y,image->get_value_at(1,y));
08629 }
08630 }
08631
08632 if (y_offset == 0) {
08633 for (int x = 0; x < nx; x++) {
08634 image->set_value_at_fast(x,0,image->get_value_at(x,1));
08635 }
08636 }
08637
08638 if (y_offset == 0 && x_offset == 0) {
08639 image->set_value_at_fast(0,0,image->get_value_at(1,1));
08640 }
08641
08642 image->update();
08643 EXITFUNC;
08644 }
08645
08646
08647 void ClampingProcessor::process_inplace( EMData* image )
08648 {
08649
08650 if ( image->is_complex() ) throw ImageFormatException("Error: clamping processor does not work on complex images");
08651
08652 float min = params.set_default("minval",default_min);
08653 float max = params.set_default("maxval",default_max);
08654 bool tomean = params.set_default("tomean",false);
08655 float new_min_vals = min;
08656 float new_max_vals = max;
08657 if (tomean){
08658
08659 new_min_vals = image->get_attr("mean");
08660 new_max_vals = image->get_attr("mean");
08661 }
08662
08663
08664
08665 if ( max < min ) throw InvalidParameterException("Error: minval was greater than maxval, aborting");
08666
08667 size_t size = image->get_size();
08668 for(size_t i = 0; i < size; ++i )
08669 {
08670 float * data = &image->get_data()[i];
08671 if ( *data < min ) *data = new_min_vals;
08672 else if ( *data > max ) *data = new_max_vals;
08673 }
08674 image->update();
08675 }
08676
08677 void TestTomoImage::insert_rectangle( EMData* image, const Region& region, const float& value, const Transform& t3d )
08678 {
08679 int startx = (int)region.origin[0] - (int)region.size[0]/2;
08680 int starty = (int)region.origin[1] - (int)region.size[1]/2;
08681 int startz = (int)region.origin[2] - (int)region.size[2]/2;
08682
08683 int endx = (int)region.origin[0] + (int)region.size[0]/2;
08684 int endy = (int)region.origin[1] + (int)region.size[1]/2;
08685 int endz = (int)region.origin[2] + (int)region.size[2]/2;
08686
08687 if ( ! t3d.is_identity() ) {
08688 float xt, yt, zt;
08689 for ( float z = (float)startz; z < (float)endz; z += 0.25f ) {
08690 for ( float y = (float)starty; y < (float)endy; y += 0.25f ) {
08691 for ( float x = (float)startx; x < (float)endx; x += 0.25f ) {
08692 xt = (float) x - region.origin[0];
08693 yt = (float) y - region.origin[1];
08694 zt = (float) z - region.origin[2];
08695 Vec3f v((float)xt,(float)yt,(float)zt);
08696 v = t3d*v;
08697 image->set_value_at((int)(v[0]+region.origin[0]),(int)(v[1]+region.origin[1]),(int)(v[2]+region.origin[2]), value);
08698 }
08699 }
08700 }
08701 } else {
08702 for ( int z = startz; z < endz; ++z ) {
08703 for ( int y = starty; y < endy; ++y ) {
08704 for ( int x = startx; x < endx; ++x ) {
08705 image->set_value_at(x,y,z, value);
08706 }
08707 }
08708 }
08709 }
08710 }
08711
08712 void TestTomoImage::process_inplace( EMData* image )
08713 {
08714
08715
08716
08717
08718
08719 float nx = (float) image->get_xsize();
08720 float ny = (float) image->get_ysize();
08721 float nz = (float) image->get_zsize();
08722
08723
08724
08725
08726 float inc = 1.0f/22.0f;
08727 float xinc = inc;
08728 float yinc = inc;
08729 float zinc = inc;
08730
08731 Dict d;
08732 d["a"] = (float) .4*nx+3;
08733 d["b"] = (float) .4*ny+3;
08734 d["c"] = (float) .4*nz+3;
08735 d["fill"] = 0.2;
08736 image->process_inplace("testimage.ellipsoid",d);
08737
08738 d["a"] = (float) .4*nx;
08739 d["b"] = (float) .4*ny;
08740 d["c"] = (float) .4*nz;
08741 d["fill"] = 0.1;
08742 image->process_inplace("testimage.ellipsoid",d);
08743
08744
08745 {
08746 Transform t;
08747 t.set_trans(0.,ny*4.0f*yinc-ny/2,0);
08748 Dict d;
08749 d["transform"] = &t;
08750 d["a"] = (float) 2.*xinc*nx;
08751 d["b"] = (float)0.5*yinc*ny;
08752 d["c"] = (float) 1.*zinc*nz;
08753 d["fill"] = 0.3;
08754 image->process_inplace("testimage.ellipsoid",d);
08755 }
08756
08757 {
08758 Transform t;
08759 t.set_trans(0.,ny*5.5f*yinc-ny/2,0);
08760 Dict d;
08761 d["transform"] = &t;
08762 d["a"] = (float) 1.5*xinc*nx;
08763 d["b"] = (float)0.5*yinc*ny;
08764 d["c"] = (float) 1.*zinc*nz;
08765 d["fill"] = 0.0;
08766 image->process_inplace("testimage.ellipsoid",d);
08767 }
08768 {
08769 Transform t;
08770 t.set_trans(0.,ny*7*yinc-ny/2,0);
08771 Dict d;
08772 d["transform"] = &t;
08773 d["a"] = (float) 1.*xinc*nx;
08774 d["b"] = (float)0.5*yinc*ny;
08775 d["c"] = (float) 1.*zinc*nz;
08776 d["fill"] = 0.3;
08777 image->process_inplace("testimage.ellipsoid",d);
08778 }
08779
08780
08781 {
08782 Transform t;
08783 t.set_trans(0.,ny*8.5f*yinc-ny/2,0);
08784 Dict d;
08785 d["transform"] = &t;
08786 d["a"] = (float) .75*xinc*nx;
08787 d["b"] = (float)0.5*yinc*ny;
08788 d["c"] = (float) 1.*zinc*nz;
08789 d["fill"] = 0.0;
08790 image->process_inplace("testimage.ellipsoid",d);
08791 }
08792
08793
08794 {
08795 Transform t;
08796 t.set_trans(0.,ny*18*yinc-ny/2,0);
08797 Dict d;
08798 d["transform"] = &t;
08799 d["a"] = (float) 2*xinc*nx;
08800 d["b"] = (float)0.5*yinc*ny;
08801 d["c"] = (float) 1.*zinc*nz;
08802 d["fill"] = 0.3;
08803 image->process_inplace("testimage.ellipsoid",d);
08804 }
08805
08806 {
08807 Transform t;
08808 t.set_trans(0.,ny*16.5f*yinc-ny/2,0);
08809 Dict d;
08810 d["transform"] = &t;
08811 d["a"] = (float) 1.5*xinc*nx;
08812 d["b"] = (float)0.5*yinc*ny;
08813 d["c"] = (float) 1.*zinc*nz;
08814 d["fill"] = 0.3;
08815 image->process_inplace("testimage.ellipsoid",d);
08816 }
08817
08818 {
08819 Transform t;
08820 t.set_trans(0.,ny*15*yinc-ny/2,0);
08821 Dict d;
08822 d["transform"] = &t;
08823 d["a"] = (float) 1*xinc*nx;
08824 d["b"] = (float)0.5*yinc*ny;
08825 d["c"] = (float) 1.*zinc*nz;
08826 d["fill"] = 0.3f;
08827 image->process_inplace("testimage.ellipsoid",d);
08828 }
08829
08830 {
08831 Transform t;
08832 t.set_trans(0.,ny*13.5f*yinc-ny/2,0);
08833 Dict d;
08834 d["transform"] = &t;
08835 d["a"] = (float).75*xinc*nx;
08836 d["b"] = (float)0.5*yinc*ny;
08837 d["c"] = (float) 1.*zinc*nz;
08838 d["fill"] = 0.3;
08839 image->process_inplace("testimage.ellipsoid",d);
08840 }
08841
08842
08843 {
08844
08845 Transform t;
08846 t.set_trans(nx*6*xinc-nx/2,ny*5*yinc-ny/2,0);
08847 Dict d;
08848 d["transform"] = &t;
08849 d["a"] = (float)1*xinc*nx;
08850 d["b"] = (float).75*yinc*ny;
08851 d["c"] = (float) .75*zinc*nz;
08852 d["fill"] = 0.25;
08853 image->process_inplace("testimage.ellipsoid",d);
08854 }
08855
08856 {
08857 Transform t;
08858 t.set_trans(nx*6*xinc-nx/2,ny*7*yinc-ny/2,0);
08859 Dict d;
08860 d["transform"] = &t;
08861 d["a"] = (float)1.5*xinc*nx;
08862 d["b"] = (float).75*yinc*ny;
08863 d["c"] = (float) .75*zinc*nz;
08864 d["fill"] = 0.25;
08865 image->process_inplace("testimage.ellipsoid",d);
08866 }
08867
08868 {
08869 Transform t;
08870 t.set_trans(nx*6*xinc-nx/2,ny*9*yinc-ny/2,0);
08871 Dict d;
08872 d["transform"] = &t;
08873 d["a"] = (float)2*xinc*nx;
08874 d["b"] = (float).75*yinc*ny;
08875 d["c"] = (float) .75*zinc*nz;
08876 d["fill"] = 0.25;
08877 image->process_inplace("testimage.ellipsoid",d);
08878 }
08879
08880 {
08881 Transform t;
08882 t.set_trans(nx*6*xinc-nx/2,ny*11*yinc-ny/2,0);
08883 Dict d;
08884 d["transform"] = &t;
08885 d["a"] = (float)2.5*xinc*nx;
08886 d["b"] = (float).75*yinc*ny;
08887 d["c"] = (float) 1*zinc*nz;
08888 d["fill"] = 0.25;
08889 image->process_inplace("testimage.ellipsoid",d);
08890 }
08891
08892 {
08893 Transform t;
08894 t.set_trans(nx*6*xinc-nx/2,ny*13*yinc-ny/2,0);
08895 Dict d;
08896 d["transform"] = &t;
08897 d["a"] = (float) 3*xinc*nx;
08898 d["b"] = (float).75*yinc*ny;
08899 d["c"] = (float) 1*zinc*nz;
08900 d["fill"] = 0.25;
08901 image->process_inplace("testimage.ellipsoid",d);
08902 }
08903
08904
08905 {
08906 Region region(nx*15.*inc,ny*17.*inc,nz/2.,1.*inc*nx,1.5*inc*ny,1.5*inc*nz);
08907 insert_rectangle(image, region, 0.25);
08908 }
08909 {
08910 Region region(nx*15.*inc,ny*15.*inc,nz/2.,1.5*inc*nx,1.5*inc*ny,1.5*inc*nz);
08911 insert_rectangle(image, region, 0.25);
08912 }
08913 {
08914 Region region(nx*15.*inc,ny*13.*inc,nz/2.,2.*inc*nx,1.5*inc*ny,1.5*inc*nz);
08915 insert_rectangle(image, region, 0.25);
08916 }
08917 {
08918 Region region(nx*15.*inc,ny*11.*inc,nz/2.,2.5*inc*nx,1.5*inc*ny,1.5*inc*nz);
08919 insert_rectangle(image, region, 0.25);
08920 }
08921 {
08922 Region region(nx*15.*inc,ny*9.*inc,nz/2.,3.*inc*nx,1.5*inc*ny,1.5*inc*nz);
08923 insert_rectangle(image, region, 0.25);
08924 }
08925
08926
08927 {
08928 Region region(nx/2.,ny/2.,nz/2.,2.*inc*nx,2.5*inc*ny,1.*inc*nz);
08929 Transform t3d(Dict("type","eman","az",(float)-25.0));
08930 insert_rectangle(image, region, 0.4f, t3d);
08931 }
08932
08933
08934 {
08935 Transform t;
08936 t.set_trans(nx*6.8f*xinc-nx/2,ny*16*yinc-ny/2,0);
08937 Dict rot;
08938 rot["type"] = "eman";
08939 rot["az"] = 43.0f;
08940 t.set_rotation(rot);
08941 Dict d;
08942 d["transform"] = &t;
08943 d["a"] = (float) 1.5*xinc*nx;
08944 d["b"] = (float) .5*yinc*ny;
08945 d["c"] = (float) .5*zinc*nz;
08946 d["fill"] = 0.2;
08947 image->process_inplace("testimage.ellipsoid",d);
08948 }
08949 {
08950 Transform t;
08951 t.set_trans(nx*7.2f*xinc-nx/2,ny*16*yinc-ny/2,0);
08952 Dict rot;
08953 rot["type"] = "eman";
08954 rot["az"] = 135.0f;
08955 t.set_rotation(rot);
08956 Dict d;
08957 d["transform"] = &t;
08958 d["a"] = (float) 1.5*xinc*nx;
08959 d["b"] = (float) .5*yinc*ny;
08960 d["c"] = (float) .5*zinc*nz;
08961 d["fill"] = 0.3;
08962 image->process_inplace("testimage.ellipsoid",d);
08963 }
08964
08965
08966 {
08967 Transform t;
08968 t.set_trans(nx*3.5f*xinc-nx/2,ny*8*yinc-ny/2,0);
08969 Dict d;
08970 d["transform"] = &t;
08971 d["a"] = (float) .5*xinc*nx;
08972 d["b"] = (float) .5*yinc*ny;
08973 d["c"] = (float) .5*zinc*nz;
08974 d["fill"] = 2.05;
08975 image->process_inplace("testimage.ellipsoid",d);
08976
08977 t.set_trans(nx*8*xinc-nx/2,ny*18*yinc-ny/2,0);
08978 image->process_inplace("testimage.ellipsoid",d);
08979
08980 t.set_trans(nx*14*xinc-nx/2,ny*18.2f*yinc-ny/2,0);
08981 image->process_inplace("testimage.ellipsoid",d);
08982
08983 t.set_trans(nx*18*xinc-nx/2,ny*14*yinc-ny/2,0);
08984 image->process_inplace("testimage.ellipsoid",d);
08985
08986 t.set_trans(nx*17*xinc-nx/2,ny*7.5f*yinc-ny/2,0);
08987 image->process_inplace("testimage.ellipsoid",d);
08988 }
08989
08990
08991
08992 {
08993 Region region(nx*18.*inc,ny*11.5*inc,nz/2.,1.*inc*nx,1.*inc*ny,1.*inc*nz);
08994 Transform t3d(Dict("type","eman","az",(float)45.0));
08995 insert_rectangle(image, region, 1.45f, t3d);
08996 }
08997 {
08998 Region region(nx*3.*inc,ny*10.5*inc,nz/2.,1.*inc*nx,1.*inc*ny,1.*inc*nz);
08999 Transform t3d(Dict("type","eman","az",(float)45.0));
09000 insert_rectangle(image, region, 1.45f, t3d);
09001 }
09002
09003
09004 {
09005 Transform t;
09006 t.set_trans(nx*14*xinc-nx/2,ny*7.5f*yinc-ny/2,0);
09007 Dict d;
09008 d["transform"] = &t;
09009 d["a"] = (float) .5*xinc*nx;
09010 d["b"] = (float) .5*yinc*ny;
09011 d["c"] = (float) .5*zinc*nz;
09012 d["fill"] = .35;
09013 image->process_inplace("testimage.ellipsoid",d);
09014 }
09015 {
09016 Transform t;
09017 t.set_trans(nx*15*xinc-nx/2,ny*7.5f*yinc-ny/2,0);
09018 Dict d;
09019 d["transform"] = &t;
09020 d["a"] = (float) .25*xinc*nx;
09021 d["b"] = (float) .25*yinc*ny;
09022 d["c"] = (float) .25*zinc*nz;
09023 d["fill"] = .35;
09024 image->process_inplace("testimage.ellipsoid",d);
09025
09026 t.set_trans(nx*13.5f*xinc-nx/2,ny*6.5f*yinc-ny/2,0);
09027 image->process_inplace("testimage.ellipsoid",d);
09028
09029 t.set_trans(nx*14.5f*xinc-nx/2,ny*6.5f*yinc-ny/2,0);
09030 image->process_inplace("testimage.ellipsoid",d);
09031
09032 t.set_trans(nx*15.5f*xinc-nx/2,ny*6.5f*yinc-ny/2,0);
09033 image->process_inplace("testimage.ellipsoid",d);
09034
09035 t.set_trans(nx*14*xinc-nx/2,ny*5.5f*yinc-ny/2,0);
09036 image->process_inplace("testimage.ellipsoid",d);
09037
09038 t.set_trans(nx*14*xinc-nx/2,ny*5.5f*yinc-ny/2,0);
09039 image->process_inplace("testimage.ellipsoid",d);
09040
09041 t.set_trans(nx*15*xinc-nx/2,ny*5.5f*yinc-ny/2,0);
09042 image->process_inplace("testimage.ellipsoid",d);
09043
09044 t.set_trans(nx*16*xinc-nx/2,ny*5.5f*yinc-ny/2,0);
09045 image->process_inplace("testimage.ellipsoid",d);
09046
09047 t.set_trans(nx*14.5f*xinc-nx/2,ny*4.5f*yinc-ny/2,0);
09048 image->process_inplace("testimage.ellipsoid",d);
09049
09050 t.set_trans(nx*15.5f*xinc-nx/2,ny*4.5f*yinc-ny/2,0);
09051 image->process_inplace("testimage.ellipsoid",d);
09052 }
09053
09054
09055
09056
09057
09058
09059
09060
09061 }
09062
09063 void NSigmaClampingProcessor::process_inplace(EMData *image)
09064 {
09065 float nsigma = params.set_default("nsigma",default_sigma);
09066 float sigma = image->get_attr("sigma");
09067 float mean = image->get_attr("mean");
09068 params.set_default("minval",mean - nsigma*sigma);
09069 params.set_default("maxval",mean + nsigma*sigma);
09070
09071 ClampingProcessor::process_inplace(image);
09072 }
09073
09074 void HistogramBin::process_inplace(EMData *image)
09075 {
09076 float min = image->get_attr("minimum");
09077 float max = image->get_attr("maximum");
09078 float nbins = (float)params.set_default("nbins",default_bins);
09079 bool debug = params.set_default("debug",false);
09080
09081 vector<int> debugscores;
09082 if ( debug ) {
09083 debugscores = vector<int>((int)nbins, 0);
09084 }
09085
09086 if ( nbins < 0 ) throw InvalidParameterException("nbins must be greater than 0");
09087
09088 float bin_width = (max-min)/nbins;
09089 float bin_val_offset = bin_width/2.0f;
09090
09091 size_t size = image->get_size();
09092 float* dat = image->get_data();
09093
09094 for(size_t i = 0; i < size; ++i ) {
09095 float val = dat[i];
09096 val -= min;
09097 int bin = (int) (val/bin_width);
09098
09099
09100 if (bin == nbins) bin -= 1;
09101
09102 dat[i] = min + bin*bin_width + bin_val_offset;
09103 if ( debug ) {
09104 debugscores[bin]++;
09105 }
09106 }
09107
09108 if ( debug ) {
09109 int i = 0;
09110 for( vector<int>::const_iterator it = debugscores.begin(); it != debugscores.end(); ++it, ++i)
09111 cout << "Bin " << i << " has " << *it << " pixels in it" << endl;
09112 }
09113
09114 }
09115 void ConvolutionProcessor::process_inplace(EMData* image)
09116 {
09117
09118 EMData* null = 0;
09119 EMData* with = params.set_default("with", null);
09120 if ( with == NULL ) throw InvalidParameterException("Error - the image required for the convolution is null");
09121
09122 EMData* newimage = fourierproduct(image, with, CIRCULANT, CONVOLUTION, false);
09123
09124 float* orig = image->get_data();
09125 float* work = newimage->get_data();
09126 int nx = image->get_xsize();
09127 int ny = image->get_ysize();
09128 int nz = image->get_zsize();
09129 memcpy(orig,work,nx*ny*nz*sizeof(float));
09130 image->update();
09131
09132 delete newimage;
09133 }
09134
09135 void XGradientProcessor::process_inplace( EMData* image )
09136 {
09137 if (image->is_complex()) throw ImageFormatException("Cannot edge detect a complex image");
09138
09139 EMData* e = new EMData();
09140 int nx = image->get_xsize();
09141 int ny = image->get_ysize();
09142 int nz = image->get_zsize();
09143
09144 if ( nz == 1 && ny == 1 ) {
09145 if ( nx < 3 ) throw ImageDimensionException("Error - cannot edge detect an image with less than three pixels");
09146
09147 e->set_size(3,1,1);
09148 e->set_value_at(0,-1);
09149 e->set_value_at(2, 1);
09150
09151 Region r = Region(-nx/2+1,nx);
09152 e->clip_inplace(r);
09153 } else if ( nz == 1 ) {
09154 if ( nx < 3 || ny < 3 ) throw ImageDimensionException("Error - cannot edge detect an image with less than three pixels");
09155 e->set_size(3,3,1);
09156 e->set_value_at(0,0,-1);
09157 e->set_value_at(0,1,-2);
09158 e->set_value_at(0,2,-1);
09159
09160 e->set_value_at(2,0,1);
09161 e->set_value_at(2,1,2);
09162 e->set_value_at(2,2,1);
09163 Region r = Region(-nx/2+1,-ny/2+1,nx,ny);
09164 e->clip_inplace(r);
09165 } else {
09166 if ( nx < 3 || ny < 3 || nz < 3) throw ImageDimensionException("Error - cannot edge detect an image with less than three pixels");
09167 e->set_size(3,3,3);
09168 e->set_value_at(0,0,0,-1);
09169 e->set_value_at(0,1,0,-1);
09170 e->set_value_at(0,2,0,-1);
09171 e->set_value_at(0,0,1,-1);
09172 e->set_value_at(0,1,1,-8);
09173 e->set_value_at(0,2,1,-1);
09174 e->set_value_at(0,0,2,-1);
09175 e->set_value_at(0,1,2,-1);
09176 e->set_value_at(0,2,2,-1);
09177
09178 e->set_value_at(2,0,0,1);
09179 e->set_value_at(2,1,0,1);
09180 e->set_value_at(2,2,0,1);
09181 e->set_value_at(2,0,1,1);
09182 e->set_value_at(2,1,1,8);
09183 e->set_value_at(2,2,1,1);
09184 e->set_value_at(2,0,2,1);
09185 e->set_value_at(2,1,2,1);
09186 e->set_value_at(2,2,2,1);
09187
09188 Region r = Region(-nx/2+1,-ny/2+1,-nz/2+1,nx,ny,nz);
09189 e->clip_inplace(r);
09190 }
09191
09192 Dict conv_parms;
09193 conv_parms["with"] = e;
09194 image->process_inplace("math.convolution", conv_parms);
09195 image->process_inplace("xform.phaseorigin.tocenter");
09196
09197 delete e;
09198 }
09199
09200
09201 void TomoTiltAngleWeightProcessor::process_inplace( EMData* image )
09202 {
09203 bool fim = params.set_default("angle_fim", false);
09204 float alt;
09205 if ( fim ) {
09206 alt = image->get_attr("euler_alt");
09207 }
09208 else alt = params.set_default("angle", 0.0f);
09209
09210 float cosine = cos(alt*M_PI/180.0f);
09211 float mult_fac = 1.0f/(cosine);
09212 image->mult( mult_fac );
09213 }
09214
09215 void TomoTiltEdgeMaskProcessor::process_inplace( EMData* image )
09216 {
09217 bool biedgemean = params.set_default("biedgemean", false);
09218 bool edgemean = params.set_default("edgemean", false);
09219
09220 if (biedgemean && edgemean) throw InvalidParameterException("The edgemean and biedgemean options are mutually exclusive");
09221
09222 bool fim = params.set_default("angle_fim", false);
09223 float alt;
09224 if ( fim ) {
09225 Transform* t = (Transform*)image->get_attr("xform.projection");
09226 Dict d = t->get_params("eman");
09227 alt = (float) d["alt"];
09228 if(t) {delete t; t=0;}
09229 }
09230 else alt = params.set_default("angle", 0.0f);
09231
09232
09233 float cosine = cos(alt*M_PI/180.0f);
09234
09235
09236 int nx = image->get_xsize();
09237 int ny = image->get_ysize();
09238 int x_clip = static_cast<int>( (float) nx * ( 1.0 - cosine ) / 2.0);
09239
09240 float x1_edge_mean = 0.0;
09241 float x2_edge_mean = 0.0;
09242
09243 if ( biedgemean )
09244 {
09245 float edge_mean = 0.0;
09246
09247
09248 for ( int i = 0; i < ny; ++i ) {
09249 edge_mean += image->get_value_at(x_clip, i );
09250 edge_mean += image->get_value_at(nx - x_clip-1, i );
09251 }
09252
09253 edge_mean /= 2*ny;
09254
09255
09256 for ( int i = 0; i < ny; ++i ) {
09257 for ( int j = nx-1; j >= nx - x_clip; --j) {
09258 image->set_value_at(j,i,edge_mean);
09259 }
09260 for ( int j = 0; j < x_clip; ++j) {
09261 image->set_value_at(j,i,edge_mean);
09262 }
09263 }
09264 x1_edge_mean = edge_mean;
09265 x2_edge_mean = edge_mean;
09266 }
09267 else if (edgemean)
09268 {
09269 for ( int i = 0; i < ny; ++i ) {
09270 x1_edge_mean += image->get_value_at(x_clip, i );
09271 x2_edge_mean += image->get_value_at(nx - x_clip-1, i );
09272 }
09273 x1_edge_mean /= ny;
09274 x2_edge_mean /= ny;
09275
09276 for ( int i = 0; i < ny; ++i ) {
09277 for ( int j = 0; j < x_clip; ++j) {
09278 image->set_value_at(j,i,x1_edge_mean);
09279 }
09280 for ( int j = nx-1; j >= nx - x_clip; --j) {
09281 image->set_value_at(j,i,x2_edge_mean);
09282 }
09283 }
09284 }
09285 else
09286 {
09287
09288 Dict zero_dict;
09289 zero_dict["x0"] = x_clip;
09290 zero_dict["x1"] = x_clip;
09291 zero_dict["y0"] = 0;
09292 zero_dict["y1"] = 0;
09293 image->process_inplace( "mask.zeroedge2d", zero_dict );
09294 }
09295
09296 int gauss_rad = params.set_default("gauss_falloff", 0);
09297 if ( gauss_rad != 0)
09298 {
09299
09300
09301
09302 if ( gauss_rad > x_clip ) gauss_rad = x_clip;
09303
09304 float gauss_sigma = params.set_default("gauss_sigma", 3.0f);
09305 if ( gauss_sigma < 0 ) throw InvalidParameterException("Error - you must specify a positive, non-zero gauss_sigma");
09306 float sigma = (float) gauss_rad/gauss_sigma;
09307
09308 GaussianFunctoid gf(sigma);
09309
09310 for ( int i = 0; i < ny; ++i ) {
09311
09312 float left_value = image->get_value_at(x_clip, i );
09313 float scale1 = left_value-x1_edge_mean;
09314
09315 float right_value = image->get_value_at(nx - x_clip - 1, i );
09316 float scale2 = right_value-x2_edge_mean;
09317
09318 for ( int j = 1; j < gauss_rad; ++j )
09319 {
09320 image->set_value_at(x_clip-j, i, scale1*gf((float)j)+x1_edge_mean );
09321 image->set_value_at(nx - x_clip + j-1, i, scale2*gf((float)j)+x2_edge_mean);
09322 }
09323 }
09324 }
09325
09326 image->update();
09327 }
09328
09329 void YGradientProcessor::process_inplace( EMData* image )
09330 {
09331 if (image->is_complex()) throw ImageFormatException("Cannot edge detect a complex image");
09332
09333 EMData* e = new EMData();
09334 int nx = image->get_xsize();
09335 int ny = image->get_ysize();
09336 int nz = image->get_zsize();
09337
09338 if ( nz == 1 && ny == 1 ) {
09339 throw ImageDimensionException("Error - cannot detect Y edges for an image that that is 1D!");
09340 } else if ( nz == 1 ) {
09341 if ( nx < 3 || ny < 3 ) throw ImageDimensionException("Error - cannot edge detect an image with less than three pixels");
09342 e->set_size(3,3,1);
09343 e->set_value_at(0,0,-1);
09344 e->set_value_at(1,0,-2);
09345 e->set_value_at(2,0,-1);
09346
09347 e->set_value_at(0,2,1);
09348 e->set_value_at(1,2,2);
09349 e->set_value_at(2,2,1);
09350 Region r = Region(-nx/2+1,-ny/2+1,nx,ny);
09351 e->clip_inplace(r);
09352 } else {
09353 if ( nx < 3 || ny < 3 || nz < 3) throw ImageDimensionException("Error - cannot edge detect an image with less than three pixels");
09354 e->set_size(3,3,3);
09355 e->set_value_at(0,0,0,-1);
09356 e->set_value_at(1,0,0,-1);
09357 e->set_value_at(2,0,0,-1);
09358 e->set_value_at(0,0,1,-1);
09359 e->set_value_at(1,0,1,-8);
09360 e->set_value_at(2,0,1,-1);
09361 e->set_value_at(0,0,2,-1);
09362 e->set_value_at(1,0,2,-1);
09363 e->set_value_at(2,0,2,-1);
09364
09365 e->set_value_at(0,2,0,1);
09366 e->set_value_at(1,2,0,1);
09367 e->set_value_at(2,2,0,1);
09368 e->set_value_at(0,2,1,1);
09369 e->set_value_at(1,2,1,8);
09370 e->set_value_at(2,2,1,1);
09371 e->set_value_at(0,2,2,1);
09372 e->set_value_at(1,2,2,1);
09373 e->set_value_at(2,2,2,1);
09374
09375 Region r = Region(-nx/2+1,-ny/2+1,-nz/2+1,nx,ny,nz);
09376 e->clip_inplace(r);
09377 }
09378
09379 Dict conv_parms;
09380 conv_parms["with"] = e;
09381 image->process_inplace("math.convolution", conv_parms);
09382
09383 delete e;
09384 }
09385
09386
09387 void ZGradientProcessor::process_inplace( EMData* image )
09388 {
09389 if (image->is_complex()) throw ImageFormatException("Cannot edge detect a complex image");
09390
09391 EMData* e = new EMData();
09392 int nx = image->get_xsize();
09393 int ny = image->get_ysize();
09394 int nz = image->get_zsize();
09395
09396 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");
09397
09398 e->set_size(3,3,3);
09399 e->set_value_at(0,0,0,-1);
09400 e->set_value_at(1,0,0,-1);
09401 e->set_value_at(2,0,0,-1);
09402 e->set_value_at(0,1,0,-1);
09403 e->set_value_at(1,1,0,-8);
09404 e->set_value_at(2,1,0,-1);
09405 e->set_value_at(0,2,0,-1);
09406 e->set_value_at(1,2,0,-1);
09407 e->set_value_at(2,2,0,-1);
09408
09409 e->set_value_at(0,0,2,1);
09410 e->set_value_at(1,0,2,1);
09411 e->set_value_at(2,0,2,1);
09412 e->set_value_at(0,1,2,1);
09413 e->set_value_at(1,1,2,8);
09414 e->set_value_at(2,1,2,1);
09415 e->set_value_at(0,2,2,1);
09416 e->set_value_at(1,2,2,1);
09417 e->set_value_at(2,2,2,1);
09418
09419 Region r = Region(-nx/2+1,-ny/2+1,-nz/2+1,nx,ny,nz);
09420 e->clip_inplace(r);
09421
09422 Dict conv_parms;
09423 conv_parms["with"] = e;
09424 image->process_inplace("math.convolution", conv_parms);
09425
09426 delete e;
09427 }
09428
09429
09430 #ifdef EMAN2_USING_CUDA
09431
09432
09433
09434
09435 #include "sparx/cuda/cuda_mpi_kmeans.h"
09436 MPICUDA_kmeans::MPICUDA_kmeans() {
09437 h_IM = NULL;
09438 h_AVE = NULL;
09439 h_ASG = NULL;
09440 h_dist = NULL;
09441 h_AVE2 = NULL;
09442 h_im2 = NULL;
09443 h_NC = NULL;
09444 params = NULL;
09445 d_im = NULL;
09446 d_AVE = NULL;
09447 d_dist = NULL;
09448 }
09449
09450 MPICUDA_kmeans::~MPICUDA_kmeans() {
09451 if (h_IM) delete h_IM;
09452 if (h_ASG) delete h_ASG;
09453 if (h_AVE) delete h_AVE;
09454 if (h_dist) delete h_dist;
09455 if (h_AVE2) delete h_AVE2;
09456 if (h_im2) delete h_im2;
09457 if (h_NC) delete h_NC;
09458 if (params) delete params;
09459 }
09460
09461 #include "sparx/cuda/cuda_mpi_kmeans.h"
09462 int MPICUDA_kmeans::setup(int extm, int extN, int extn, int extK, int extn_start) {
09463 m = extm;
09464 N = extN;
09465 n = extn;
09466 K = extK;
09467 n_start = extn_start;
09468 size_IM = m * N;
09469 size_im = m * n;
09470 size_AVE = m * K;
09471 size_dist = n * K;
09472 ite = 0;
09473 BLOCK_SIZE = 512;
09474 NB = size_dist / BLOCK_SIZE;
09475 ins_BLOCK = NB * BLOCK_SIZE;
09476
09477 h_IM = (float*)malloc(size_IM * sizeof(float));
09478 if (h_IM == 0) return 1;
09479 h_im = &h_IM[n_start * m];
09480
09481 h_AVE = (float*)malloc(size_AVE * sizeof(float));
09482 if (h_AVE == 0) return 1;
09483
09484 h_ASG = (unsigned short int*)malloc(N * sizeof(unsigned short int));
09485 if (h_ASG == 0) return 1;
09486 h_asg = &h_ASG[n_start];
09487
09488 h_AVE2 = (float*)malloc(K * sizeof(float));
09489 if (h_AVE2 == 0) return 1;
09490
09491 h_im2 = (float*)malloc(n * sizeof(float));
09492 if (h_im2 == 0) return 1;
09493
09494 h_dist = (float*)malloc(size_dist * sizeof(float));
09495 if (h_dist == 0) return 1;
09496
09497 h_NC = (unsigned int*)malloc(K * sizeof(unsigned int));
09498 if (h_NC == 0) return 1;
09499
09500 params = (int*)malloc(8 * sizeof(int));
09501 if (params == 0) return 1;
09502 params[0] = n;
09503 params[1] = m;
09504 params[2] = K;
09505 params[3] = 0;
09506 params[4] = 0;
09507 params[5] = BLOCK_SIZE;
09508 params[6] = NB;
09509 params[7] = ins_BLOCK;
09510
09511 return 0;
09512 }
09513
09514
09515 void MPICUDA_kmeans::append_flat_image(EMData* im, int pos) {
09516 for (int i = 0; i < m ; ++i) h_IM[pos * m + i] = (*im)(i);
09517 }
09518
09519
09520 int MPICUDA_kmeans::init_mem(int numdev) {
09521 int stat = 1;
09522 float** hd_AVE = NULL;
09523 float** hd_im = NULL;
09524 float** hd_dist = NULL;
09525 hd_AVE = &d_AVE;
09526 hd_im = &d_im;
09527 hd_dist = &d_dist;
09528 stat = cuda_mpi_init(h_im, hd_im, hd_AVE, hd_dist, size_im, size_AVE, size_dist, numdev);
09529
09530
09531
09532 return stat;
09533 }
09534
09535
09536 void MPICUDA_kmeans::compute_im2() {
09537 for (int i = 0; i < n; i++) {
09538 h_im2[i] = 0.0f;
09539 for (int j = 0; j < m; j++) h_im2[i] += (h_im[i * m + j] * h_im[i * m + j]);
09540 }
09541 }
09542
09543
09544 int MPICUDA_kmeans::random_ASG(long int rnd) {
09545 srand(rnd);
09546 int ret = 20;
09547 int flag = 0;
09548 int i, k;
09549 for (k = 0; k < K; k++) h_NC[k] = 0;
09550 while (ret > 0) {
09551 ret--;
09552 for (i = 0; i < N; i++) {
09553 h_ASG[i] = rand() % K;
09554 h_NC[h_ASG[i]]++;
09555 }
09556 flag = 1;
09557 k = K;
09558 while (k > 0 && flag) {
09559 k--;
09560 if (h_NC[k] <= 1) {
09561 flag = 0;
09562 if (ret == 0) {
09563
09564 return -1;
09565 }
09566 for (k = 0; k < K; k++) h_NC[k] = 0;
09567 }
09568 if (flag == 1) ret = 0;
09569 }
09570 }
09571 return 0;
09572 }
09573
09574
09575 vector <int> MPICUDA_kmeans::get_ASG() {
09576 vector <int> ASG(h_ASG, &h_ASG[N]);
09577 return ASG;
09578 }
09579
09580
09581 vector <int> MPICUDA_kmeans::get_asg() {
09582 vector <int> asg(h_asg, &h_asg[n]);
09583 return asg;
09584 }
09585
09586
09587 void MPICUDA_kmeans::compute_NC() {
09588 for (int i = 0; i < K; ++i) h_NC[i] = 0;
09589 for (int i = 0; i < N; ++i) h_NC[h_ASG[i]]++;
09590 }
09591
09592
09593 vector <int> MPICUDA_kmeans::get_NC() {
09594 vector <int> NC(h_NC, &h_NC[K]);
09595 return NC;
09596 }
09597
09598
09599 void MPICUDA_kmeans::set_ASG(const vector <int>& ASG) {
09600 for (int i = 0; i < N ; ++i) h_ASG[i] = ASG[i];
09601 }
09602
09603
09604 void MPICUDA_kmeans::set_NC(const vector <int>& NC) {
09605 for (int i = 0; i < K; ++i) h_NC[i] = NC[i];
09606 }
09607
09608
09609 int MPICUDA_kmeans::get_ct_im_mv() {
09610 return params[4];
09611 }
09612
09613
09614 void MPICUDA_kmeans::set_T(float extT) {
09615 T = extT;
09616 }
09617
09618
09619 float MPICUDA_kmeans::get_T() {
09620 return T;
09621 }
09622
09623
09624 void MPICUDA_kmeans::compute_AVE() {
09625 float buf = 0.0f;
09626 int i, j, c, d, ind;
09627
09628 for (i = 0; i < size_AVE; ++i) h_AVE[i] = 0.0f;
09629 for (i = 0; i < N; ++i) {
09630 c = h_ASG[i] * m;
09631 d = i * m;
09632 for (j = 0; j < m; ++j) h_AVE[c + j] += h_IM[d + j];
09633 }
09634 for (i = 0; i < K; i++) {
09635 buf = 0.0f;
09636 for (j = 0 ; j < m; j++) {
09637 ind = i * m + j;
09638 h_AVE[ind] /= (float)h_NC[i];
09639 buf += (h_AVE[ind] * h_AVE[ind]);
09640 }
09641 h_AVE2[i] = buf;
09642 }
09643 }
09644
09645
09646 void MPICUDA_kmeans::set_AVE(EMData* im, int pos) {
09647 for (int i = 0; i < m ; ++i) h_AVE[pos * m + i] = (*im)(i);
09648 }
09649
09650
09651 vector<EMData*> MPICUDA_kmeans::get_AVE() {
09652 vector<EMData*> ave(K);
09653 for (int k = 0; k < K; ++k) {
09654 EMData* im = new EMData();
09655 im->set_size(m, 1, 1);
09656 float *ptr = im->get_data();
09657 for (int i = 0; i < m; ++i) {ptr[i] = h_AVE[k * m + i];}
09658 ave[k] = im->copy();
09659 delete im;
09660 }
09661 return ave;
09662 }
09663
09664
09665 int MPICUDA_kmeans::one_iter() {
09666 int status = cuda_mpi_kmeans(h_AVE, d_AVE, h_dist, d_dist, d_im, h_im2, h_AVE2, h_asg, h_NC, params);
09667 ite++;
09668 return status;
09669 }
09670
09671
09672 int MPICUDA_kmeans::one_iter_SA() {
09673 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);
09674 ite++;
09675 return status;
09676 }
09677
09678
09679 vector <float> MPICUDA_kmeans::compute_ji() {
09680 int status = cuda_mpi_dist(h_AVE, d_AVE, h_dist, d_dist, d_im, n, K, m);
09681 vector <float> ji(K);
09682 int i;
09683 if (status != 0) {
09684 for (i = 0; i < K; ++i) ji[i] = -1.0;
09685 return ji;
09686 }
09687 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]]);
09688 return ji;
09689 }
09690
09691
09692 vector <float> MPICUDA_kmeans::compute_criterion(const vector <float>& Ji) {
09693 float buf = 0.0f;
09694 float Je = 0.0f;
09695 float Tr_AVE = 0.0f;
09696 float v_max = 0.0f;
09697 float* S_AVE2 = (float*)calloc(m, sizeof(float));
09698 float* S_AVE = (float*)calloc(m, sizeof(float));
09699 vector <float> crit(4);
09700 int i, j, k;
09701
09702 for (i = 0; i < K; ++i) Je += (Ji[i] / float(m));
09703 crit[0] = Je;
09704
09705 for (i = 0; i < K; ++i) {
09706 for (j = 0; j < m; ++j) {
09707 S_AVE[j] += h_AVE[i * m + j];
09708 S_AVE2[j] += (h_AVE[i * m + j] * h_AVE[i * m +j]);
09709 }
09710 }
09711 buf = 1 / (float)K;
09712 for (i = 0; i < m; ++i) Tr_AVE += (buf * (S_AVE2[i] - buf * S_AVE[i] * S_AVE[i]));
09713
09714 crit[1] = Tr_AVE * Je;
09715
09716 crit[2] = (Tr_AVE * (float)(N - K)) / (Je * (float)(K - 1));
09717
09718 for (i = 0; i < K; ++i) {
09719 v_max = 0.0f;
09720 for (j = 0; j < K; ++j) {
09721 if (j != i) {
09722 buf = 0.0f;
09723 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]));
09724 buf = (Ji[i] / (float)h_NC[i] + Ji[j] / (float)h_NC[j]) * ((float)m / buf);
09725 }
09726 if (buf > v_max) v_max = buf;
09727 }
09728 crit[3] += v_max;
09729 }
09730 crit[3] /= (float)K;
09731 free(S_AVE);
09732 free(S_AVE2);
09733 return crit;
09734 }
09735
09736
09737 int MPICUDA_kmeans::shutdown() {
09738 return cuda_mpi_shutdown(d_im, d_AVE, d_dist);
09739 }
09741
09742 void CudaMultProcessor::process_inplace(EMData* image) {
09743 float val = params.set_default("scale",(float) 1.0);
09744 EMDataForCuda tmp = image->get_data_struct_for_cuda();
09745 emdata_processor_mult(&tmp,val);
09746 image->gpu_update();
09747 }
09748
09749
09750 void CudaCorrelationProcessor::process_inplace(EMData* image) {
09751 EMData* with = params.set_default("with",(EMData*)0);
09752 if (with == 0) throw InvalidParameterException("You must supply the with parameter, and it must be valid. It is NULL.");
09753
09754 EMDataForCuda left = image->get_data_struct_for_cuda();
09755 with->bind_cuda_texture(false);
09756 emdata_processor_correlation_texture(&left,1);
09757 image->gpu_update();
09758
09759 }
09760
09761 #endif //EMAN2_USING_CUDA
09762
09763 void EMAN::dump_processors()
09764 {
09765 dump_factory < Processor > ();
09766 }
09767
09768 map<string, vector<string> > EMAN::dump_processors_list()
09769 {
09770 return dump_factory_list < Processor > ();
09771 }
09772
09773 map<string, vector<string> > EMAN::group_processors()
09774 {
09775 map<string, vector<string> > processor_groups;
09776
09777 vector <string> processornames = Factory<Processor>::get_list();
09778
09779 for (size_t i = 0; i < processornames.size(); i++) {
09780 Processor * f = Factory<Processor>::get(processornames[i]);
09781 if (dynamic_cast<RealPixelProcessor*>(f) != 0) {
09782 processor_groups["RealPixelProcessor"].push_back(f->get_name());
09783 }
09784 else if (dynamic_cast<BoxStatProcessor*>(f) != 0) {
09785 processor_groups["BoxStatProcessor"].push_back(f->get_name());
09786 }
09787 else if (dynamic_cast<ComplexPixelProcessor*>(f) != 0) {
09788 processor_groups["ComplexPixelProcessor"].push_back(f->get_name());
09789 }
09790 else if (dynamic_cast<CoordinateProcessor*>(f) != 0) {
09791 processor_groups["CoordinateProcessor"].push_back(f->get_name());
09792 }
09793 else if (dynamic_cast<FourierProcessor*>(f) != 0) {
09794 processor_groups["FourierProcessor"].push_back(f->get_name());
09795 }
09796 else if (dynamic_cast<NewFourierProcessor*>(f) != 0) {
09797 processor_groups["FourierProcessor"].push_back(f->get_name());
09798 }
09799 else if (dynamic_cast<NormalizeProcessor*>(f) != 0) {
09800 processor_groups["NormalizeProcessor"].push_back(f->get_name());
09801 }
09802 else {
09803 processor_groups["Others"].push_back(f->get_name());
09804 }
09805 }
09806
09807 return processor_groups;
09808 }
09809
09810
09811
09812
09813
09814 float ModelHelixProcessor::radprofile(float r, int type)
09815
09816 {
09817
09818 double ret = 0;
09819 if (type == 0) {
09820 r /= 2;
09821 ret = exp(-r * r);
09822 } else if (type == 1) {
09823 r /= 2;
09824 ret = (1 - r * r / 4) * exp(-r * r / 4);
09825 } else if (type == 2) {
09826
09827
09828
09829
09830
09831 if (r >= 12.2)
09832 return 0;
09833 static float an[15] = { -3.9185246832229140e-16f,
09834 3.3957205298900993e-14f, 2.0343351971222658e-12f,
09835 -4.4935965816879751e-10f, 3.0668169835080933e-08f,
09836 -1.1904544689091790e-06f, 2.9753088549414953e-05f,
09837 -4.9802112876220150e-04f, 5.5900917825309360e-03f,
09838 -4.0823714462925299e-02f, 1.8021733669148599e-01f,
09839 -4.0992557296268717e-01f, 3.3980328566901458e-01f,
09840 -3.6062024812411908e-01f, 1.0000000000000000e+00f };
09841
09842 ret = an[0];
09843 for (int i = 1; i < 15; i++) {
09844 ret = ret * r + an[i];
09845 }
09846 }
09847 return (float)ret;
09848 }
09849
09850 void ModelEMCylinderProcessor::process_inplace(EMData * in)
09851
09852 {
09853
09854
09855 EMData * cyl = in;
09856 int nx = cyl->get_xsize();
09857 int ny = cyl->get_ysize();
09858 int nz = cyl->get_zsize();
09859
09860 int type = params.set_default("type", 2);
09861 float len = params.set_default("length", 16.2);
09862 int x0 = params.set_default("x0", -1);
09863 int y0 = params.set_default("y0", -1);
09864 int z0 = params.set_default("z0", -1);
09865
09866
09867 if (x0 < 0 || x0 >= nx)
09868 x0 = nx / 2;
09869 if (y0 < 0 || y0 >= ny)
09870 y0 = ny / 2;
09871 if (z0 < 0 || z0 >= nz)
09872 z0 = nz / 2;
09873
09874 float apix_x = cyl->get_attr("apix_x");
09875 float apix_y = cyl->get_attr("apix_y");
09876 float apix_z = cyl->get_attr("apix_z");
09877
09878 float * dat = cyl->get_data();
09879 int cyl_voxel_len = (int) (len / apix_z);
09880 int cyl_k_min = z0 - cyl_voxel_len / 2;
09881 int cyl_k_max = z0 + cyl_voxel_len / 2;
09882
09883 int x, y;
09884 for (int k = 0; k < nz; k++) {
09885 for (int j = 0; j < ny; j++) {
09886 for (int i = 0; i < nx; i++, dat++) {
09887 x = i - x0;
09888 y = j - y0;
09889 float radius = (float)hypot(x * apix_x, y * apix_y);
09890 if ((k > cyl_k_min) && (k < cyl_k_max))
09891 *dat += radprofile(radius, type);
09892
09893
09894
09895 }
09896 }
09897 }
09898 }
09899
09900 void ApplyPolynomialProfileToHelix::process_inplace(EMData * in)
09901 {
09902 EMData * cyl = in;
09903 int nx = cyl->get_xsize();
09904 int ny = cyl->get_ysize();
09905 int nz = cyl->get_zsize();
09906 float apix_x = cyl->get_attr("apix_x");
09907 float apix_y = cyl->get_attr("apix_y");
09908 float apix_z = cyl->get_attr("apix_z");
09909 float lengthAngstroms = params["length"];
09910 int z0 = params.set_default("z0", -1);
09911
09912 if (z0 < 0 || z0 >= nz)
09913 z0 = nz / 2;
09914
09915 int z_start = Util::round( z0 - 0.5*lengthAngstroms/apix_z );
09916 int z_stop = Util::round( z0 + 0.5*lengthAngstroms/apix_z );
09917
09918 float * dat = cyl->get_data();
09919 double rho_x_sum, rho_y_sum, rho_sum, x_cm, y_cm, radius;
09920
09921 for (int k = 0; k < nz; k++)
09922 {
09923 rho_x_sum = rho_y_sum = rho_sum = 0;
09924
09925 if (k >= z_start && k <= z_stop)
09926
09927 {
09928
09929 for (int j = 0; j < ny; j++)
09930 {
09931 for (int i = 0; i < nx; i++, dat++)
09932 {
09933 rho_x_sum += (*dat)*i;
09934 rho_y_sum += (*dat)*j;
09935 rho_sum += *dat;
09936 }
09937 }
09938 if (rho_sum != 0)
09939 {
09940 dat -= nx*ny;
09941 x_cm = rho_x_sum/rho_sum;
09942 y_cm = rho_y_sum/rho_sum;
09943
09944
09945 for (int j=0; j<ny;j++)
09946 {
09947 for (int i=0;i<nx;i++,dat++)
09948 {
09949 radius = hypot( (i-x_cm)*apix_x, (j-y_cm)*apix_y );
09950 *dat = radprofile((float)radius, 2);
09951 }
09952 }
09953 }
09954 }
09955 else
09956
09957 {
09958 for (int j=0; j<ny; j++)
09959 for(int i=0; i<nx; i++)
09960 {
09961 *dat = 0;
09962 dat++;
09963 }
09964 }
09965
09966 }
09967 }
09968
09969 EMData* BinarySkeletonizerProcessor::process(EMData * image)
09970 {
09971 using namespace wustl_mm::GraySkeletonCPP;
09972 using namespace wustl_mm::SkeletonMaker;
09973
09974 Volume * vimage = new Volume(image);
09975 float threshold = params["threshold"];
09976 int min_curvew = params.set_default("min_curve_width", 4);
09977 int min_srfcw = params.set_default("min_surface_width", 4);
09978 bool mark_surfaces = params.set_default("mark_surfaces", true);
09979 Volume* vskel = VolumeSkeletonizer::PerformPureJuSkeletonization(vimage, "unused", static_cast<double>(threshold), min_curvew, min_srfcw);
09980
09981 if (mark_surfaces) {
09982 VolumeSkeletonizer::MarkSurfaces(vskel);
09983 }
09984
09985 vskel->getVolumeData()->owns_emdata = false;
09986 EMData* skel = vskel->get_emdata();
09987 skel->update();
09988 return skel;
09989 }
09990
09991 void BinarySkeletonizerProcessor::process_inplace(EMData * image)
09992 {
09993 EMData* em_skel = this->process(image);
09994
09995 *image = *em_skel;
09996 image->update();
09997 delete em_skel;
09998 em_skel = NULL;
09999 return;
10000 }