IMP logo
IMP Reference Guide  2.22.0
The Integrative Modeling Platform
PathMap.h
Go to the documentation of this file.
1 /**
2  * \file IMP/bff/PathMap.h
3  * \brief Class to search path on grids
4  *
5  * \authors Thomas-Otavio Peulen
6  * Copyright 2007-2023 IMP Inventors. All rights reserved.
7  *
8  */
9 #ifndef IMPBFF_PATHMAP_H
10 #define IMPBFF_PATHMAP_H
11 
12 #include <IMP/bff/bff_config.h>
13 
14 #include <stdlib.h> /* malloc, free, rand */
15 #include <limits>
16 
17 #include <cmath>
18 #include <algorithm>
19 #include <unordered_set>
20 #include <queue>
21 #include <vector>
22 #include <utility> /* std::pair */
23 #include <Eigen/Dense>
24 
25 #include <IMP/Object.h>
26 #include <IMP/Particle.h>
27 #include <IMP/core/XYZR.h>
29 
30 #include <IMP/em/MRCReaderWriter.h>
32 #include <IMP/em/EMReaderWriter.h>
34 
35 #include <IMP/bff/PathMapHeader.h>
36 #include <IMP/bff/PathMapTile.h>
38 
39 IMPBFF_BEGIN_NAMESPACE
40 
41 class PathMapTile;
42 
43 
44 //! Class to search path on grids
45 class IMPBFFEXPORT PathMap : public IMP::em::SampledDensityMap {
46 
47 friend class PathMapTile;
48 friend class AV;
49 
50 private:
51 
52  // used in path search
53  std::vector<bool> visited;
54  std::vector<bool> edge_computed;
55  std::vector<float> cost;
56 
57 protected:
58 
59  std::vector<PathMapTile> tiles;
60  PathMapHeader pathMapHeader_;
61  std::vector<int> offsets_;
62  std::vector<PathMapTileEdge>& get_edges(int tile_idx);
63 
64 public:
65 
66 
67  /**
68 
69  @brief Updates the tiles in the path map.
70  *
71  This function updates the tiles in the path map based on the given parameters.
72  *
73  @param obstacle_threshold The threshold value for considering a cell as an obstacle. Default value is -1.0.
74  @param binarize A flag indicating whether to binarize the path map. Default value is true.
75  @param obstacle_penalty The penalty value for obstacle cells. Default value is TILE_PENALTY_DEFAULT.
76  @param reset_tile_edges A flag indicating whether to reset the edges of the tiles. Default value is true.
77  */
78  void update_tiles(
79  float obstacle_threshold=-1.0,
80  bool binarize=true,
81  float obstacle_penalty=TILE_PENALTY_DEFAULT,
82  bool reset_tile_edges=true
83  );
84 
85  /**
86  * @brief Resizes the PathMap object.
87  *
88  * This function resizes the PathMap object to accommodate the specified number of voxels.
89  *
90  * @param nvox The number of voxels to resize the PathMap to.
91  */
92  void resize(unsigned int nvox);
93 
94  /**
95 
96  @brief Sets the data for the path map.
97  *
98  This function sets the input data for the path map. The input data is a 1D array of doubles representing the map.
99  *
100  @param input Pointer to the input data array.
101  @param n_input Number of elements in the input data array.
102  @param obstacle_threshold The threshold value for considering a cell as an obstacle. Default value is -1.
103  @param binarize Flag indicating whether to binarize the input data. Default value is true.
104  @param obstacle_penalty The penalty value for obstacle cells. Default value is TILE_PENALTY_DEFAULT.
105  *
106  @note The input data array should be of size n_input.
107  @note If binarize is set to true, the input data will be converted to binary values based on the obstacle_threshold.
108  @note The obstacle_penalty is used to assign penalty values to obstacle cells in the path map.
109  */
110  void set_data(double *input, int n_input,
111  float obstacle_threshold=-1, bool binarize=true,
112  float obstacle_penalty=TILE_PENALTY_DEFAULT);
113 
114  /**
115 
116  Returns a vector of neighbor index offsets within a given radius.
117  @param neighbor_radius The radius within which to find neighbors. If negative, the radius is obtained from the path map header.
118  @return A vector of neighbor index offsets, where each offset consists of three integers (z, y, x) representing the relative position of the neighbor,
119  and one integer representing the tile offset. The vector also includes the edge cost between the current tile and the neighbor.
120  */
121  std::vector<int> get_neighbor_idx_offsets(double neighbor_radius = -1){
122  if(neighbor_radius < 0){
123  auto pmh = get_path_map_header();
124  neighbor_radius = pmh->get_neighbor_radius();
125  }
126  const int nn = ceil(neighbor_radius);
127  const double nr2 = neighbor_radius * neighbor_radius;
128 
129  const IMP::em::DensityHeader* header = get_header();
130  int nx = header->get_nx();
131  int ny = header->get_ny();
132  int nx_ny = nx * ny;
133 
134  std::vector<int> offsets;
135  for(int z = -nn; z < nn; z += 1) {
136  double dz2 = z * z;
137  int oz = z * nx_ny;
138  for(int y = -nn; y < nn; y++) {
139  int oy = y * nx;
140  double dz2_dy2 = dz2 + y * y;
141  for(int x = -nn; x < nn; x++) {
142  int ox = x;
143  int dz2_dy2_dx2 = dz2_dy2 + x * x;
144  if(dz2_dy2_dx2 <= nr2){
145  int d; // edge_cost is a float stored in an 32bit int
146  float *p = (float*) &d; // Make a float pointer point at the integer
147  *p = sqrt((float) dz2_dy2_dx2); // Pretend that the integer is a float and store the value
148  int tile_offset = oz + oy + ox;
149  offsets.emplace_back(z);
150  offsets.emplace_back(y);
151  offsets.emplace_back(x);
152  offsets.emplace_back(tile_offset);
153  offsets.emplace_back(d);
154  }
155  }
156  }
157  }
158  return offsets;
159  }
160 
161  //! Get index of voxel in an axis
162  /*!
163  * Returns the index of a voxel on a grid in a certain
164  * dimension.
165  * @param index voxel index
166  * @param dim dimension
167  * @return index of voxel in axis of dimension
168  */
169  int get_dim_index_by_voxel(long index, int dim);
170 
171  /**
172 
173  @brief Returns a read-only pointer to the header of the map.
174  *
175  @return const PathMapHeader* A read-only pointer to the header of the map.
176  */
177  const PathMapHeader *get_path_map_header() const { return &pathMapHeader_; }
178 
179 
180  /**
181 
182  @brief Returns a pointer to the header of the map in a writable version.
183  *
184  @return A pointer to the header of the map in a writable version.
185  */
186  PathMapHeader *get_path_map_header_writable() { return &pathMapHeader_; }
187 
188 
189  /**
190 
191  @brief Set the path map header.
192  *
193  This function sets the path map header for the path map.
194  *
195  @param path_map_header The path map header to set.
196  @param resolution The resolution of the path map. Default value is -1.0.
197  */
198  void set_path_map_header(PathMapHeader &path_map_header, float resolution = -1.0);
199 
200 
201  /**
202 
203  @brief Get the values of all tiles.
204  *
205  A tile in a path map contains information on the penalty for visiting a tile, the cost of a path
206  from the origin of a path search to the tile, the density of the tile, and other user-defined information.
207  *
208  When getting information from a tile, the returned values can be cropped to a specified range.
209  *
210  @param value_type Specifies the type of the returned information (see: PathMapTileOutputs).
211  Depending on the value type, the output can be the penalty for visiting the tile, the total
212  cost of a path to the tile, or the density of the tile. Additional user-defined content can also be accessed.
213  @param bounds Bound for cropping the output values.
214  @param feature_name Name of a feature when accessing additional information.
215  @return A vector of values for the specified parameters.
216  @relates PathMapTile::get_value
217  */
218  std::vector<float> get_tile_values(
219  int value_type = PM_TILE_COST,
220  std::pair<float, float> bounds = std::pair<float, float>(
221  {std::numeric_limits<float>::min(),
222  std::numeric_limits<float>::max()}),
223  const std::string &feature_name=""
224  );
225 
226  /**
227 
228  @brief Retrieves the values of the tiles in the path map.
229  *
230  This function retrieves the values of the tiles in the path map and stores them in the output array.
231  *
232  @param output A pointer to a 2D array of floats where the tile values will be stored.
233  @param nx A pointer to an integer that will store the number of tiles in the x-direction.
234  @param ny A pointer to an integer that will store the number of tiles in the y-direction.
235  @param nz A pointer to an integer that will store the number of tiles in the z-direction.
236  @param value_type The type of value to retrieve for each tile. Defaults to PM_TILE_COST.
237  @param bounds A pair of floats representing the lower and upper bounds for the tile values.
238  Defaults to the minimum and maximum float values.
239  @param feature_name The name of the feature for which to retrieve the tile values.
240  Defaults to an empty string.
241  */
242  void get_tile_values(
243  float **output, int *nx, int *ny, int *nz,
244  int value_type = PM_TILE_COST,
245  std::pair<float, float> bounds = std::pair<float, float>(
246  {std::numeric_limits<float>::min(),
247  std::numeric_limits<float>::max()}),
248  const std::string &feature_name=""
249  );
250 
251  /*!
252  * Values of tiles
253  * @return vector of all tiles in the accessible volume
254  */
255  std::vector<PathMapTile>& get_tiles();
256 
257  /// Change the value of a density inside or outside of a sphere
258  /*!
259  * Changes the value of the density inside or outside of a sphere.
260  * The density is used in the path-search (i.e., the accessible
261  * volume calculation
262  * @param r0 location of the sphere
263  * @param radius radius of the sphere
264  * @param value value inside or outside of the sphere
265  * @param inverse if set to true (default) the values outside of the sphere
266  * are modified. If false the values inside of the sphere are modified.
267  */
268  void fill_sphere(IMP::algebra::Vector3D r0, double radius, double value, bool inverse=true);
269 
270  /**
271 
272  @brief Finds a path between two indices in the path map.
273  *
274  This function finds a path between the specified path begin index and path end index in the path map.
275  If the path end index is not specified, the function will find a path from the path begin index to the last index in the path map.
276  The heuristic mode parameter determines the heuristic function to be used for path finding.
277  *
278  @param path_begin_idx The index of the path begin point in the path map.
279  @param path_end_idx The index of the path end point in the path map. Default value is -1, which means the last index in the path map.
280  @param heuristic_mode The mode of the heuristic function to be used for path finding. Default value is 0.
281  *
282  @return void
283  */
284  void find_path(long path_begin_idx, long path_end_idx = -1, int heuristic_mode = 0);
285 
286 
287  /**
288 
289  @brief Finds the shortest path between two nodes using Dijkstra's algorithm.
290  *
291  This function finds the shortest path between two nodes in the path map using Dijkstra's algorithm.
292  The path is calculated from the node at index path_begin_idx to the node at index path_end_idx.
293  If path_end_idx is not provided, the function will calculate the path to the last node in the map.
294  *
295  @param path_begin_idx The index of the starting node.
296  @param path_end_idx The index of the ending node (optional).
297  */
298  void find_path_dijkstra(long path_begin_idx, long path_end_idx = -1);
299 
300 
301  /**
302 
303  @brief Finds the shortest path between two indices using the A* algorithm.
304  *
305  This function uses the A* algorithm to find the shortest path between two indices in the path map.
306  The path is stored in the
307  path
308  member variable.
309  *
310  @param path_begin_idx The index of the starting point of the path.
311  @param path_end_idx The index of the ending point of the path. If not provided, the function will use the last index in the path map.
312  */
313  void find_path_astar(long path_begin_idx, long path_end_idx = -1);
314 
315  /**
316 
317  @brief Get the XYZ density of the path map.
318  This function returns a vector of IMP::algebra::Vector4D objects representing
319  the XYZ density of the path map.
320  @return std::vector The XYZ density of the path map.
321  */
322  std::vector<IMP::algebra::Vector4D> get_xyz_density();
323 
324  /**
325 
326  @brief Get the XYZ density of the path map.
327  This function returns the XYZ density of the path map as a 2D array.
328  @param output A pointer to a 2D array to store the XYZ density.
329  @param n_output1 A pointer to an integer to store the number of rows in the output array.
330  @param n_output2 A pointer to an integer to store the number of columns in the output array.
331  */
332  void get_xyz_density(double** output, int* n_output1, int* n_output2);
333 
334  /**
335 
336  @brief Resamples the obstacles in the path map.
337  *
338  This function resamples the obstacles in the path map, updating their positions and sizes.
339  *
340  @param extra_radius The extra radius to add to the obstacles (optional, default is 0.0).
341  */
342  void sample_obstacles(double extra_radius=0.0);
343 
344  /**
345 
346  @brief Constructs a PathMap object.
347  *
348  @param header The PathMapHeader object.
349  @param name The name of the PathMap.
350  @param kt The kernel type.
351  @param resolution The resolution of the PathMap.
352  */
353  explicit PathMap(
354  PathMapHeader &header,
355  std::string name = "PathMap%1%",
356  IMP::em::KernelType kt = IMP::em::BINARIZED_SPHERE,
357  float resolution = -1.0
358  );
359 
360 };
361 
362 
363 /**
364  * @brief Writes a path map to a file.
365  *
366  * Guesses the file type from the file name. The supported file formats are:
367  * - .mrc/.map
368  * - .em
369  * - .vol
370  * - .xplor
371  *
372  * @param m The PathMap object to write.
373  * @param filename The name of the file to write to.
374  * @param value_type The value type.
375  * @param bounds The bounds of the path map.
376  * @param feature_name The name of the feature.
377  */
378 IMPEMEXPORT
379 void write_path_map(
380  PathMap *m,
381  std::string filename,
382  int value_type,
383  const std::pair<float, float> bounds = std::pair<float, float>(
384  std::numeric_limits<float>::min(),
385  std::numeric_limits<float>::max()
386  ),
387  const std::string &feature_name = ""
388 );
389 
390 IMPBFF_END_NAMESPACE
391 
392 #endif //IMPBFF_PATHMAP_H
A decorator for a particle with accessible volume (AV).
Definition: AV.h:94
const DensityHeader * get_header() const
Returns a read-only pointer to the header of the map.
Definition: DensityMap.h:245
Header class for path search class PathMap.
DensityMap * binarize(DensityMap *orig_map, float threshold, bool reverse=false)
Return a map with 0 for all voxels below the threshold and 1 for those above.
IntPairs get_edges(const BoundingBoxD< 3 > &)
Return the edges of the box as indices into the vertices list.
Definition: BoundingBoxD.h:314
Tile used in path search by PathMap.
Class to search path on grids.
Definition: PathMap.h:45
Tile edges used in path search by PathMap.
Class for sampling a density map from particles.
const PathMapHeader * get_path_map_header() const
Returns a read-only pointer to the header of the map.
Definition: PathMap.h:177
Write path penalty.
Definition: PathMapTile.h:36
PathMapHeader * get_path_map_header_writable()
Returns a pointer to the header of the map in a writable version.
Definition: PathMap.h:186
int get_nx() const
Get the number of voxels in the x dimension.
Classes to read or write MRC files.
Classes to read or write density files in XPLOR format.
Classes to handle individual model particles. (Note that implementation of inline functions is in int...
int get_ny() const
Get the number of voxels in the y dimension.
void write_path_map(PathMap *m, std::string filename, int value_type, const std::pair< float, float > bounds=std::pair< float, float >(std::numeric_limits< float >::min(), std::numeric_limits< float >::max()), const std::string &feature_name="")
Writes a path map to a file.
A shared base class to help in debugging and things.
std::vector< int > get_neighbor_idx_offsets(double neighbor_radius=-1)
Definition: PathMap.h:121
VectorD< 3 > Vector3D
Definition: VectorD.h:408
Management of Spider Headers Electron Microscopy. Compatible with Spider and Xmipp formats Copyright ...
Decorator for a sphere-like particle.
Sampled density map.
Classes to read or write density files in EM format.