Public Member Functions | Static Public Member Functions | Static Public Attributes
EMAN::AutoMask3D2Processor Class Reference

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

#include <processor.h>

Inheritance diagram for EMAN::AutoMask3D2Processor:
Inheritance graph
Collaboration diagram for EMAN::AutoMask3D2Processor:
Collaboration graph

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.

radiusPixel radius of a ball which is used to seed the flood filling operation
thresholdAn isosurface threshold that suitably encases the mass
nshellsThe number of dilation operations
nshellsgaussnumber 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 5351 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.

The description of this processor.

Implements EMAN::Processor.

Definition at line 5366 of file processor.h.

                        return "This will mask a 3-D volume using a 'flood filling' approach. It begins with a seed generated either as a sphere with \
specified 'radius' or with the 'nmaxseed' highest values. It then includes any mass connected to the seed with value higher than 'threshold'.\
Next, the mask is expanded by 'nshells'+'nshellsgauss'/2 voxels. Finally a gaussian low-pass filter is applied with a width of 'nshellsgauss'.";
virtual string EMAN::AutoMask3D2Processor::get_name ( ) const [inline, virtual]

Get the processor's name.

Each processor is identified by a unique name.

The processor's name.

Implements EMAN::Processor.

Definition at line 5356 of file processor.h.

References NAME.

                        return NAME;
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.

A dictionary containing the parameter info.

Reimplemented from EMAN::Processor.

Definition at line 5373 of file processor.h.

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

                        TypeDict d;
                        d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
                        d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
                        d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
                        d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
                        d.put("nshells", EMObject::INT, "Number of 1-voxel shells to expand the mask by.");
                        d.put("nshellsgauss", EMObject::INT, "Width in voxels of a Gaussian decay at the edge of the mask.");
                        d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
                        d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
                        return d;
static Processor* EMAN::AutoMask3D2Processor::NEW ( ) [inline, static]

Definition at line 5361 of file processor.h.

                        return new AutoMask3D2Processor();
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.

imageThe image to be processed.

Implements EMAN::Processor.

Definition at line 7110 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(), ny, EMAN::Processor::params, EMAN::EMData::process_inplace(), EMAN::Dict::set_default(), EMAN::EMData::set_size(), EMAN::EMData::set_value_at(), and EMAN::EMData::update().

        if (!image) {
                LOGWARN("NULL Image");

        if (image->get_ndim() != 3) {
                throw ImageDimensionException("This processor was only ever designed to work on 3D images.");

         The mask writing functionality was removed to comply with an EMAN2 policy which dictates that file io is not allowed from within a processor
         To get around this just use the return_mask parameter.
        string mask_output = params.set_default("write_mask", "");
        if ( mask_output != "") {
                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.");
                if (!EMUtil::is_valid_filename(mask_output)) throw InvalidParameterException("The mask output file name type is invalid or unrecognized");

        int radius=0;
        if (params.has_key("radius")) {
                radius = params["radius"];
        int nmaxseed=0;
        if (params.has_key("nmaxseed")) {
                nmaxseed = params["nmaxseed"];

        float threshold=0.0;
        if (params.has_key("sigma")) threshold=(float)(image->get_attr("mean"))+(float)(image->get_attr("sigma"))*(float)params["sigma"];
        else threshold=params["threshold"];

        int nshells = params["nshells"];
        int nshellsgauss = params["nshellsgauss"];
        int verbose=params.set_default("verbose",0);

        int nx = image->get_xsize();
        int ny = image->get_ysize();
        int nz = image->get_zsize();
        int nxy=nx*ny;

        EMData *amask = new EMData();
        amask->set_size(nx, ny, nz);

        float *dat = image->get_data();
        float *dat2 = amask->get_data();
        int i,j,k;
        size_t l = 0;

        // Seeds with the highest valued pixels
        if (nmaxseed>0) {
                vector<Pixel> maxs=image->calc_n_highest_locations(nmaxseed);

                for (vector<Pixel>::iterator i=maxs.begin(); i<maxs.end(); i++) {
                        if (verbose) printf("Seed at %d,%d,%d (%1.3f)\n",(*i).x,(*i).y,(*i).z,(*i).value);

        // Seeds with a sphere
        if (radius>0) {
                // start with an initial sphere
                for (k = -nz / 2; k < nz / 2; ++k) {
                        for (j = -ny / 2; j < ny / 2; ++j) {
                                for (i = -nx / 2; i < nx / 2; ++i,++l) {
                                        if (abs(k) > radius || abs(j) > radius || abs(i) > radius) continue;
                                        if ( (k * k + j * j + i * i) > (radius*radius) || dat[l] < threshold) continue;
                                        dat2[l] = 1.0f;

        // iteratively 'flood fills' the map... recursion would be better
        int done=0;
        int iter=0;
        while (!done) {
                if (verbose && iter%10==0) printf("%d iterations\n",iter);
                for (k=1; k<nz-1; ++k) {
                        for (j=1; j<ny-1; ++j) {
                                for (i=1; i<nx-1; ++i) {
                                        if (dat2[l]) continue;
                                        if (dat[l]>threshold && (dat2[l-1]||dat2[l+1]||dat2[l+nx]||dat2[l-nx]||dat2[l-nxy]||dat2[l+nxy])) {


        if (verbose) printf("expanding mask\n");
        amask->process_inplace("mask.addshells.gauss", Dict("val1", (int)(nshells+nshellsgauss/2),"val2",0));
        if (verbose) printf("filtering mask\n");
        amask->process_inplace("filter.lowpass.gauss", Dict("cutoff_abs", (float)(1.0f/(float)nshellsgauss)));
        amask->process_inplace("threshold.belowtozero", Dict("minval",(float)0.002));   // this makes the value exactly 0 beyond ~2.5 sigma

        bool return_mask = params.set_default("return_mask",false);
        if (return_mask) {
                // 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.
                dat = image->get_data();
                dat2 = amask->get_data();
        } else {

        // EMAN2 policy is not to allow file io from with a processor
        //if (mask_output != "") {
        //      amask->write_image(mask_output);

        delete amask;

Member Data Documentation

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

Definition at line 5387 of file processor.h.

Referenced by get_name().

The documentation for this class was generated from the following files: