Xmipp  v3.23.11-Nereus
Public Member Functions | Public Attributes | Friends | List of all members
Feature Class Referenceabstract

#include <phantom.h>

Inheritance diagram for Feature:
Inheritance graph
[legend]
Collaboration diagram for Feature:
Collaboration graph
[legend]

Public Member Functions

virtual void prepare ()=0
 
void assign (const Feature &F)
 
virtual void rotate (const Matrix2D< double > &E)
 
virtual void rotate_center (const Matrix2D< double > &E)
 
virtual int point_inside (const Matrix1D< double > &r, Matrix1D< double > &aux) const =0
 
int point_inside (const Matrix1D< double > &r) const
 
virtual double density_inside (const Matrix1D< double > &r, Matrix1D< double > &aux) const =0
 
int voxel_inside (const Matrix1D< double > &r, Matrix1D< double > &aux1, Matrix1D< double > &aux2) const
 
int voxel_inside (const Matrix1D< double > &r) const
 
double voxel_inside_by_normalized_density (const Matrix1D< double > &r, Matrix1D< double > &aux1, Matrix1D< double > &aux2) const
 
int intersects_sphere (const Matrix1D< double > &r, double radius, Matrix1D< double > &aux1, Matrix1D< double > &aux2, Matrix1D< double > &aux3) const
 
int intersects_sphere (const Matrix1D< double > &r, double radius) const
 
Featureencircle (double radius=0) const
 
virtual Featurescale (double factor) const =0
 
Featurebackground (int back_mode, double back_param) const
 
virtual double intersection (const Matrix1D< double > &direction, const Matrix1D< double > &passing_point, Matrix1D< double > &r, Matrix1D< double > &u) const =0
 
double intersection (const Matrix1D< double > &direction, const Matrix1D< double > &passing_point) const
 
virtual double volume () const =0
 
void mean_variance_in_plane (Image< double > *V, double z, double &mean, double &var)
 
void project_to (Projection &P, const Matrix2D< double > &VP, const Matrix2D< double > &PV) const
 
void corners (const MultidimArray< double > &V, Matrix1D< double > &corner1, Matrix1D< double > &corner2)
 
void draw_in (MultidimArray< double > &V, int color_mode=INTERNAL, double colour=-1)
 
void sketch_in (MultidimArray< double > &V, double colour=2)
 
void shift (double shiftX, double shiftY, double shiftZ)
 
void selfApplyGeometry (const Matrix2D< double > &A)
 
virtual void feat_printf (FILE *fh) const =0
 
virtual void feat_printm (MetaData &MD, size_t id)=0
 
void readCommon (char *line)
 
void readCommon (MDRow &row)
 
void read (MDRow &row)
 
virtual void read_specific (const std::vector< double > &vector)=0
 

Public Attributes

std::string type
 
char add_assign
 
double density
 
Matrix1D< double > center
 
double max_distance
 

Friends

std::ostream & operator<< (std::ostream &o, const Feature *F)
 

Detailed Description

Feature superclass. This is a superclass from which all features (cones, cylinders, ...) inherit. It contains all general information common to all feature classes, then the subclasses give the specific parameters for the feature.

Definition at line 93 of file phantom.h.

Member Function Documentation

◆ assign()

void Feature::assign ( const Feature F)

Another function for assigmnet.

Definition at line 92 of file phantom.cpp.

93 {
94  *this = F;
95 }

◆ background()

Feature * Feature::background ( int  back_mode,
double  back_param 
) const

Return a pointer to a feature which is the background of the actual one. You can specify two ways of computing the background, either as a sphere surrounding the feature or as an enlarged version of the feature. This is chosen giving the modes ENLARGE_MODE or SPHERE_MODE. Depending on the mode used the background parameter is understood as the sphere radius or as the scaling factor.

Definition at line 1662 of file phantom.cpp.

1663 {
1664  switch (back_mode)
1665  {
1666  case ENLARGE_MODE:
1667  return scale(back_param);
1668  break;
1669  case SPHERE_MODE:
1670  return encircle(back_param);
1671  break;
1672  default:
1673  REPORT_ERROR(ERR_VALUE_INCORRECT, "Feature::background: mode not supported");
1674  break;
1675  }
1676 }
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
#define ENLARGE_MODE
Definition: phantom.h:248
virtual Feature * scale(double factor) const =0
#define SPHERE_MODE
Definition: phantom.h:249
Incorrect value received.
Definition: xmipp_error.h:195
Feature * encircle(double radius=0) const
Definition: phantom.cpp:1644

◆ corners()

void Feature::corners ( const MultidimArray< double > &  V,
Matrix1D< double > &  corner1,
Matrix1D< double > &  corner2 
)

Define 3D corners for a feature. This function returns two Z3 points where the feature is confined. The volume borders are taken into account and you might make a for using these two values like this: \Ex:

F.corners(V,corner1,corner2);
for (int k=ZZ(corner1); k<=ZZ(corner2); k++)
for (int i=YY(corner1); i<=YY(corner2); i++)
for (int j=XX(corner1); j<=XX(corner2); j++) {
...
}

Definition at line 967 of file phantom.cpp.

969 {
970  corner1.resize(3);
971  corner2.resize(3);
972  XX(corner1) = XMIPP_MAX(FLOOR(XX(center) - max_distance), STARTINGX(V));
973  YY(corner1) = XMIPP_MAX(FLOOR(YY(center) - max_distance), STARTINGY(V));
974  ZZ(corner1) = XMIPP_MAX(FLOOR(ZZ(center) - max_distance), STARTINGZ(V));
975  XX(corner2) = XMIPP_MIN(CEIL(XX(center) + max_distance), FINISHINGX(V));
976  YY(corner2) = XMIPP_MIN(CEIL(YY(center) + max_distance), FINISHINGY(V));
977  ZZ(corner2) = XMIPP_MIN(CEIL(ZZ(center) + max_distance), FINISHINGZ(V));
978 }
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
#define FINISHINGX(v)
Matrix1D< double > center
Definition: phantom.h:119
#define FINISHINGZ(v)
#define STARTINGX(v)
#define STARTINGY(v)
#define FLOOR(x)
Definition: xmipp_macros.h:240
#define XX(v)
Definition: matrix1d.h:85
#define CEIL(x)
Definition: xmipp_macros.h:225
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
double max_distance
Definition: phantom.h:126
#define YY(v)
Definition: matrix1d.h:93
#define FINISHINGY(v)
#define STARTINGZ(v)
#define ZZ(v)
Definition: matrix1d.h:101

◆ density_inside()

virtual double Feature::density_inside ( const Matrix1D< double > &  r,
Matrix1D< double > &  aux 
) const
pure virtual

Speeded up density inside a feature, VIRTUAL!!. This function MUST be implemented for each subclass with NON constant density as blobs and tells you if a point is inside the feature or not plus give you information about the density of the feature at that point. If the point is inside returns 1 multiplied by the density of the NORMALIZED feature and if not, returns 0. The point is given in the vector r, and aux is an auxiliar vector with dimension 3 (must be externally resized) used to do some computations. This auxiliar vector must be supplied in order to gain speed as no memory allocating and freeing is needed.

Implemented in Cone, Ellipsoid, Cube, DCylinder, Cylinder, Gaussian, Blob, and Sphere.

◆ draw_in()

void Feature::draw_in ( MultidimArray< double > &  V,
int  color_mode = INTERNAL,
double  colour = -1 
)

Draw a feature in a Volume. This function draws a feature in a volume (*V). The word "colour" is a little misleading as the colour really refers to a grey-level global density. Ie, the default mode (INTERNAL) draws the feature with its own density and discards the "colour" given in the function call. However, you may change this colour, set a new global density and draw the volume with this given density. This option is useful to generate easily a labelled volume.

The Add-Assign behaviour is the one of the feature if the colour is internally defined, or Assign if the colour is externally given. In the assign behaviour a voxel value is assigned to the volume if the voxel there is smaller than the value we pretend to assign.

A voxel is drawn with a colour proportional to the number of Vertex inside the features. The volume is not cleaned at the beginning. \ Ex:

f.draw_in(V) --> Internal density
f.draw_in(V,INTERNAL,0.5) --> Internal density, 0.5 is discarded
f.draw_in(V,EXTERNAL,0.5) --> External density=0.5

Definition at line 983 of file phantom.cpp.

984 {
985  Matrix1D<double> aux1(3);
986  Matrix1D<double> aux2(3);
987  Matrix1D<double> corner1(3);
988  Matrix1D<double> corner2(3);
989  Matrix1D<double> r(3);
990  int add;
991  double inside;
992  double final_colour;
993 
994  if (colour_mode == INTERNAL)
995  {
996  final_colour = density;
997  add = add_assign == '+';
998  }
999  else
1000  {
1001  final_colour = colour;
1002  add = 0;
1003  }
1004 
1005  corners(V, corner1, corner2);
1006 #ifdef DEBUG
1007 
1008  std::cout << "Drawing \n";
1009  std::cout << this;
1010  std::cout << "colour_mode=" << colour_mode << std::endl;
1011  std::cout << "add_assign= " << add_assign << std::endl;
1012  std::cout << "add= " << add << std::endl;
1013  std::cout << " Corner 1" << corner1.transpose() << std::endl;
1014  std::cout << " Corner 2" << corner2.transpose() << std::endl;
1015 #endif
1016 
1017  FOR_ALL_ELEMENTS_IN_ARRAY3D_BETWEEN(corner1, corner2)
1018  {
1019  inside = voxel_inside_by_normalized_density(r, aux1, aux2);
1020 #ifdef DEBUG
1021  //int condition=(ZZ(r)==-12) && (YY(r)==1);
1022  int condition = 1;
1023  if (condition)
1024  std::cout << " r=" << r.transpose() << " inside= " << inside;
1025 #endif
1026 
1027  if (inside != 0)
1028  {
1029  double drawing_colour = final_colour * inside / 8;
1030  if (add)
1031  Vr += drawing_colour;
1032  else
1033  Vr = drawing_colour; // It does not select the maximum between Vr and drawing_colour anymore -> it fails when adding less dense features
1034 #ifdef DEBUG
1035 
1036  if (condition)
1037  std::cout << " V(r)=" << VOLVOXEL(V, (int)ZZ(r), (int)YY(r), (int)XX(r));
1038 #endif
1039 
1040  }
1041 #ifdef DEBUG
1042  if (condition)
1043  std::cout << std::endl;
1044 #endif
1045 
1046  }
1047 }
#define VOLVOXEL(V, k, i, j)
void corners(const MultidimArray< double > &V, Matrix1D< double > &corner1, Matrix1D< double > &corner2)
Definition: phantom.cpp:967
double voxel_inside_by_normalized_density(const Matrix1D< double > &r, Matrix1D< double > &aux1, Matrix1D< double > &aux2) const
Definition: phantom.cpp:880
double density
Definition: phantom.h:114
char add_assign
Definition: phantom.h:108
#define XX(v)
Definition: matrix1d.h:85
#define Vr
Definition: phantom.cpp:982
#define YY(v)
Definition: matrix1d.h:93
#define ZZ(v)
Definition: matrix1d.h:101
#define FOR_ALL_ELEMENTS_IN_ARRAY3D_BETWEEN(corner1, corner2)
#define INTERNAL
Definition: phantom.h:330

◆ encircle()

Feature * Feature::encircle ( double  radius = 0) const

Produce a sphere envolving the feature. This function returns a pointer to a feature (a sphere) with the same center, density, and feature behaviour as the given feature. The radius could be given in voxel units or if you leave it 0 then the radius is computed as 1.5 times the max_distance of this feature

Definition at line 1644 of file phantom.cpp.

1645 {
1646  Sphere *f;
1647  f = new Sphere;
1648 
1649  if (radius == 0)
1650  radius = 1.5 * max_distance;
1651 
1652  f->type = "sph";
1653  f->add_assign = add_assign;
1654  f->density = density;
1655  f->center = center;
1656  f->max_distance = radius;
1657  f->radius = radius;
1658 
1659  return (Feature *)f;
1660 }
double radius
Sphere radius.
Definition: phantom.h:471
Matrix1D< double > center
Definition: phantom.h:119
double density
Definition: phantom.h:114
char add_assign
Definition: phantom.h:108
double * f
double max_distance
Definition: phantom.h:126
std::string type
Definition: phantom.h:101

◆ feat_printf()

virtual void Feature::feat_printf ( FILE *  fh) const
pure virtual

Print the feature in the Feature format, VIRTUAL!!!. This function prints the feature in the Standard Feature format (readable by this library). Notice that the standard format is different for each specific feature. See Phantoms for more information about the supported file format.

Implemented in Cone, Ellipsoid, Cube, DCylinder, Cylinder, Gaussian, Blob, and Sphere.

◆ feat_printm()

virtual void Feature::feat_printm ( MetaData MD,
size_t  id 
)
pure virtual

Implemented in Cone, Ellipsoid, Cube, DCylinder, Cylinder, Gaussian, Blob, and Sphere.

◆ intersection() [1/2]

virtual double Feature::intersection ( const Matrix1D< double > &  direction,
const Matrix1D< double > &  passing_point,
Matrix1D< double > &  r,
Matrix1D< double > &  u 
) const
pure virtual

Speeded Up intersection of a feature with a ray, VIRTUAL!!!. This function returns the length of the intersection between the ray defined by its direction and a passing point and the actual feature (whose center and dimensions are known by itself).

r and u are auxiliar vectors of dimension 3, they must be supplied in order to gain speed. r is the passing point expressed in the feature coordinate system, and u is the direction in the same coordinate system.

Implemented in Cone, Ellipsoid, Cube, DCylinder, Cylinder, Gaussian, Blob, and Sphere.

◆ intersection() [2/2]

double Feature::intersection ( const Matrix1D< double > &  direction,
const Matrix1D< double > &  passing_point 
) const
inline

Intersection of a feature with a ray. This function does the same as the previous one but you needn't provide extra auxiliar vectors.

Definition at line 274 of file phantom.h.

276  {
277  Matrix1D<double> r(3);
278  Matrix1D<double> u(3);
279  return intersection(direction, passing_point, r, u);
280  }
virtual double intersection(const Matrix1D< double > &direction, const Matrix1D< double > &passing_point, Matrix1D< double > &r, Matrix1D< double > &u) const =0
doublereal * u

◆ intersects_sphere() [1/2]

int Feature::intersects_sphere ( const Matrix1D< double > &  r,
double  radius,
Matrix1D< double > &  aux1,
Matrix1D< double > &  aux2,
Matrix1D< double > &  aux3 
) const

Speeded up sphere intersecting feature. This function returns TRUE if a sphere of a given radius has any voxel inside this feature. r is the center of the sphere in R3. This speeded up function needs two vectors with dimension 3 externally resized.

Definition at line 936 of file phantom.cpp.

939 {
940  double radius2 = radius * radius;
941  bool intersects = false;
942  for (int k = FLOOR(ZZ(r) - radius); k <= CEIL(ZZ(r) + radius) && !intersects; k++)
943  {
944  auto dk=(double) k;
945  double distk2=(dk - ZZ(r))*(dk - ZZ(r));
946  for (int i = FLOOR(YY(r) - radius); i <= CEIL(YY(r) + radius) && !intersects; i++)
947  {
948  auto di=(double) i;
949  double distki2=distk2+(di - YY(r))*(di - YY(r));
950  for (int j = FLOOR(XX(r) - radius); j <= CEIL(XX(r) + radius) && !intersects; j++)
951  {
952  auto dj=(double) j;
953  if (distki2+(dj - XX(r))*(dj - XX(r))>radius2)
954  continue;
955  VECTOR_R3(aux3, j, i, k);
956  intersects = voxel_inside(aux3, aux1, aux2);
957  }
958  }
959  }
960  return intersects;
961 }
double * di
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
int voxel_inside(const Matrix1D< double > &r, Matrix1D< double > &aux1, Matrix1D< double > &aux2) const
Definition: phantom.cpp:845
#define FLOOR(x)
Definition: xmipp_macros.h:240
#define XX(v)
Definition: matrix1d.h:85
#define CEIL(x)
Definition: xmipp_macros.h:225
#define j
#define YY(v)
Definition: matrix1d.h:93
#define VECTOR_R3(v, x, y, z)
Definition: matrix1d.h:124
#define ZZ(v)
Definition: matrix1d.h:101

◆ intersects_sphere() [2/2]

int Feature::intersects_sphere ( const Matrix1D< double > &  r,
double  radius 
) const
inline

Sphere intersecting feature. This function is based in the previous one. It makes the same but you needn't supply the auxiliar vectors.

Definition at line 222 of file phantom.h.

223  {
224  Matrix1D<double> aux1(3);
225  Matrix1D<double> aux2(3);
226  Matrix1D<double> aux3(3);
227  return intersects_sphere(r, radius, aux1, aux2, aux3);
228  }
int intersects_sphere(const Matrix1D< double > &r, double radius, Matrix1D< double > &aux1, Matrix1D< double > &aux2, Matrix1D< double > &aux3) const
Definition: phantom.cpp:936

◆ mean_variance_in_plane()

void Feature::mean_variance_in_plane ( Image< double > *  V,
double  z,
double &  mean,
double &  var 
)

Mean and variance in a given plane. Given a plane z=z0, this function returns the mean and variance values of the volume (*V) in the voxels inside this feature. A voxel is considered to belong to the feature if it is totally inside the feature. If the plane is outside the volume scope the result is mean=variance=0

Definition at line 1929 of file phantom.cpp.

1931 {
1932  double sum1 = 0;
1933  double sum2 = 0;
1934  double no_points = 0;
1935  Matrix1D<double> r(3);
1936  Matrix1D<double> aux1(3);
1937  Matrix1D<double> aux2(3);
1938 
1939  mean = 0;
1940  var = 0;
1941  if (z < STARTINGZ(VOLMATRIX(*V)) || z > FINISHINGZ(VOLMATRIX(*V)))
1942  return;
1943 
1944  ZZ(r) = z;
1945  for (YY(r) = STARTINGY(VOLMATRIX(*V)); YY(r) <= FINISHINGY(VOLMATRIX(*V)); YY(r)++)
1946  for (XX(r) = STARTINGX(VOLMATRIX(*V)); XX(r) <= FINISHINGX(VOLMATRIX(*V)); XX(r)++)
1947  {
1948  if (voxel_inside(r, aux1, aux2) == 8)
1949  {
1950  double voxel = VOLVOXEL(*V, (int)ZZ(r), (int)YY(r), (int)XX(r));
1951  sum1 += voxel;
1952  sum2 += voxel * voxel;
1953  no_points++;
1954  }
1955  }
1956  if (no_points != 0)
1957  {
1958  mean = sum1 / no_points;
1959  var = sum2 / no_points - mean * mean;
1960  }
1961 }
#define VOLVOXEL(V, k, i, j)
#define FINISHINGX(v)
#define VOLMATRIX(V)
#define FINISHINGZ(v)
#define STARTINGX(v)
#define STARTINGY(v)
int voxel_inside(const Matrix1D< double > &r, Matrix1D< double > &aux1, Matrix1D< double > &aux2) const
Definition: phantom.cpp:845
#define XX(v)
Definition: matrix1d.h:85
double z
#define YY(v)
Definition: matrix1d.h:93
#define FINISHINGY(v)
#define STARTINGZ(v)
#define ZZ(v)
Definition: matrix1d.h:101

◆ point_inside() [1/2]

virtual int Feature::point_inside ( const Matrix1D< double > &  r,
Matrix1D< double > &  aux 
) const
pure virtual

Speeded up point inside a feature, VIRTUAL!!. This function MUST be implemented for each subclass and tells you if a point is inside the feature or not. If the point is inside returns 1 and if not, returns 0. The point is given in the vector r, and aux is an auxiliar vector with dimension 3 (must be externally resized) used to do some computations. This auxiliar vector must be supplied in order to gain speed as no memory allocating and freeing is needed.

Implemented in Cone, Ellipsoid, Cube, DCylinder, Cylinder, Gaussian, Blob, and Sphere.

◆ point_inside() [2/2]

int Feature::point_inside ( const Matrix1D< double > &  r) const
inline

Point inside a feature. This function is based in the previous one. It makes the same but you needn't supply the auxiliar vector.

Definition at line 160 of file phantom.h.

161  {
162  Matrix1D<double> aux(3);
163  return point_inside(r, aux);
164  }
virtual int point_inside(const Matrix1D< double > &r, Matrix1D< double > &aux) const =0

◆ prepare()

virtual void Feature::prepare ( )
pure virtual

Prepare feature for work. This function computes the maximum distance and possibly the Euler and inverse Euler matrices.

Implemented in Cone, Ellipsoid, Cube, DCylinder, Cylinder, Gaussian, Blob, and Sphere.

◆ project_to()

void Feature::project_to ( Projection P,
const Matrix2D< double > &  VP,
const Matrix2D< double > &  PV 
) const

Project feature onto a projection plane. Projection is a class itself which has got inside the direction of projection. The projection plane is not cleaned (set all values to 0) when entering this function, but the projection of this feature is added to the already stored one. The projection plane is supposed to have its logical origin in the right place (normally, the middle of the image) before entering the function. An oversampling technique is used in order to produce better projections, the projection in one pixel is computed from the value of 4 points near the pixel, you can modify the subsampling value (actually 2x2=4) by changing a constant at the beginning of the function.

The matrix VP (3x3) is used to define how to relate a point in the 3D universal coordinate to the projection plane. So a point ru in the universal coordinate system, projects to VP*r. PV must be the inverse of the forwarding projection matrix.

Definition at line 1293 of file phantom.cpp.

1295 {
1296 constexpr float SUBSAMPLING = 2; // for every measure 2x2 line
1297  // integrals will be taken to
1298  // avoid numerical errors
1299 constexpr float SUBSTEP = 1/(SUBSAMPLING*2.0);
1300 
1301  Matrix1D<double> origin(3);
1303  VP.getRow(2, direction);
1304  direction.selfTranspose();
1305  Matrix1D<double> corner1(3);
1306  Matrix1D<double> corner2(3);
1307  Matrix1D<double> act(3);
1309 
1310  // Find center of the feature in the projection plane ...................
1311  // Step 1). Project the center to the plane, the result is in the
1312  // universal coord system
1313  M3x3_BY_V3x1(origin, VP, center);
1314 
1315  // Matrix1D<double> origin_debug(3);
1316  // Uproject_to_plane(center,P.direction,0,origin_debug);
1317 
1318  //#define DEBUG_LITTLE
1319 #ifdef DEBUG_LITTLE
1320 
1321  std::cout << "Actual feature\n" << this << std::endl;
1322  std::cout << "center " << center.transpose() << std::endl;
1323  std::cout << "VP matrix\n" << VP << std::endl;
1324  std::cout << "P.direction " << P.direction.transpose() << std::endl;
1325  std::cout << "direction " << direction.transpose() << std::endl;
1326  std::cout << "P.euler matrix " << P.euler << std::endl;
1327  std::cout << "max_distance " << max_distance << std::endl;
1328  std::cout << "origin " << origin.transpose() << std::endl;
1329  // std::cout << "origin_debug (Univ.coord) " << origin_debug.transpose() << std::endl;
1330 #endif
1331  /*
1332  // Step 2). Express this projected center in the projection coord system
1333  M3x3_BY_V3x1(origin_debug,P.euler,origin_debug);
1334  // if (A!=NULL) M2x2_BY_V2x1(origin,*A,origin_);
1335  #ifdef DEBUG_LITTLE
1336  std::cout << "origin (Proj.coord) " << origin_debug.transpose() << std::endl;
1337  #endif
1338  */
1339 
1340  // Find limits for projection ...........................................
1341  // Choose corners for the projection of this feature. It is supposed
1342  // to have at the worst case a projection of size max_distance
1345 #ifdef DEBUG_LITTLE
1346 
1347  std::cout << "Corner1 : " << corner1.transpose() << std::endl
1348  << "Corner2 : " << corner2.transpose() << std::endl;
1349 #endif
1350 
1351  box_enclosing(corner1, corner2, VP, corner1, corner2);
1352  // if (A!=NULL) {
1353  // rectangle_enclosing(corner1,corner2,*A,corner1,corner2);
1354 #ifdef DEBUG_LITTLE
1355 
1356  std::cout << "Corner1 moves to : " << corner1.transpose() << std::endl
1357  << "Corner2 moves to : " << corner2.transpose() << std::endl;
1358 #endif
1359  // }
1360 
1361  V3_PLUS_V3(corner1, origin, corner1);
1362  V3_PLUS_V3(corner2, origin, corner2);
1363 #ifdef DEBUG_LITTLE
1364 
1365  std::cout << "Corner1 finally is : " << corner1.transpose() << std::endl
1366  << "Corner2 finally is : " << corner2.transpose() << std::endl;
1367 #endif
1368  /*
1369  Matrix1D<double> corner1_debug(2),corner2_debug(2);
1370  VECTOR_R2(corner1_debug, max_distance, max_distance);
1371  VECTOR_R2(corner2_debug,-max_distance,-max_distance);
1372  #ifdef DEBUG_LITTLE
1373  std::cout << "Corner1_debug : " << corner1_debug.transpose() << std::endl
1374  << "Corner2_debug : " << corner2_debug.transpose() << std::endl;
1375  #endif
1376  V2_PLUS_V2(corner1_debug,origin_debug,corner1_debug);
1377  V2_PLUS_V2(corner2_debug,origin_debug,corner2_debug);
1378  #ifdef DEBUG_LITTLE
1379  std::cout << "Corner1_debug finally is : " << corner1_debug.transpose() << std::endl
1380  << "Corner2_debug finally is : " << corner2_debug.transpose() << std::endl;
1381  #endif
1382  */
1383  // Discard not necessary components
1384  corner1.resize(2);
1385  corner2.resize(2);
1386 
1387  // Clip to image size
1388  sortTwoVectors(corner1, corner2);
1389  XX(corner1) = CLIP(ROUND(XX(corner1)), STARTINGX(P()), FINISHINGX(P()));
1390  YY(corner1) = CLIP(ROUND(YY(corner1)), STARTINGY(P()), FINISHINGY(P()));
1391  XX(corner2) = CLIP(ROUND(XX(corner2)), STARTINGX(P()), FINISHINGX(P()));
1392  YY(corner2) = CLIP(ROUND(YY(corner2)), STARTINGY(P()), FINISHINGY(P()));
1393 
1394 #ifdef DEBUG_LITTLE
1395 
1396  std::cout << "corner1 " << corner1.transpose() << std::endl;
1397  std::cout << "corner2 " << corner2.transpose() << std::endl;
1398  std::cout.flush();
1399 #endif
1400 
1401  // Check if there is something to project
1402  if (XX(corner1) == XX(corner2))
1403  return;
1404  if (YY(corner1) == YY(corner2))
1405  return;
1406 
1407  // Study the projection for each point in the projection plane ..........
1408  // (u,v) are in the deformed projection plane (if any deformation)
1409  for (auto v = (int)YY(corner1); v <= (int)YY(corner2); v++)
1410  for (auto u = (int)XX(corner1); u <= (int)XX(corner2); u++)
1411  {
1412  double length = 0;
1413 #ifdef DEBUG_EVEN_MORE
1414 
1415  std::cout << "Studying point (" << u << "," << v << ")\n";
1416  std::cout.flush();
1417 #endif
1418 
1419  // Perform subsampling ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1420  double u0 = u - (int)(SUBSAMPLING / 2.0) * SUBSTEP;
1421  double v0 = v - (int)(SUBSAMPLING / 2.0) * SUBSTEP;
1422  double actv = v0;
1423  for (int subv = 0; subv < SUBSAMPLING; subv++)
1424  {
1425  double actu = u0;
1426  for (int subu = 0; subu < SUBSAMPLING; subu++)
1427  {
1428  // Compute the coordinates of point (subu,subv) which is
1429  // within the plane in the universal coordinate system
1430  XX(act) = actu;
1431  YY(act) = actv;
1432  ZZ(act) = 0;
1433  // if (Ainv!=NULL) M2x2_BY_V2x1(act,*Ainv,act);
1434  // M3x3_BY_V3x1(act,P.eulert,act);
1435  M3x3_BY_V3x1(act, PV, act);
1436 
1437  // Compute the intersection of a ray which passes through
1438  // this point and its direction is perpendicular to the
1439  // projection plane
1440  double possible_length = intersection(direction, act);
1441  if (possible_length > 0)
1442  length += possible_length;
1443 
1444 #ifdef DEBUG_EVEN_MORE
1445 
1446  std::cout << "Averaging at (" << actu << "," << actv << ")\n";
1447  std::cout << " which in univ. coords is " << act.transpose() << std::endl;
1448  std::cout << " intersection there " << possible_length << std::endl;
1449 #endif
1450  // Prepare for next iteration
1451  actu += SUBSTEP * 2.0;
1452  }
1453  actv += SUBSTEP * 2.0;
1454  }
1455  length /= (SUBSAMPLING * SUBSAMPLING);
1456 #ifdef DEBUG
1457 
1458  std::cout << "Final value added at position (" << u << "," << v << ")="
1459  << length << std::endl;
1460 #endif
1461 
1462  // Add at the correspondent pixel the found intersection ,,,,,,,,,,
1463  IMGPIXEL(P, v, u) += length * density;
1464  }
1465 }
void sortTwoVectors(Matrix1D< T > &v1, Matrix1D< T > &v2)
Definition: matrix1d.h:1206
#define FINISHINGX(v)
Matrix2D< double > euler
Matrix1D< double > center
Definition: phantom.h:119
double density
Definition: phantom.h:114
void selfTranspose()
Definition: matrix1d.h:944
#define STARTINGX(v)
Matrix1D< T > transpose() const
Definition: matrix1d.cpp:644
#define STARTINGY(v)
#define CLIP(x, x0, xF)
Definition: xmipp_macros.h:260
void box_enclosing(const Matrix1D< double > &v0, const Matrix1D< double > &vF, const Matrix2D< double > &V, Matrix1D< double > &corner1, Matrix1D< double > &corner2)
Definition: geometry.cpp:366
#define XX(v)
Definition: matrix1d.h:85
virtual double intersection(const Matrix1D< double > &direction, const Matrix1D< double > &passing_point, Matrix1D< double > &r, Matrix1D< double > &u) const =0
__host__ __device__ float length(float2 v)
#define ROUND(x)
Definition: xmipp_macros.h:210
void direction(const MultidimArray< double > &orMap, MultidimArray< double > &qualityMap, double lambda, int size, MultidimArray< double > &dirMap, int x, int y)
Matrix1D< double > direction
double max_distance
Definition: phantom.h:126
#define M3x3_BY_V3x1(a, M, b)
Definition: matrix2d.h:170
#define YY(v)
Definition: matrix1d.h:93
#define FINISHINGY(v)
#define VECTOR_R3(v, x, y, z)
Definition: matrix1d.h:124
doublereal * u
double v0
void getRow(size_t i, Matrix1D< T > &v) const
Definition: matrix2d.cpp:871
#define ZZ(v)
Definition: matrix1d.h:101
#define V3_PLUS_V3(a, b, c)
Definition: matrix1d.h:190
#define IMGPIXEL(I, i, j)
#define SPEED_UP_temps012
Definition: xmipp_macros.h:403

◆ read()

void Feature::read ( MDRow row)

Definition at line 213 of file phantom.cpp.

214 {
215  readCommon(row);
216  std::vector<double> VectSpecific; // Vector for specific parameters of feature
217  row.getValue(MDL_PHANTOM_FEATURE_SPECIFIC, VectSpecific);
218  read_specific(VectSpecific);
219 }
void readCommon(char *line)
Definition: phantom.cpp:177
T & getValue(MDLabel label)
Specific parameters for a feature (vector double)
virtual void read_specific(const std::vector< double > &vector)=0

◆ read_specific()

virtual void Feature::read_specific ( const std::vector< double > &  vector)
pure virtual

Read a feature from a file, VIRTUAL!!!. The format must be the one given in Phantoms, and each subclass must implement its own I/O routines. These routines must fill only the non common part of the feature description, but they receive the whole line with the description.

Implemented in Cone, Ellipsoid, Cube, DCylinder, Cylinder, Gaussian, Blob, and Sphere.

◆ readCommon() [1/2]

void Feature::readCommon ( char *  line)

Read common part of the feature description. The common part is the feature type, the behaviour, density and center. The description is passed as a line. Exceptions are thrown if the description doesn't conform the standard specification.

Definition at line 177 of file phantom.cpp.

178 {
179  int stat;
180  char straux[6];
181  center.resize(3);
182  stat = sscanf(line, "%s %c %lf %lf %lf %lf",
183  straux,
184  &add_assign,
185  &density,
186  &(XX(center)),
187  &(YY(center)),
188  &(ZZ(center)));
189  if (stat != 6)
191  (std::string)"Error when reading common part of feature: " + line);
192  type = straux;
193 }
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
Matrix1D< double > center
Definition: phantom.h:119
double density
Definition: phantom.h:114
char add_assign
Definition: phantom.h:108
#define XX(v)
Definition: matrix1d.h:85
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
Couldn&#39;t read from file.
Definition: xmipp_error.h:139
#define YY(v)
Definition: matrix1d.h:93
std::string type
Definition: phantom.h:101
#define ZZ(v)
Definition: matrix1d.h:101

◆ readCommon() [2/2]

void Feature::readCommon ( MDRow row)

Definition at line 196 of file phantom.cpp.

197 {
198  center.resize(3);
199  std::vector <double> VecFeatureCenter; // Keep the center of the feature
200  std::string s_op; // As no label for char in MD_TYPE (for add/assign)
204  !row.getValue(MDL_PHANTOM_FEATURE_CENTER,VecFeatureCenter))
205  REPORT_ERROR(ERR_ARG_MISSING, (std::string)"Error when reading common part of feature");
206  XX(center) = VecFeatureCenter[0];
207  YY(center) = VecFeatureCenter[1];
208  ZZ(center) = VecFeatureCenter[2];
209  add_assign = s_op[0];
210 }
Argument missing.
Definition: xmipp_error.h:114
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
Matrix1D< double > center
Definition: phantom.h:119
double density
Definition: phantom.h:114
char add_assign
Definition: phantom.h:108
The density of the feature (double)
T & getValue(MDLabel label)
#define XX(v)
Definition: matrix1d.h:85
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
Type of the feature (Sphere, Blob, ...) (std::string)
#define YY(v)
Definition: matrix1d.h:93
Operation in case of overlapping features (+,-)
Center of the feature (vector double)
std::string type
Definition: phantom.h:101
#define ZZ(v)
Definition: matrix1d.h:101

◆ rotate()

void Feature::rotate ( const Matrix2D< double > &  E)
virtual

Rotate the whole feature. Rotate this feature using a rotation matrix. The center as well as the feature itself is rotated.

Reimplemented in Oriented_Feature.

Definition at line 159 of file phantom.cpp.

160 {
161  rotate_center(E);
162 }
virtual void rotate_center(const Matrix2D< double > &E)
Definition: phantom.cpp:151

◆ rotate_center()

void Feature::rotate_center ( const Matrix2D< double > &  E)
virtual

Rotate only the center. Rotate the center of this feature only around the phantom center

Definition at line 151 of file phantom.cpp.

152 {
153  Matrix2D<double> inverse_angles_matrix;
154  inverse_angles_matrix = E.inv();
155  center = inverse_angles_matrix * center;
156  //center=E*center;
157 }
void inv(Matrix2D< T > &result) const
Definition: matrix2d.cpp:663
Matrix1D< double > center
Definition: phantom.h:119

◆ scale()

virtual Feature* Feature::scale ( double  factor) const
pure virtual

Return a scaled version of this feature, VIRTUAL!!!. This function returns a pointer to a feature (of the same type as the feature for which the function was called, ie, if you scale a sphere the result is a sphere, if you scale a cone, the result is a cone, ...) that is a scaled version of the actual feature (see each specific implementation to see which is the relatioship between the two features). This function is useful to define backgrounds with the same shape of the given feature.

Implemented in Cone, Ellipsoid, Cube, DCylinder, Cylinder, Gaussian, Blob, and Sphere.

◆ selfApplyGeometry()

void Feature::selfApplyGeometry ( const Matrix2D< double > &  A)

Apply a general geometric transformation. The transformation must be defined by a 4x4 matrix that can be generated using the geometric functions in xmippGeometry or xmippMatrix2D. The matrix must be the desired transformation (i.e., new coordinate=A*old_coordinate. Don't worry because the selfApplyGeometry of Phantom take cares of passing to this function the appropriate matrix. No check is done about the size of A.

Only the center is transformed, the feature will keep the same size.

Definition at line 1078 of file phantom.cpp.

1079 {
1080  Matrix1D<double> r(4);
1081  XX(r) = XX(center);
1082  YY(r) = YY(center);
1083  ZZ(r) = ZZ(center);
1084  r(3) = 1;
1085  r = A * r;
1086  XX(center) = XX(r);
1087  YY(center) = YY(r);
1088  ZZ(center) = ZZ(r);
1089 }
Matrix1D< double > center
Definition: phantom.h:119
#define XX(v)
Definition: matrix1d.h:85
#define YY(v)
Definition: matrix1d.h:93
#define ZZ(v)
Definition: matrix1d.h:101

◆ shift()

void Feature::shift ( double  shiftX,
double  shiftY,
double  shiftZ 
)

Shift. Shift the feature a given amount of voxels. The new center is the old center plus the given shift, and that's all

Definition at line 1070 of file phantom.cpp.

1071 {
1072  XX(center) += shiftX;
1073  YY(center) += shiftY;
1074  ZZ(center) += shiftZ;
1075 }
Matrix1D< double > center
Definition: phantom.h:119
#define XX(v)
Definition: matrix1d.h:85
#define YY(v)
Definition: matrix1d.h:93
#define ZZ(v)
Definition: matrix1d.h:101

◆ sketch_in()

void Feature::sketch_in ( MultidimArray< double > &  V,
double  colour = 2 
)

Draw the surface of the feature. This function draws the surface of the feature at the given volume. A voxel is said to belong to the surface if the number of corners inside the feature meets 1<=n<=7. The default gray_level with which voxels will be drawn is 2 (normally higher than the usual volume grey levels, and the behaviour of the voxels drawn is Assign.

Definition at line 1051 of file phantom.cpp.

1052 {
1053  Matrix1D<double> aux1(3);
1054  Matrix1D<double> aux2(3);
1055  Matrix1D<double> corner1(3);
1056  Matrix1D<double> corner2(3);
1057  Matrix1D<double> r(3);
1058  int inside;
1059 
1060  corners(V, corner1, corner2);
1061  FOR_ALL_ELEMENTS_IN_ARRAY3D_BETWEEN(corner1, corner2)
1062  {
1063  inside = voxel_inside(r, aux1, aux2);
1064  if (inside != 0 && inside != 8)
1065  A3D_ELEM(V, (int)ZZ(r), (int)YY(r), (int)XX(r)) = colour;
1066  }
1067 }
void corners(const MultidimArray< double > &V, Matrix1D< double > &corner1, Matrix1D< double > &corner2)
Definition: phantom.cpp:967
#define A3D_ELEM(V, k, i, j)
int voxel_inside(const Matrix1D< double > &r, Matrix1D< double > &aux1, Matrix1D< double > &aux2) const
Definition: phantom.cpp:845
#define XX(v)
Definition: matrix1d.h:85
#define YY(v)
Definition: matrix1d.h:93
#define ZZ(v)
Definition: matrix1d.h:101
#define FOR_ALL_ELEMENTS_IN_ARRAY3D_BETWEEN(corner1, corner2)

◆ volume()

virtual double Feature::volume ( ) const
pure virtual

Volume of the feature in (voxel units)� , VIRTUAL!!!. This function returns the volume of each feature supposing that a voxel is of size 1x1x1.

Implemented in Cone, Ellipsoid, Cube, DCylinder, Cylinder, Gaussian, Blob, and Sphere.

◆ voxel_inside() [1/2]

int Feature::voxel_inside ( const Matrix1D< double > &  r,
Matrix1D< double > &  aux1,
Matrix1D< double > &  aux2 
) const

Speeded up voxel inside a feature. A voxel is compound of 8 subvoxels. This function returns the number of subvoxel centers falling inside the feature. The voxel size is supposed to be 1, and r is the center of the voxel in R3. This speeded up function needs two vectors with dimension 3 externally resized.

Definition at line 845 of file phantom.cpp.

847 {
848 
849  // The subvoxels are visited following a Gray code, so the number
850  // of operations is minimized
851  XX(aux1) = XX(r) + 0.25;
852  YY(aux1) = YY(r) + 0.25;
853  ZZ(aux1) = ZZ(r) + 0.25; // 000
854  int inside = point_inside(aux1, aux2);
855  DEBUG_SHOW;
856  ZZ(aux1) -= 0.5;
857  inside += point_inside(aux1, aux2); // 001
858  DEBUG_SHOW;
859  YY(aux1) -= 0.5;
860  inside += point_inside(aux1, aux2); // 011
861  DEBUG_SHOW;
862  ZZ(aux1) += 0.5;
863  inside += point_inside(aux1, aux2); // 010
864  DEBUG_SHOW;
865  XX(aux1) -= 0.5;
866  inside += point_inside(aux1, aux2); // 110
867  DEBUG_SHOW;
868  ZZ(aux1) -= 0.5;
869  inside += point_inside(aux1, aux2); // 111
870  DEBUG_SHOW;
871  YY(aux1) += 0.5;
872  inside += point_inside(aux1, aux2); // 101
873  DEBUG_SHOW;
874  ZZ(aux1) += 0.5;
875  inside += point_inside(aux1, aux2); // 100
876  DEBUG_SHOW;
877  return inside;
878 }
#define DEBUG_SHOW
Definition: phantom.cpp:843
virtual int point_inside(const Matrix1D< double > &r, Matrix1D< double > &aux) const =0
#define XX(v)
Definition: matrix1d.h:85
#define YY(v)
Definition: matrix1d.h:93
#define ZZ(v)
Definition: matrix1d.h:101

◆ voxel_inside() [2/2]

int Feature::voxel_inside ( const Matrix1D< double > &  r) const
inline

Voxel inside a feature. This function is based in the previous one. It makes the same but you needn't supply the auxiliar vectors.

Definition at line 192 of file phantom.h.

193  {
194  Matrix1D<double> aux1(3);
195  Matrix1D<double> aux2(3);
196  return voxel_inside(r, aux1, aux2);
197  }
int voxel_inside(const Matrix1D< double > &r, Matrix1D< double > &aux1, Matrix1D< double > &aux2) const
Definition: phantom.cpp:845

◆ voxel_inside_by_normalized_density()

double Feature::voxel_inside_by_normalized_density ( const Matrix1D< double > &  r,
Matrix1D< double > &  aux1,
Matrix1D< double > &  aux2 
) const

A voxel is compound of 8 subvoxels. This function returns the number of subvoxel centers falling inside the feature multiplied by the normalized feature density. That is, the value of the density is always 1 at the origin The voxel size is supposed to be 1, and r is the center of the voxel in R3. This speeded up function needs two vectors with dimension 3 externally resized.

Definition at line 880 of file phantom.cpp.

884 {
885 #ifdef NEVER
886  if (type == "blo")
887  {
888  std::cout << "den=" << density_inside(r, aux2) << std::endl;
889  return(density_inside(r, aux2));
890  }
891  else
892  return((double)voxel_inside(r, aux1, aux2));
893 #endif
894  // The subvoxels are visited following a Gray code, so the number
895  // of operations is minimized
896  XX(aux1) = XX(r) + 0.25;
897  YY(aux1) = YY(r) + 0.25;
898  ZZ(aux1) = ZZ(r) + 0.25; // 000
899  double inside = (double)point_inside(aux1, aux2)
900  * density_inside(r, aux2);
901  DEBUG_SHOW;
902  ZZ(aux1) -= 0.5;
903  inside += (double)point_inside(aux1, aux2)
904  * density_inside(r, aux2); // 001
905  DEBUG_SHOW;
906  YY(aux1) -= 0.5;
907  inside += (double)point_inside(aux1, aux2)
908  * density_inside(r, aux2); // 011
909  DEBUG_SHOW;
910  ZZ(aux1) += 0.5;
911  inside += (double)point_inside(aux1, aux2)
912  * density_inside(r, aux2); // 010
913  DEBUG_SHOW;
914  XX(aux1) -= 0.5;
915  inside += (double)point_inside(aux1, aux2)
916  * density_inside(r, aux2); // 110
917  DEBUG_SHOW;
918  ZZ(aux1) -= 0.5;
919  inside += (double)point_inside(aux1, aux2)
920  * density_inside(r, aux2); // 111
921  DEBUG_SHOW;
922  YY(aux1) += 0.5;
923  inside += (double)point_inside(aux1, aux2)
924  * density_inside(r, aux2); // 101
925  DEBUG_SHOW;
926  ZZ(aux1) += 0.5;
927  inside += (double)point_inside(aux1, aux2)
928  * density_inside(r, aux2); // 100
929  DEBUG_SHOW;
930  return inside;
931 
932 }
#define DEBUG_SHOW
Definition: phantom.cpp:843
virtual int point_inside(const Matrix1D< double > &r, Matrix1D< double > &aux) const =0
int voxel_inside(const Matrix1D< double > &r, Matrix1D< double > &aux1, Matrix1D< double > &aux2) const
Definition: phantom.cpp:845
#define XX(v)
Definition: matrix1d.h:85
#define YY(v)
Definition: matrix1d.h:93
virtual double density_inside(const Matrix1D< double > &r, Matrix1D< double > &aux) const =0
std::string type
Definition: phantom.h:101
#define ZZ(v)
Definition: matrix1d.h:101

Friends And Related Function Documentation

◆ operator<<

std::ostream& operator<< ( std::ostream &  o,
const Feature F 
)
friend

Show feature not in the standard format but more informatively. This function is based on the std::cout << ... of each subclass. First shows the common part of the feature and then its specific part. Be careful that you must show a pointer to the feature!! \ Ex: Sphere sphere; std::cout << (Feature *) &sphere;

Definition at line 569 of file phantom.cpp.

570 {
571  if (F != nullptr)
572  {
573  o << "Feature --------" << std::endl;
574  o << " type: " << F->type << std::endl;
575  o << " add_assign: " << F->add_assign << std::endl;
576  o << " density: " << F->density << std::endl;
577  o << " center: " << F->center.transpose() << std::endl;
578  if (F->type == "sph")
579  o << *((Sphere *) F);
580  else if (F->type == "blo")
581  o << *((Blob *) F);
582  else if (F->type == "gau")
583  o << *((Gaussian *) F);
584  else if (F->type == "cyl")
585  o << *((Cylinder *) F);
586  else if (F->type == "dcy")
587  o << *((DCylinder *) F);
588  else if (F->type == "cub")
589  o << *((Cube *) F);
590  else if (F->type == "ell")
591  o << *((Ellipsoid *) F);
592  else if (F->type == "con")
593  o << *((Cone *) F);
594  }
595  return o;
596 }
Definition: phantom.h:1244
Definition: phantom.h:563
Matrix1D< double > center
Definition: phantom.h:119
double density
Definition: phantom.h:114
char add_assign
Definition: phantom.h:108
Matrix1D< T > transpose() const
Definition: matrix1d.cpp:644
Definition: phantom.h:1010
std::string type
Definition: phantom.h:101

Member Data Documentation

◆ add_assign

char Feature::add_assign

Feature behaviour. This flag indicates how the feature behaves inside the voxel volume. If this flag is set to '+' then the voxels occupied by this feature are incremented with the feature value. If the flag is set to '=' then the voxels are set to to the same value of the feature.

Definition at line 108 of file phantom.h.

◆ center

Matrix1D<double> Feature::center

Center of the feature. The center of the feature is understood differently according to the specific class, see them to know exactly how this value is interpreted.

Definition at line 119 of file phantom.h.

◆ density

double Feature::density

Feature Density. Density of the feature in grey level values. It needn't be between 0 and 1, or 0 and 255. What is more, it can be even negative, and so you can build holes inside volumes.

Definition at line 114 of file phantom.h.

◆ max_distance

double Feature::max_distance

Maximum distance from the center. This value is a precalculated and tells the maximum distance from any point belonging to the feature to its center. This is used to speed up some functions not considering voxels which we know are beyond the scope of this feature.

Definition at line 126 of file phantom.h.

◆ type

std::string Feature::type

Feature type. A three letters string telling what kind of feature this object is. For example, "cyl", "con", "cub", ... See the specific classes to know exactly which is each label.

Definition at line 101 of file phantom.h.


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