CFEL - ASG Software Suite  2.5.0
CASS
geom_parser.cpp
Go to the documentation of this file.
1 // Copyright (C) 2014 Lutz Foucar
2 
3 /**
4  * @file geom_parser.cpp class to parse and retrieve info from geom files.
5  *
6  * @author Lutz Foucar
7  */
8 
9 #include <map>
10 #include <fstream>
11 #include <stdexcept>
12 #include <cstdlib>
13 #include <algorithm>
14 #include <tr1/functional>
15 
16 #include "geom_parser.h"
17 #include "cass.h"
18 
19 using namespace cass;
20 using namespace GeometryInfo;
21 using namespace std;
22 using tr1::bind;
23 using tr1::placeholders::_1;
24 using tr1::placeholders::_2;
25 
26 
27 struct asicInfo_t
28 {
29  long int min_fs;
30  long int min_ss;
31  long int max_fs;
32  long int max_ss;
34  double res;
35  string clen;
36  double corner_x;
37  double corner_y;
38  long int no_index;
39  double x_fs;
40  double x_ss;
41  double y_fs;
42  double y_ss;
43 };
44 
46 {
47  GeometryInfo::pos_t pos(minuent);
48  pos.x -= subtrahend.x;
49  pos.y -= subtrahend.y;
50  return pos;
51 }
52 
53 size_t GeometryInfo::linearizeComponents(const GeometryInfo::pos_t &pos, const size_t nCols)
54 {
55  const size_t col(static_cast<size_t>(pos.x + 0.5));
56  const size_t row(static_cast<size_t>(pos.y + 0.5));
57  return (row*nCols + col);
58 }
59 
60 GeometryInfo::conversion_t GeometryInfo::generateConversionMap(const string &filename, const size_t sizeOfSrc, const size_t nSrcCols, const bool convertFromCheetahToCASS)
61 {
62  typedef map<string,asicInfo_t> asicInfoMap_t;
63  asicInfoMap_t geomInfos;
64  conversion_t src2lab(sizeOfSrc);
65 
66  /** open file @throw invalid_argument when it could not be opened */
67  ifstream geomFile (filename.c_str());
68  if (!geomFile.is_open())
69  throw invalid_argument("GeometryInfo::generateLookupTable(): could not open file '" +
70  filename +"'");
71 
72  /** read the file line by line */
73  string line;
74  while(!geomFile.eof())
75  {
76  getline(geomFile, line);
77 
78  /** if there is no '/' in line skip line */
79  if (line.find('/') == string::npos)
80  continue;
81 
82  /** get asic string, value name and value (as string) from line */
83  const string asic(line.substr(0,line.find('/')));
84  const string valueNameAndValue(line.substr(line.find('/')+1));
85  string valueName(valueNameAndValue.substr(0,valueNameAndValue.find('=')));
86  string valueString(valueNameAndValue.substr(valueNameAndValue.find('=')+1));
87 
88  /** eliminate whitespace from value name */
89  valueName.erase(remove(valueName.begin(), valueName.end(), ' '), valueName.end());
90 
91  /** depending on the value name retrieve the value as right type */
92  char * pEnd;
93  if (valueName == "min_fs")
94  geomInfos[asic].min_fs = std::strtol(valueString.c_str(),&pEnd,10);
95  else if (valueName == "min_ss")
96  geomInfos[asic].min_ss = std::strtol(valueString.c_str(),&pEnd,10);
97  else if (valueName == "max_fs")
98  geomInfos[asic].max_fs = std::strtol(valueString.c_str(),&pEnd,10);
99  else if (valueName == "max_ss")
100  geomInfos[asic].max_ss = std::strtol(valueString.c_str(),&pEnd,10);
101  else if (valueName == "badrow_direction")
102  {
103  valueString.erase(remove(valueString.begin(), valueString.end(), ' '), valueString.end());
104  geomInfos[asic].badrow_direction = valueString;
105  }
106  else if (valueName == "res")
107  geomInfos[asic].res = std::strtod(valueString.c_str(),&pEnd);
108  else if (valueName == "clen")
109  {
110  valueString.erase(remove(valueString.begin(), valueString.end(), ' '), valueString.end());
111  geomInfos[asic].clen = valueString;
112  }
113  else if (valueName == "corner_x")
114  geomInfos[asic].corner_x = std::strtod(valueString.c_str(),&pEnd);
115  else if (valueName == "corner_y")
116  geomInfos[asic].corner_y = std::strtod(valueString.c_str(),&pEnd);
117  else if (valueName == "no_index")
118  geomInfos[asic].no_index = std::strtol(valueString.c_str(),&pEnd,10);
119  else if (valueName == "fs")
120  {
121  /** if value is fs then parse the string containing the 2 numbers */
122  pEnd = &valueString[0];
123  for (int i(0); i < 2 ; ++i)
124  {
125  const double number = std::strtod(pEnd,&pEnd);
126  if (pEnd[0] == 'x')
127  geomInfos[asic].x_fs = number;
128  else if (pEnd[0] == 'y')
129  geomInfos[asic].y_fs = number;
130  else
131  throw runtime_error(string("GeometryInfo::generateConversionMap: Cannot assign '") +
132  pEnd[0] + "' to x or y, in line with contents'" +
133  line + "'. Parsed info so far: " +
134  "asic '" + asic + "', "
135  "value Name and Value '" + valueNameAndValue + "', "
136  "value Name '" + valueName + "', "
137  "value as String '" + valueString + "', "
138  "number extracted so far '" + toString(number) + "', "
139  "parsing iteration '" + toString(i) + "'");
140  ++pEnd;
141  }
142  }
143  else if (valueName == "ss")
144  {
145  pEnd = &valueString[0];
146  for (int i(0); i < 2 ; ++i)
147  {
148  const double number = std::strtod(pEnd,&pEnd);
149  if (pEnd[0] == 'x')
150  geomInfos[asic].x_ss = number;
151  else if (pEnd[0] == 'y')
152  geomInfos[asic].y_ss = number;
153  else
154  throw runtime_error(string("GeometryInfo::generateConversionMap: Cannot assign '") +
155  pEnd[0] + "' to x or y, in line with contents'" +
156  line + "'. Parsed info so far: " +
157  "asic '" + asic + "', "
158  "value Name and Value '" + valueNameAndValue + "', "
159  "value Name '" + valueName + "', "
160  "value as String '" + valueString + "', "
161  "number extracted so far '" + toString(number) + "', "
162  "parsing iteration '" + toString(i) + "'");
163  ++pEnd;
164  }
165  }
166  }
167 
168  /** go through all defined asics */
169  asicInfoMap_t::iterator it(geomInfos.begin());
170  for (; it != geomInfos.end(); ++it)
171  {
172  asicInfo_t& ai(it->second);
173 
174  /** if requested transform the start and end positions from the cheetah
175  * layout to the raw cass layout
176  */
177  if (convertFromCheetahToCASS)
178  {
179  const int nx(194);
180  const int ny(185);
181  const int quad(ai.min_fs/(2*nx));
182  const int asicRow(ai.min_ss/(1*ny));
183  const int xbegin(ai.min_fs/(1*nx) % 2);
184  const int ybegin(quad*2*4+asicRow);
185 
186  ai.min_fs = xbegin*nx;
187  ai.max_fs = xbegin*nx + nx-1;
188 
189  ai.min_ss = ybegin*ny;
190  ai.max_ss = ybegin*ny + ny-1;
191  }
192 
193 
194  /** go through all pixels of this asics module */
195  const int rowAsicRange(ai.max_ss - ai.min_ss);
196  const int colAsicRange(ai.max_fs - ai.min_fs);
197  for (int rowInAsic = 0; rowInAsic <= rowAsicRange; ++rowInAsic)
198  {
199  for (int colInAsic = 0; colInAsic <= colAsicRange; ++colInAsic)
200  {
201  /** find the position in the lab frame (in pixel units) of the current
202  * position (colInAsic,rowInAsic) in the asic
203  */
204  double xInLab = ai.x_fs*colInAsic + ai.x_ss*rowInAsic + ai.corner_x;
205  double yInLab = ai.y_fs*colInAsic + ai.y_ss*rowInAsic + ai.corner_y;
206 
207  /** determine where the current position in the asic is in the src image */
208  int colInSrc = ai.min_fs+colInAsic;
209  int rowInSrc = ai.min_ss+rowInAsic;
210 
211  /** find position in the linearized array */
212  int idxInSrc = rowInSrc * nSrcCols + colInSrc;
213 
214  /** check if whats been given in the geomfile goes together with the src */
215  if (idxInSrc >= static_cast<int>(sizeOfSrc))
216  throw out_of_range("generateConversionMap(): The generated index '" +
217  toString(idxInSrc) + "' is too big for the src with size '"+
218  toString(sizeOfSrc) + "' in position in asic '" +
219  it->first + "', row '" + toString(rowInAsic) +
220  ", col '" + toString(colInAsic) +
221  ", resulting position in lab would be x '" +
222  toString(xInLab) + ", y '" + toString(yInLab) +
223  "'. With position in source col '" +
224  toString(colInSrc) + "', row '" +
225  toString(rowInSrc) + "'");
226 
227  /** remember what x,y position in the lab does this position in the
228  * asic correspond to
229  */
230  src2lab[idxInSrc].x = xInLab;
231  src2lab[idxInSrc].y = yInLab;
232  }
233  }
234  }
235  return src2lab;
236 }
237 
239  const size_t sizeOfSrc,
240  const size_t nSrcCols,
241  const bool convertFromCheetahToCASS)
242 {
243  lookupTable_t lookupTable;
244  lookupTable.lut.resize(sizeOfSrc);
246  generateConversionMap(filename, sizeOfSrc, nSrcCols, convertFromCheetahToCASS);
247 
248  /** get the minimum and maximum position in lab x and y */
249  lookupTable.min.x = min_element(src2lab.begin(),src2lab.end(),
250  std::tr1::bind(less<pos_t::x_t>(),
251  std::tr1::bind<pos_t::x_t>(&pos_t::x,_1),
252  std::tr1::bind<pos_t::x_t>(&pos_t::x,_2)))->x;
253  lookupTable.min.y = min_element(src2lab.begin(),src2lab.end(),
254  std::tr1::bind(less<pos_t::y_t>(),
255  std::tr1::bind<pos_t::y_t>(&pos_t::y,_1),
256  std::tr1::bind<pos_t::y_t>(&pos_t::y,_2)))->y;
257  lookupTable.max.x = max_element(src2lab.begin(),src2lab.end(),
258  std::tr1::bind(less<pos_t::x_t>(),
259  std::tr1::bind<pos_t::x_t>(&pos_t::x,_1),
260  std::tr1::bind<pos_t::x_t>(&pos_t::x,_2)))->x;
261  lookupTable.max.y = max_element(src2lab.begin(),src2lab.end(),
262  std::tr1::bind(less<pos_t::y_t>(),
263  std::tr1::bind<pos_t::y_t>(&pos_t::y,_1),
264  std::tr1::bind<pos_t::y_t>(&pos_t::y,_2)))->y;
265 
266  /** move all values, such that they start at 0
267  * \f$ pos.x -= min_x \f$
268  * \f$ pos.y -= min_y \f$
269  */
270  transform(src2lab.begin(),src2lab.end(),src2lab.begin(),
271  std::tr1::bind(minus,_1,lookupTable.min));
272 
273  /** get the new maximum value of the shifted lab, which corresponds to the
274  * number of pixels that are required in the dest image, since all lab
275  * values are in pixel coordinates.
276  */
277  const double max_x = max_element(src2lab.begin(),src2lab.end(),
278  std::tr1::bind(less<pos_t::x_t>(),
279  std::tr1::bind<pos_t::x_t>(&pos_t::x,_1),
280  std::tr1::bind<pos_t::x_t>(&pos_t::x,_2)))->x;
281  const double max_y = max_element(src2lab.begin(),src2lab.end(),
282  std::tr1::bind(less<pos_t::y_t>(),
283  std::tr1::bind<pos_t::y_t>(&pos_t::y,_1),
284  std::tr1::bind<pos_t::y_t>(&pos_t::y,_2)))->y;
285 
286  /** determine the dimensions of the destination image */
287  lookupTable.nCols = static_cast<int>(max_x + 0.5)+1;
288  lookupTable.nRows = static_cast<int>(max_y + 0.5)+1;
289 
290  /** convert the positions in the lab space (pixel units) to linearized indizes
291  * in the destination image
292  * \f$ _lookuptable = round(src2lab.x) + round(src2lab.y)*nDestCols \f$
293  */
294  transform(src2lab.begin(),src2lab.end(),lookupTable.lut.begin(),
295  std::tr1::bind(&linearizeComponents,_1,lookupTable.nCols));
296 
297  /** check if the boundaries are ok, @throw out of range if not. */
298  if(lookupTable.nCols*lookupTable.nRows <= *max_element(lookupTable.lut.begin(),lookupTable.lut.end()))
299  throw out_of_range("generateLookupTable(): the maximum index in the lookup table '" +
300  toString(*max_element(lookupTable.lut.begin(),lookupTable.lut.end())) +
301  "' does not fit with the destination size of '" +
302  toString(lookupTable.nCols*lookupTable.nRows) + "'");
303 
304  return lookupTable;
305 }
pos_t minus(const pos_t &minuent, const pos_t &subtrahend)
functor to substract one position from the other
Definition: geom_parser.cpp:45
long int min_fs
Definition: geom_parser.cpp:29
double corner_y
Definition: geom_parser.cpp:37
long int no_index
Definition: geom_parser.cpp:38
STL namespace.
std::vector< pos_t > conversion_t
define the conversion table type
Definition: geom_parser.h:29
ForwardIterator min_element(ForwardIterator first, ForwardIterator last)
provide own implementation of min_element to be able to compile
Definition: operations.cpp:66
long int max_ss
Definition: geom_parser.cpp:32
conversion_t generateConversionMap(const std::string &filename, const size_t sizeOfSrc, const size_t nSrcCols, const bool convertFromCheetahToCASS)
parse the geom file and generate a lookup table
Definition: geom_parser.cpp:60
combine the position in the lab into a struct
Definition: geom_parser.h:20
double y_ss
Definition: geom_parser.cpp:42
ForwardIterator max_element(ForwardIterator first, ForwardIterator last)
provide own implementation of min_element to be able to compile
Definition: operations.cpp:41
double y_fs
Definition: geom_parser.cpp:41
double x_ss
Definition: geom_parser.cpp:40
string badrow_direction
Definition: geom_parser.cpp:33
size_t linearizeComponents(const pos_t &pos, const size_t nCols)
convert index with 2 components into a linearized index
Definition: geom_parser.cpp:53
file contains global definitions for project cass
class to parse and retrieve info from geom files.
std::string toString(const Type &t)
convert any type to a string
Definition: cass.h:63
long int max_fs
Definition: geom_parser.cpp:31
combine info needed for the lookuptable
Definition: geom_parser.h:32
double x_fs
Definition: geom_parser.cpp:39
double corner_x
Definition: geom_parser.cpp:36
double res
Definition: geom_parser.cpp:34
string clen
Definition: geom_parser.cpp:35
long int min_ss
Definition: geom_parser.cpp:30
std::vector< size_t > lut
Definition: geom_parser.h:34
lookupTable_t generateLookupTable(const std::string &filename, const size_t sizeOfSrc, const size_t nSrcCols, const bool convertFromCheetahToCASS)
generate a lookup table for a new image