EMAN2
Public Member Functions | Static Public Member Functions | Static Public Attributes | List of all members
EMAN::GaussSegmentProcessor Class Reference

Segment a volume by sequentially finding the highest peak and subtracting a Gaussian at that point from the density after strongly filtering the map to a specified resolvability. More...

#include <processor.h>

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

Public Member Functions

string get_name () const
 Get the processor's name. More...
 
virtual EMDataprocess (const EMData *const image)
 To proccess an image out-of-place. More...
 
void process_inplace (EMData *image)
 To process an image in-place. More...
 
TypeDict get_param_types () const
 Get processor parameter information in a dictionary. More...
 
string get_desc () const
 Get the descrition of this specific processor. More...
 
- Public Member Functions inherited from EMAN::Processor
virtual ~Processor ()
 
virtual void process_list_inplace (vector< EMData * > &images)
 To process multiple images using the same algorithm. More...
 
virtual Dict get_params () const
 Get the processor parameters in a key/value dictionary. More...
 
virtual void set_params (const Dict &new_params)
 Set the processor parameters using a key/value dictionary. More...
 

Static Public Member Functions

static ProcessorNEW ()
 
- Static Public Member Functions inherited from EMAN::Processor
static string get_group_desc ()
 Get the description of this group of processors. More...
 
static void EMFourierFilterInPlace (EMData *fimage, Dict params)
 Compute a Fourier-filter processed image in place. More...
 
static EMDataEMFourierFilter (EMData *fimage, Dict params)
 Compute a Fourier-processor processed image without altering the original image. More...
 

Static Public Attributes

static const string NAME = "segment.gauss"
 

Additional Inherited Members

- Public Types inherited from EMAN::Processor
enum  fourier_filter_types {
  TOP_HAT_LOW_PASS , TOP_HAT_HIGH_PASS , TOP_HAT_BAND_PASS , TOP_HOMOMORPHIC ,
  GAUSS_LOW_PASS , GAUSS_HIGH_PASS , GAUSS_BAND_PASS , GAUSS_INVERSE ,
  GAUSS_HOMOMORPHIC , BUTTERWORTH_LOW_PASS , BUTTERWORTH_HIGH_PASS , BUTTERWORTH_HOMOMORPHIC ,
  KAISER_I0 , KAISER_SINH , KAISER_I0_INVERSE , KAISER_SINH_INVERSE ,
  SHIFT , TANH_LOW_PASS , TANH_HIGH_PASS , TANH_HOMOMORPHIC ,
  TANH_BAND_PASS , RADIAL_TABLE , CTF_
}
 Fourier filter Processor type enum. More...
 
- Protected Attributes inherited from EMAN::Processor
Dict params
 

Detailed Description

Segment a volume by sequentially finding the highest peak and subtracting a Gaussian at that point from the density after strongly filtering the map to a specified resolvability.

Author
Steve Ludtke
Date
2021/04/18

Definition at line 1660 of file processor.h.

Member Function Documentation

◆ get_desc()

string EMAN::GaussSegmentProcessor::get_desc ( ) const
inlinevirtual

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

1689 {
1690 return "Segments a volume by sequentially finding and subtracting Gaussians at a specified resolvability.";
1691 }

◆ get_name()

string EMAN::GaussSegmentProcessor::get_name ( ) const
inlinevirtual

Get the processor's name.

Each processor is identified by a unique name.

Returns
The processor's name.

Implements EMAN::Processor.

Definition at line 1663 of file processor.h.

1664 {
1665 return NAME;
1666 }
static const string NAME
Definition: processor.h:1693

References NAME.

◆ get_param_types()

TypeDict EMAN::GaussSegmentProcessor::get_param_types ( ) const
inlinevirtual

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

1672 {
1673 TypeDict d ;
1674 d.put("minratio",EMObject::FLOAT,"The ratio of the smallest amplitude segment to locate relative to the strongest peak (default=0.5)");
1675 d.put("maxnseg",EMObject::INT,"Maximum number of segments to return (default = unlimited)");
1676 d.put("width",EMObject::FLOAT,"Required: full width of Gaussians in A at 1/e (FWHM). Also used to determine map prefiltration.");
1677 d.put("mask",EMObject::EMDATA,"Optional: mask to apply to map after filtration to limit where centers are placed");
1678 d.put("skipseg",EMObject::INT,"Normally the returned map is a segmentation map, but this is unnecessary if only the center coordinates are needed. If 1, the returned map will be a residual volume, not a segmentation map. If 2, it will be the filtered map before segmentation");
1679 d.put("verbose",EMObject::INT,"Be verbose while running");
1680 return d;
1681 }
TypeDict is a dictionary to store <string, EMObject::ObjectType> pair.
Definition: emobject.h:305
void put(const string &key, EMObject::ObjectType o, const string &desc="")
Definition: emobject.h:330

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

◆ NEW()

static Processor * EMAN::GaussSegmentProcessor::NEW ( )
inlinestatic

Definition at line 1683 of file processor.h.

1684 {
1685 return new GaussSegmentProcessor();
1686 }
Segment a volume by sequentially finding the highest peak and subtracting a Gaussian at that point fr...
Definition: processor.h:1661

◆ process()

EMData * GaussSegmentProcessor::process ( const EMData *const  image)
virtual

To proccess an image out-of-place.

For those processors which can only be processed out-of-place, override this function to give the right behavior.

Parameters
imageThe image will be copied, actual process happen on copy of image.
Returns
the image processing result, may or may not be the same size of the input image

Reimplemented from EMAN::Processor.

Definition at line 1448 of file processor.cpp.

1449{
1450
1451 float minratio = params.set_default("minratio",0.5f);
1452 int maxnseg = params.set_default("maxnseg",0);
1453 int skipseg = params.set_default("skipseg",0);
1454 float width = params.set_default("width",10.0f);
1455 int verbose = params.set_default("verbose",0);
1456 EMData *mask= (EMData *)params.set_default("mask",(EMData *)NULL);
1457 float apix=image->get_attr("apix_x");
1458 int nx=image->get_xsize();
1459 int ny=image->get_ysize();
1460 int nz=image->get_zsize();
1461
1462 EMData * result = image->process("threshold.belowtozero",Dict("minval",0.0f));
1463 // The intent of these filters is to insure that the map effectively
1464// result->process_inplace("filter.lowpass.gauss",Dict("cutoff_freq",0.45/width)); // 0.45 = sqrt(2)/pi, resolvability threshold
1465// result->process_inplace("filter.lowpass.gauss",Dict("cutoff_freq",0.637/width)); // 0.637 = 2/pi, (may be Rayleigh criterion?)
1466 if (mask!=NULL) {
1467 result->mult(*mask);
1468 result->process_inplace("normalize.local",Dict("radius",nx*apix/(3.0f*width),"threshold",(float)result->get_attr("sigma_nonzero")*1.2));
1469 }
1470
1471 XYData gsf;
1472 gsf.make_gauss(nx*4,1.0f/apix,0.45/width);
1473// gsf.make_gauss(nx*4,1.0f/apix,0.637/width);
1474 result->process_inplace("filter.setstrucfac",Dict("apix",apix,"strucfac",&gsf));
1475
1476 // Generate a Gaussian we can subtract out of the volume quickly
1477 int gs=2*width/(float)image->get_attr("apix_x");
1478 EMData gsub(gs,gs,gs);
1479 gsub.to_one();
1480 gsub.process_inplace("mask.gaussian",Dict("outer_radius",int(width/(2.0*apix))));
1481
1482 if (verbose>2) {
1483 result->set_attr("render_bits",12);
1484 result->set_attr("render_min",(float)result->get_attr("minimum"));
1485 result->set_attr("render_max",(float)result->get_attr("maximum"));
1486 result->write_image("segfilt.hdf",0,EMUtil::IMAGE_UNKNOWN,false,0,EMUtil::EM_COMPRESSED);
1487 }
1488
1489 EMData *cache = NULL;
1490 if (skipseg==2) cache=result->copy();
1491
1492 // original version of the code. A bit slow but works very well
1493// vector<float> centers;
1494// vector<float> amps;
1495// if (maxnseg==0) maxnseg=2000000000;
1496// float maxval=0.0f;
1497//
1498// while (amps.size()<maxnseg) {
1499// IntPoint p = result->calc_max_location();
1500// FloatPoint fp(p[0],p[1],p[2]);
1501//
1502// float amp=result->get_value_at(p[0],p[1],p[2]);
1503// if (amp<maxval*minratio) break;
1504// amps.push_back(amp);
1505// centers.push_back(p[0]);
1506// centers.push_back(p[1]);
1507// centers.push_back(p[2]);
1508// if (amp>maxval) maxval=amp; // really this should only happen once...
1509//
1510// result->insert_scaled_sum(&gsub,fp,1.0,-amp);
1511// }
1512
1513 // This was an alternate version, to improve speed. While it is faster, the approximations its making
1514 // produce slightly less optimal results.
1515 vector<float> centers;
1516 vector<float> amps;
1517 if (maxnseg==0) maxnseg=2000000000;
1518
1519 float thr=(float)result->get_attr("maximum")*minratio;
1520 while (amps.size()<maxnseg) {
1521 if ((float)result->get_attr("maximum")<=thr) break;
1522 // We find all peak values greater than our threshold
1523 vector<Pixel> pixels=result->calc_highest_locations(thr);
1524 if (pixels.size()==0) break;
1525 if (verbose>1) printf("%d %f %f %f %d\n",pixels.size(),pixels[0].get_value(),pixels[1].get_value(),pixels[2].get_value(),amps.size());
1526
1527 for (int i=0; i<pixels.size(); i++) {
1528 IntPoint p = pixels[i].get_point();
1529 FloatPoint fp(p[0],p[1],p[2]);
1530
1531 float amp=result->get_value_at(p[0],p[1],p[2]);
1532 if (amp!=pixels[i].get_value()) continue; // skip any values near a value we've just changed, should come back in the next round
1533 // printf("%d %d %d %f %f %f\n",p[0],p[1],p[2],amp,pixels[i].get_value(),pixels[i+1].get_value());
1534// if (i<pixels.size()-1 && amp<pixels[i+1].get_value()) continue; // if one of the identified peaks has been reduced by a nearby peak too much
1535 if (amp<thr) continue;
1536// if (amp<thr) { maxnseg=amps.size(); break; }
1537 amps.push_back(amp);
1538 centers.push_back(p[0]);
1539 centers.push_back(p[1]);
1540 centers.push_back(p[2]);
1541
1542 result->insert_scaled_sum(&gsub,fp,1.0,-amp);
1543 }
1544 }
1545
1546 if (verbose) printf("Found %d centers\n",amps.size());
1547
1548 if (verbose>2) {
1549 result->set_attr("render_bits",12);
1550 result->set_attr("render_min",(float)result->get_attr("minimum"));
1551 result->set_attr("render_max",(float)result->get_attr("maximum"));
1552 result->write_image("segfilt.hdf",1,EMUtil::IMAGE_UNKNOWN,false,0,EMUtil::EM_COMPRESSED);
1553 }
1554 if (!skipseg) {
1555 // after we have our list of centers classify pixels
1556 for (int z=0; z<nz; z++) {
1557 for (int y=0; y<ny; y++) {
1558 for (int x=0; x<nz; x++) {
1559// if (image->get_value_at(x,y,z)<thr) {
1560// result->set_value_at(x,y,z,-1.0); //below threshold -> -1 (unclassified)
1561// continue;
1562// }
1563 int bcls=-1; // best matching class
1564 float bdist=(float)(nx+ny+nz); // distance for best class
1565 for (unsigned int c=0; c<centers.size()/3; c++) {
1566 float d=Util::hypot3(x-centers[c*3],y-centers[c*3+1],z-centers[c*3+2]);
1567 if (d<bdist) { bdist=d; bcls=c; }
1568 }
1569 result->set_value_at(x,y,z,(float)bcls); // set the pixel to the class number
1570 }
1571 }
1572 }
1573 if (verbose) printf("segmented\n");
1574 }
1575
1576 //if skipseg is set to 2, we return the filtered, unsegmented map (with valid centers)
1577 if (skipseg==2) {
1578 delete result;
1579 result=cache;
1580 }
1581
1582 result->set_attr("segment_centers",centers);
1583 result->set_attr("segment_amps",amps);
1584
1585 return result;
1586}
Dict is a dictionary to store <string, EMObject> pair.
Definition: emobject.h:385
type set_default(const string &key, type val)
Default setting behavior This can be achieved using a template - d.woolford Jan 2008 (before there wa...
Definition: emobject.h:569
EMData stores an image's data and defines core image processing routines.
Definition: emdata.h:82
@ EM_COMPRESSED
Definition: emutil.h:105
@ IMAGE_UNKNOWN
Definition: emutil.h:113
FloatPoint defines a float-coordinate point in a 1D/2D/3D space.
Definition: geometry.h:278
IntPoint defines an integer-coordinate point in a 1D/2D/3D space.
Definition: geometry.h:192
static float hypot3(int x, int y, int z)
Euclidean distance function in 3D: f(x,y,z) = sqrt(x*x + y*y + z*z);.
Definition: util.h:827
XYData defines a 1D (x,y) data set.
Definition: xydata.h:47
void make_gauss(int n, float xmax, float width)
Definition: xydata.cpp:162
#define y(i, j)
Definition: projector.cpp:1516
#define x(i)
Definition: projector.cpp:1517

References EMAN::EMUtil::EM_COMPRESSED, EMAN::Util::hypot3(), EMAN::EMUtil::IMAGE_UNKNOWN, EMAN::XYData::make_gauss(), EMAN::Processor::params, EMAN::Dict::set_default(), x, and y.

◆ process_inplace()

void GaussSegmentProcessor::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
imageThe image to be processed.

Implements EMAN::Processor.

Definition at line 1441 of file processor.cpp.

1442{
1443 printf("Process inplace not implemented. Please use process.\n");
1444 return;
1445}

Member Data Documentation

◆ NAME

const string GaussSegmentProcessor::NAME = "segment.gauss"
static

Definition at line 1693 of file processor.h.

Referenced by get_name().


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