OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
InitGridWithPixel.hpp
Go to the documentation of this file.
1 //
2 // Created by jstark on 2019-11-07.
3 //
15 #ifndef IMAGE_BASED_RECONSTRUCTION_GETINITIALGRID_HPP
16 #define IMAGE_BASED_RECONSTRUCTION_GETINITIALGRID_HPP
17 
18 #include <iostream>
19 #include <typeinfo>
20 #include <cmath>
21 #include <sys/stat.h>
22 
23 #include "Vector/vector_dist.hpp"
24 #include "Grid/grid_dist_id.hpp"
25 #include "data_type/aggregate.hpp"
26 #include "Decomposition/CartDecomposition.hpp"
27 
29 typedef signed char BYTE;
30 
31 inline bool exists_test (const std::string& name) {
32  struct stat buffer;
33  return (stat (name.c_str(), &buffer) == 0);
34 }
35 
36 
37 
44 std::vector<int> get_size(const std::string & path_to_file)
45 {
46  std::vector<int> stack_dimst_1d;
47  // check if file exists and stream input csv file
48  if(!exists_test(path_to_file)){
49  std::cout << "------------------------------------------------------------------------" << std::endl;
50  std::cout << "Error: file " << path_to_file << " does not exist. Aborting..." << std::endl;
51  std::cout << "------------------------------------------------------------------------" << std::endl;
52  abort();
53  }
54  std::ifstream file(path_to_file);
55 
56 
57  // get its size
58  std::streampos fileSize;
59  file.seekg(0, std::ios::end);
60  fileSize = file.tellg();
61  file.seekg(0, std::ios::beg);
62 
63  // reserve capacity
64  stack_dimst_1d.reserve(fileSize);
65 
66  std::string field;
67  while ( getline(file, field) ) // 1 field per axis
68  {
69  std::istringstream iss(field);
70  int val;
71  iss >> val;
72  stack_dimst_1d.push_back(val); // add the #pixels for current axis to the array
73  }
74 
75  // reverse order to compensate reverse reading
76  std::reverse(std::begin(stack_dimst_1d), std::end(stack_dimst_1d));
77 
78  return stack_dimst_1d;
79 }
80 
81 
91 template <size_t Phi_0, typename grid_type>
92 void load_pixel_onto_grid(grid_type & grid, std::string file_name, std::vector <int> & stack_dims)
93 {
94  constexpr size_t x = 0;
95  constexpr size_t y = 1;
96  constexpr size_t z = 2;
97 
98  // check if file exists and stream input file
99  if(!exists_test(file_name)){
100  std::cout << "------------------------------------------------------------------------" << std::endl;
101  std::cout << "Error: file " << file_name << " does not exist. Aborting..." << std::endl;
102  std::cout << "------------------------------------------------------------------------" << std::endl;
103  abort();
104  }
105  std::ifstream file_stream (file_name, std::ifstream::binary);
106 
107  auto & v_cl = create_vcluster();
108  if (v_cl.rank() == 0)
109  {
110  for (int d = 0; d < grid_type::dims; d++)
111  {
112  std::cout << "# grid points in dimension " << d << " = " << grid.size(d) << std::endl;
113  }
114  }
115 
116  // assign pixel values to domain. For each pixel get factor_refinement number of grid points with corresponding value
117  auto dom = grid.getDomainIterator();
118  std::vector<BYTE> pixel_line; // one x-line of the image stack which will be read
119 
120  size_t sz_img[grid_type::dims];
121  for (int d = 0; d < grid_type::dims; d++)
122  {
123  sz_img[d] = stack_dims[d];
124  }
125  grid_sm<grid_type::dims,void> ginfo_image(sz_img); // in order to get the image related key later on
126 
127  double refinement[grid_type::dims];
128  for (int d = 0; d < grid_type::dims; d++)
129  {
130  refinement[d] = (double) grid.size(d) / (double)stack_dims[d]; // get the factor, by which the grid resolution differs from the image stack resolution
131  if (v_cl.rank() == 0) std::cout << "effective refinement in dimension " << d << " = " << refinement[d] << std::endl;
132  }
133 
134  while(dom.isNext())
135  {
136  auto key = dom.get();
137  auto gkey = grid.getGKey(key);
138 
139  // In case a patch starts within a group of nodes to which same pixel-value should be assigned, get the
140  // respective rest-offset
141  int rest_offset = (int) (fmod(gkey.get(0), refinement[x])); // get the remainder
142 
143 
144  // get l as the length of one x-line of the original image stack for the specific patch on the processor
145  auto & gbox = grid.getLocalGridsInfo();
146  auto & DomBox = gbox.get(key.getSub()).Dbox;
147  size_t patch_size = DomBox.getHigh(0) - DomBox.getLow(0) + 1;
148 
149  size_t l = (size_t) ceil( (patch_size + rest_offset) / refinement[x]);
150 
151  // in case that the grid has a different resolution than the underlying image stack:
152  // create a key which is used to get the offset for the file reading
153  // the indices in this key are corrected by the refinement factor
154  for (int d = 0; d < grid_type::dims; d++)
155  {
156  gkey.set_d(d, floor(gkey.get(d) / refinement[d]));
157  }
158 
159  // the offset matches the pixel from the image stack to the corresponding current position of the iterator
160  // in the grid
161  size_t offset = ginfo_image.LinId(gkey);
162  file_stream.seekg(offset); // jump to the correct position in the file
163 
164  // prepare space for the pixel values of one x-line in the original image stack
165  pixel_line.resize(l);
166  // stream the file and fill pixel values into pixel_line
167  file_stream.read((char*) & pixel_line[0], l);
168 
169  // run over a whole grid-line in x and assign pixel values from pixel_line to grid nodes
170  // if the grid is finer in x as the image stack, the same pixel value from pixel_line is
171  // assigned refinement[x] times
172  for (int k = 0; k < patch_size; ++k)
173  {
174  auto key = dom.get();
175  // get the correct index of the pixel to be read from pixel_line by considering a potential rest-offset,
176  // when the patch divides group of nodes that belong to the same pixel
177  size_t i = (size_t) floor((k + rest_offset) / refinement[x]);
178  grid.template get<Phi_0>(key) = (double) pixel_line[i];
179  ++dom;
180  }
181  // now one grid line in x is finished and the iterator dom has advanced accordingly s.t. next loop continues
182  // with next line, meaning that y increased by 1 (or z respectivley, when y = ymax + 1)
183  }
184 
185  grid.template ghost_get<Phi_0>();
186 }
187 
188 
189 
190 #endif //IMAGE_BASED_RECONSTRUCTION_GETINITIALGRID_HPP
static const unsigned int dims
Number of dimensions.
Header file containing help-functions that perform on OpenFPM-grids.
void load_pixel_onto_grid(grid_type &grid, std::string file_name, std::vector< int > &stack_dims)
Converts the pixel values stored in a binary file into doubles and loads them onto an OpenFPM grid.
std::vector< int > get_size(const std::string &path_to_file)
Read the number of pixels per dimension from a csv-file in order to create a grid with the same size.
mem_id LinId(const grid_key_dx< N, ids_type > &gk, const char sum_id[N]) const
Linearization of the grid_key_dx with a specified shift.
Definition: grid_sm.hpp:434
This is a distributed grid.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
Declaration grid_sm.
Definition: grid_sm.hpp:147