EMAN::AutoMask3D2Processor Class Reference

Tries to mask out only interesting density. More...

#include <processor.h>

Inheritance diagram for EMAN::AutoMask3D2Processor:

Inheritance graph
[legend]
Collaboration diagram for EMAN::AutoMask3D2Processor:

Collaboration graph
[legend]
List of all members.

Public Member Functions

virtual void process_inplace (EMData *image)
 To process an image in-place.
virtual string get_name () const
 Get the processor's name.
virtual string get_desc () const
 Get the descrition of this specific processor.
virtual TypeDict get_param_types () const
 Get processor parameter information in a dictionary.

Static Public Member Functions

static ProcessorNEW ()

Static Public Attributes

static const string NAME = "mask.auto3d"

Detailed Description

Tries to mask out only interesting density.

Parameters:
radius Pixel radius of a ball which is used to seed the flood filling operation
threshold An isosurface threshold that suitably encases the mass
nshells The number of dilation operations
nshellsgauss number of Gaussian pixels to expand, following the dilation operations If true the result of the operation will produce the mask, not the masked volume

Definition at line 5056 of file processor.h.


Member Function Documentation

virtual string EMAN::AutoMask3D2Processor::get_desc (  )  const [inline, virtual]

Get the descrition of this specific processor.

This function must be overwritten by a subclass.

Returns:
The description of this processor.

Implements EMAN::Processor.

Definition at line 5071 of file processor.h.

05072                 {
05073                         return "This will mask a 3-D volume using a 'flood filling' approach. It begins with a seed generated either as a sphere with \
05074 specified 'radius' or with the 'nmaxseed' highest values. It then includes any mass connected to the seed with value higher than 'threshold'.\
05075 Next, the mask is expanded by 'nshells'+'nshellsgauss'/2 voxels. Finally a gaussian low-pass filter is applied with a width of 'nshellsgauss'.";
05076                 }

virtual string EMAN::AutoMask3D2Processor::get_name (  )  const [inline, virtual]

Get the processor's name.

Each processor is identified by a unique name.

Returns:
The processor's name.

Implements EMAN::Processor.

Definition at line 5061 of file processor.h.

References NAME.

05062                 {
05063                         return NAME;
05064                 }

virtual TypeDict EMAN::AutoMask3D2Processor::get_param_types (  )  const [inline, virtual]

Get processor parameter information in a dictionary.

Each parameter has one record in the dictionary. Each record contains its name, data-type, and description.

Returns:
A dictionary containing the parameter info.

Reimplemented from EMAN::Processor.

Definition at line 5078 of file processor.h.

References EMAN::EMObject::BOOL, EMAN::EMObject::FLOAT, EMAN::EMObject::INT, and EMAN::TypeDict::put().

05079                 {
05080                         TypeDict d;
05081                         d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
05082                         d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
05083                         d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
05084                         d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
05085                         d.put("nshells", EMObject::INT, "Number of 1-voxel shells to expand the mask by.");
05086                         d.put("nshellsgauss", EMObject::INT, "Width in voxels of a Gaussian decay at the edge of the mask.");
05087                         d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
05088                         d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
05089                         return d;
05090                 }

static Processor* EMAN::AutoMask3D2Processor::NEW (  )  [inline, static]

Definition at line 5066 of file processor.h.

05067                 {
05068                         return new AutoMask3D2Processor();
05069                 }

void AutoMask3D2Processor::process_inplace ( EMData image  )  [virtual]

To process an image in-place.

For those processors which can only be processed out-of-place, override this function to just print out some error message to remind user call the out-of-place version.

Parameters:
image The image to be processed.

Implements EMAN::Processor.

Definition at line 6607 of file processor.cpp.

References abs, EMAN::EMData::calc_n_highest_locations(), EMAN::EMData::get_attr(), EMAN::EMData::get_data(), EMAN::EMData::get_ndim(), EMAN::EMData::get_size(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::Dict::has_key(), ImageDimensionException, LOGWARN, EMAN::EMData::mult(), EMAN::Processor::params, EMAN::EMData::process_inplace(), EMAN::Dict::set_default(), EMAN::EMData::set_size(), EMAN::EMData::set_value_at(), and EMAN::EMData::update().

06608 {
06609         if (!image) {
06610                 LOGWARN("NULL Image");
06611                 return;
06612         }
06613 
06614         if (image->get_ndim() != 3) {
06615                 throw ImageDimensionException("This processor was only ever designed to work on 3D images.");
06616         }
06617 
06618         /*
06619          The mask writing functionality was removed to comply with an EMAN2 policy which dictates that file io is not allowed from within a processor
06620          To get around this just use the return_mask parameter.
06621         string mask_output = params.set_default("write_mask", "");
06622         if ( mask_output != "") {
06623                 if (Util::is_file_exist(mask_output) ) throw InvalidParameterException("The mask output file name already exists. Please remove it if you don't need it.");
06624                 if (!EMUtil::is_valid_filename(mask_output)) throw InvalidParameterException("The mask output file name type is invalid or unrecognized");
06625         }
06626         */
06627 
06628         int radius=0;
06629         if (params.has_key("radius")) {
06630                 radius = params["radius"];
06631         }
06632         int nmaxseed=0;
06633         if (params.has_key("nmaxseed")) {
06634                 nmaxseed = params["nmaxseed"];
06635         }
06636 
06637         float threshold=0.0;
06638         if (params.has_key("sigma")) threshold=(float)(image->get_attr("mean"))+(float)(image->get_attr("sigma"))*(float)params["sigma"];
06639         else threshold=params["threshold"];
06640 
06641         int nshells = params["nshells"];
06642         int nshellsgauss = params["nshellsgauss"];
06643         int verbose=params.set_default("verbose",0);
06644 
06645         int nx = image->get_xsize();
06646         int ny = image->get_ysize();
06647         int nz = image->get_zsize();
06648         int nxy=nx*ny;
06649 
06650         EMData *amask = new EMData();
06651         amask->set_size(nx, ny, nz);
06652 
06653         float *dat = image->get_data();
06654         float *dat2 = amask->get_data();
06655         int i,j,k;
06656         size_t l = 0;
06657 
06658         // Seeds with the highest valued pixels
06659         if (nmaxseed>0) {
06660                 vector<Pixel> maxs=image->calc_n_highest_locations(nmaxseed);
06661 
06662                 for (vector<Pixel>::iterator i=maxs.begin(); i<maxs.end(); i++) {
06663                         amask->set_value_at((*i).x,(*i).y,(*i).z,1.0);
06664                         if (verbose) printf("Seed at %d,%d,%d (%1.3f)\n",(*i).x,(*i).y,(*i).z,(*i).value);
06665                 }
06666         }
06667 
06668         // Seeds with a sphere
06669         if (radius>0) {
06670                 // start with an initial sphere
06671                 for (k = -nz / 2; k < nz / 2; ++k) {
06672                         for (j = -ny / 2; j < ny / 2; ++j) {
06673                                 for (i = -nx / 2; i < nx / 2; ++i,++l) {
06674                                         if (abs(k) > radius || abs(j) > radius || abs(i) > radius) continue;
06675                                         if ( (k * k + j * j + i * i) > (radius*radius) || dat[l] < threshold) continue;
06676                                         dat2[l] = 1.0f;
06677                                 }
06678                         }
06679                 }
06680         }
06681 
06682 
06683         // iteratively 'flood fills' the map... recursion would be better
06684         int done=0;
06685         int iter=0;
06686         while (!done) {
06687                 iter++;
06688                 done=1;
06689                 if (verbose && iter%10==0) printf("%d iterations\n",iter);
06690                 for (k=1; k<nz-1; ++k) {
06691                         for (j=1; j<ny-1; ++j) {
06692                                 for (i=1; i<nx-1; ++i) {
06693                                         l=i+j*nx+k*nx*ny;
06694                                         if (dat2[l]) continue;
06695                                         if (dat[l]>threshold && (dat2[l-1]||dat2[l+1]||dat2[l+nx]||dat2[l-nx]||dat2[l-nxy]||dat2[l+nxy])) {
06696                                                 dat2[l]=1.0;
06697                                                 done=0;
06698                                         }
06699                                 }
06700                         }
06701                 }
06702         }
06703 
06704         amask->update();
06705 
06706         if (verbose) printf("expanding mask\n");
06707         amask->process_inplace("mask.addshells.gauss", Dict("val1", (int)(nshells+nshellsgauss/2),"val2",0));
06708         if (verbose) printf("filtering mask\n");
06709         amask->process_inplace("filter.lowpass.gauss", Dict("cutoff_abs", (float)(1.0f/(float)nshellsgauss)));
06710         amask->process_inplace("threshold.belowtozero", Dict("minval",(float)0.002));   // this makes the value exactly 0 beyond ~2.5 sigma
06711 
06712         bool return_mask = params.set_default("return_mask",false);
06713         if (return_mask) {
06714                 // Yes there is probably a much more efficient way of getting the mask itself, but I am only providing a stop gap at the moment.
06715                 dat = image->get_data();
06716                 dat2 = amask->get_data();
06717                 memcpy(dat,dat2,image->get_size()*sizeof(float));
06718         } else {
06719                 image->mult(*amask);
06720         }
06721 
06722         // EMAN2 policy is not to allow file io from with a processor
06723         //if (mask_output != "") {
06724         //      amask->write_image(mask_output);
06725         //}
06726 
06727 
06728         delete amask;
06729 }


Member Data Documentation

const string AutoMask3D2Processor::NAME = "mask.auto3d" [static]

Definition at line 5092 of file processor.h.

Referenced by get_name().


The documentation for this class was generated from the following files:
Generated on Fri Aug 10 16:32:58 2012 for EMAN2 by  doxygen 1.4.7