Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

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

ProcessorNEW ()

Static Public Attributes

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 5058 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 5073 of file processor.h.

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

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 5063 of file processor.h.

05064                 {
05065                         return NAME;
05066                 }

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 5080 of file processor.h.

References EMAN::TypeDict::put().

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

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

Definition at line 5068 of file processor.h.

05069                 {
05070                         return new AutoMask3D2Processor();
05071                 }

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 6672 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(), nx, ny, EMAN::EMData::process_inplace(), EMAN::Dict::set_default(), EMAN::EMData::set_size(), EMAN::EMData::set_value_at(), and EMAN::EMData::update().

06673 {
06674         if (!image) {
06675                 LOGWARN("NULL Image");
06676                 return;
06677         }
06678 
06679         if (image->get_ndim() != 3) {
06680                 throw ImageDimensionException("This processor was only ever designed to work on 3D images.");
06681         }
06682 
06683         /*
06684          The mask writing functionality was removed to comply with an EMAN2 policy which dictates that file io is not allowed from within a processor
06685          To get around this just use the return_mask parameter.
06686         string mask_output = params.set_default("write_mask", "");
06687         if ( mask_output != "") {
06688                 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.");
06689                 if (!EMUtil::is_valid_filename(mask_output)) throw InvalidParameterException("The mask output file name type is invalid or unrecognized");
06690         }
06691         */
06692 
06693         int radius=0;
06694         if (params.has_key("radius")) {
06695                 radius = params["radius"];
06696         }
06697         int nmaxseed=0;
06698         if (params.has_key("nmaxseed")) {
06699                 nmaxseed = params["nmaxseed"];
06700         }
06701 
06702         float threshold=0.0;
06703         if (params.has_key("sigma")) threshold=(float)(image->get_attr("mean"))+(float)(image->get_attr("sigma"))*(float)params["sigma"];
06704         else threshold=params["threshold"];
06705 
06706         int nshells = params["nshells"];
06707         int nshellsgauss = params["nshellsgauss"];
06708         int verbose=params.set_default("verbose",0);
06709 
06710         int nx = image->get_xsize();
06711         int ny = image->get_ysize();
06712         int nz = image->get_zsize();
06713         int nxy=nx*ny;
06714 
06715         EMData *amask = new EMData();
06716         amask->set_size(nx, ny, nz);
06717 
06718         float *dat = image->get_data();
06719         float *dat2 = amask->get_data();
06720         int i,j,k;
06721         size_t l = 0;
06722 
06723         // Seeds with the highest valued pixels
06724         if (nmaxseed>0) {
06725                 vector<Pixel> maxs=image->calc_n_highest_locations(nmaxseed);
06726 
06727                 for (vector<Pixel>::iterator i=maxs.begin(); i<maxs.end(); i++) {
06728                         amask->set_value_at((*i).x,(*i).y,(*i).z,1.0);
06729                         if (verbose) printf("Seed at %d,%d,%d (%1.3f)\n",(*i).x,(*i).y,(*i).z,(*i).value);
06730                 }
06731         }
06732 
06733         // Seeds with a sphere
06734         if (radius>0) {
06735                 // start with an initial sphere
06736                 for (k = -nz / 2; k < nz / 2; ++k) {
06737                         for (j = -ny / 2; j < ny / 2; ++j) {
06738                                 for (i = -nx / 2; i < nx / 2; ++i,++l) {
06739                                         if (abs(k) > radius || abs(j) > radius || abs(i) > radius) continue;
06740                                         if ( (k * k + j * j + i * i) > (radius*radius) || dat[l] < threshold) continue;
06741                                         dat2[l] = 1.0f;
06742                                 }
06743                         }
06744                 }
06745         }
06746 
06747 
06748         // iteratively 'flood fills' the map... recursion would be better
06749         int done=0;
06750         int iter=0;
06751         while (!done) {
06752                 iter++;
06753                 done=1;
06754                 if (verbose && iter%10==0) printf("%d iterations\n",iter);
06755                 for (k=1; k<nz-1; ++k) {
06756                         for (j=1; j<ny-1; ++j) {
06757                                 for (i=1; i<nx-1; ++i) {
06758                                         l=i+j*nx+k*nx*ny;
06759                                         if (dat2[l]) continue;
06760                                         if (dat[l]>threshold && (dat2[l-1]||dat2[l+1]||dat2[l+nx]||dat2[l-nx]||dat2[l-nxy]||dat2[l+nxy])) {
06761                                                 dat2[l]=1.0;
06762                                                 done=0;
06763                                         }
06764                                 }
06765                         }
06766                 }
06767         }
06768 
06769         amask->update();
06770 
06771         if (verbose) printf("expanding mask\n");
06772         amask->process_inplace("mask.addshells.gauss", Dict("val1", (int)(nshells+nshellsgauss/2),"val2",0));
06773         if (verbose) printf("filtering mask\n");
06774         amask->process_inplace("filter.lowpass.gauss", Dict("cutoff_abs", (float)(1.0f/(float)nshellsgauss)));
06775         amask->process_inplace("threshold.belowtozero", Dict("minval",(float)0.002));   // this makes the value exactly 0 beyond ~2.5 sigma
06776 
06777         bool return_mask = params.set_default("return_mask",false);
06778         if (return_mask) {
06779                 // 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.
06780                 dat = image->get_data();
06781                 dat2 = amask->get_data();
06782                 memcpy(dat,dat2,image->get_size()*sizeof(float));
06783         } else {
06784                 image->mult(*amask);
06785         }
06786 
06787         // EMAN2 policy is not to allow file io from with a processor
06788         //if (mask_output != "") {
06789         //      amask->write_image(mask_output);
06790         //}
06791 
06792 
06793         delete amask;
06794 }


Member Data Documentation

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

Definition at line 169 of file processor.cpp.


The documentation for this class was generated from the following files:
Generated on Tue Jun 11 13:48:59 2013 for EMAN2 by  doxygen 1.3.9.1