CFEL - ASG Software Suite  2.5.0
CASS
pixeldetector_mask.cpp
Go to the documentation of this file.
1 //Copyright (C) 2011, 2012 Lutz Foucar
2 
3 /**
4  * @file pixeldetector_mask.cpp contains definition of the mask of a pixeldetector
5  *
6  * @author Lutz Foucar
7  */
8 
9 #include <tr1/functional>
10 #include <map>
11 #include <string>
12 #include <stdexcept>
13 #include <sstream>
14 #include <iostream>
15 
16 #include "pixeldetector_mask.h"
17 
18 #include "cass_settings.h"
19 #include "common_data.h"
20 #include "log.h"
21 
22 using namespace cass;
23 using namespace pixeldetector;
24 using namespace std;
25 using tr1::function;
26 
27 namespace cass
28 {
29 namespace pixeldetector
30 {
31 /** an index within a matrix */
32 typedef pair<int,int> index_t;
33 
34 /** an index within a matrix but with with floating point precision */
35 typedef pair<float,float> indexf_t;
36 
37 /** operates a plus on two indices
38  *
39  * performs \f$(lhs_1+rhs_1)(lhs_2+rhs_2)\f$.
40  *
41  * @return the result of the operation
42  * @param lhs the left hand side of the operation
43  * @param rhs the right hand side of the opeation
44  *
45  * @author Lutz Foucar
46  */
47 index_t operator+(const index_t& lhs, const index_t& rhs)
48 {
49  return make_pair(lhs.first + rhs.first,
50  lhs.second + rhs.second);
51 }
52 
53 /** operates a minus on two indices
54  *
55  * performs \f$(lhs_1-rhs_1)(lhs_2-rhs_2)\f$.
56  *
57  * @return the result of the operation
58  * @param lhs the left hand side of the operation
59  * @param rhs the right hand side of the opeation
60  *
61  * @author Lutz Foucar
62  */
63 index_t operator-(const index_t& lhs, const index_t& rhs)
64 {
65  return make_pair(lhs.first - rhs.first,
66  lhs.second - rhs.second);
67 }
68 
69 /** operates times on two indices
70  *
71  * performs \f$(lhs_1*rhs_1)(lhs_2*rhs_2)\f$.
72  *
73  * @return the result of the operation
74  * @param lhs the left hand side of the operation
75  * @param rhs the right hand side of the opeation
76  *
77  * @author Lutz Foucar
78  */
79 index_t operator*(const index_t& lhs, const index_t& rhs)
80 {
81  return make_pair(lhs.first * rhs.first,
82  lhs.second * rhs.second);
83 }
84 
85 /** operates devides on two indices
86  *
87  * performs \f$(lhs_1/rhs_1)(lhs_2/rhs_2)\f$.
88  *
89  * @return the result of the operation
90  * @param lhs the left hand side of the operation
91  * @param rhs the right hand side of the opeation
92  *
93  * @author Lutz Foucar
94  */
95 indexf_t operator/(const indexf_t& lhs, const indexf_t& rhs)
96 {
97  return make_pair(lhs.first / rhs.first,
98  lhs.second / rhs.second);
99 }
100 
101 /** operates less of an indices to a scalar
102  *
103  * performs \f$(lhs_1+lhs_2)<rhs\f$.
104  *
105  * @return the result of the operation
106  * @param lhs the left hand side of the operation
107  * @param rhs the right hand side of the opeation
108  *
109  * @author Lutz Foucar
110  */
111 bool operator<(const indexf_t& lhs, const indexf_t::first_type rhs)
112 {
113  return ((lhs.first + lhs.second) < rhs);
114 }
115 
116 /** calculate the scalar product of two indices
117  *
118  * perform operation \f$ lhs_1*rhs_1 + lhs_2*rhs_2\f$
119  *
120  * @return the result of the operation
121  * @param lhs the left hand side of the operation
122  * @param rhs the right hand side of the opeation
123  *
124  * @author Lutz Foucar
125  */
126 index_t::first_type dot(const index_t& lhs, const index_t& rhs)
127 {
128  return ((lhs.first*rhs.first)+(lhs.second*lhs.second));
129 }
130 
131 
132 /** convert matrix index to linearised index
133  *
134  * @return index in the linearised array
135  * @param matrixIndex in the matrix
136  * @param width the width of the matrix
137  *
138  * @author Lutz Foucar
139  */
140 size_t TwoD2OneD(const index_t& matrixIndex, const size_t width)
141 {
142  return matrixIndex.second * width + matrixIndex.first;
143 }
144 
145 /** convert linearised index to matrixindex
146  *
147  * @return index in the matrix
148  * @param linearisedIndex the linearized index in the matrix
149  * @param width the width of the matrix
150  *
151  * @author Lutz Foucar
152  */
153 index_t OneD2TwoD(const size_t linearisedIndex, const size_t width)
154 {
155  return make_pair(linearisedIndex % width,
156  linearisedIndex / width);
157 }
158 
159 /** add a circle to the mask
160  *
161  * goes through the sqare that conatins the cirlce and checks whether the index
162  * is covered by the circle. If so the mask at that index will be set to false.
163  *
164  * @cassttng PixelDetectors/\%name\%/CorrectionMaps/Mask/\%index\%/{CenterX|CenterY}\n
165  * The center of the circle. Default is 500|500.
166  * @cassttng PixelDetectors/\%name\%/CorrectionMaps/Mask/\%index\%/{Radius}\n
167  * The radius of the circle. Default is 2.
168  *
169  * @param data the container containing the mask where the element should be added
170  * @param s the settings element to read the mask element parameters from
171  *
172  * @author Nicola Coppola
173  * @author Lutz Foucar
174  */
176 {
177  QWriteLocker lock(&data.lock);
178  const index_t center(make_pair(s.value("CenterX",500).toUInt(),
179  s.value("CenterY",500).toUInt()));
180  const index_t::first_type radius(s.value("Radius",2).toUInt());
181 
182  if ((center.first < radius) ||
183  (center.second < radius) ||
184  (static_cast<int>(data.columns) <= (center.first + radius)) ||
185  (static_cast<int>(data.rows) <= (center.second + radius)))
186  {
187  throw out_of_range("addCircle(): The radius '" + toString(radius) +
188  "' is choosen to big and does not fit the image. Center of cirlce ("
189  + toString(center.first) +","
190  + toString(center.second)+")");
191  }
192  const size_t radius_sq(radius*radius);
193  const index_t lowerLeft(make_pair(center.first-radius, center.second-radius));
194  const index_t upperRight(make_pair(center.first+radius, center.second+radius));
195  const size_t width(data.columns);
196 
197  for (index_t::first_type row(lowerLeft.second); row < upperRight.second; ++row)
198  {
199  for (index_t::first_type column(lowerLeft.first); column < upperRight.first; ++column)
200  {
201  const index_t idx(make_pair(column,row));
202  const index_t idx_sq((idx - center)*(idx - center));
203  data.mask[TwoD2OneD(idx,width)] *= !(idx_sq < radius_sq);
204  }
205  }
206 }
207 
208 /** add a square element to the mask
209  *
210  * sets all pixels covered by the square to 0.
211  *
212  * @cassttng PixelDetectors/\%name\%/CorrectionMaps/Mask/\%index\%/{LowerLeftX|LowerLeftY}\n
213  * The lower left pixel of the square element. The indizes given are
214  *. included in the square. Default is 0|0.
215  * @cassttng PixelDetectors/\%name\%/CorrectionMaps/Mask/\%index\%/{UpperRightX|UpperRightY}\n
216  * The upper right pixel of the square element. The indizes given are
217  *. included in the square. Default is 1023|1023.
218  *
219  * @param data the container containing the mask where the element should be added
220  * @param s the settings element to read the mask element parameters from
221  *
222  * @author Nicola Coppola
223  * @author Lutz Foucar
224  */
226 {
227  QWriteLocker lock(&data.lock);
228  const index_t lowerLeft(make_pair(s.value("LowerLeftX",0).toUInt(),
229  s.value("LowerLeftY",0).toUInt()));
230  const index_t upperRight(make_pair(s.value("UpperRightX",1024).toUInt(),
231  s.value("UpperRightY",1024).toUInt()));
232  if ((static_cast<int>(data.columns) <= upperRight.first) ||
233  (static_cast<int>(data.rows) <= upperRight.second))
234  throw invalid_argument("addSquare(): The upper right coordinate ("
235  + toString(upperRight.first) +","
236  + toString(upperRight.second)+") "+
237  "is too big for the mask that has a size of ("
238  + toString(data.columns) +","
239  + toString(data.rows)+") ");
240  if((upperRight.first < lowerLeft.first) ||
241  (upperRight.second < lowerLeft.second))
242  throw out_of_range("addSquare(): The lowerLeft corner ("
243  + toString(lowerLeft.first) +","
244  + toString(lowerLeft.second)+") "+
245  "is not really to the lower left of ("
246  + toString(upperRight.first) +","
247  + toString(upperRight.second)+") ");
248 
249  const size_t width(data.columns);
250  for (index_t::first_type row(lowerLeft.second); row <= upperRight.second; ++row)
251  {
252  for (index_t::first_type column(lowerLeft.first); column <= upperRight.first; ++column)
253  {
254  const index_t idx(make_pair(column,row));
255  data.mask[TwoD2OneD(idx,width)] = 0;
256  }
257  }
258 }
259 
260 /** add a ellipsodial element to the mask
261  *
262  * adds an ellipsodial to the mask. Will iterate trhough the sqare that contains
263  * the ellipse and checks which pixels should be masked.
264  *
265  * @cassttng PixelDetectors/\%name\%/CorrectionMaps/Mask/\%index\%/{CenterX|CenterY}\n
266  * The central point of the ellipse. Default is 500|500.
267  * @cassttng PixelDetectors/\%name\%/CorrectionMaps/Mask/\%index\%/{SemiAxisX|SemiAxisY}\n
268  * The semi axis along x and y of the ellipse. By definition the
269  * longer one defines the major axis and the smaller on the minor axis.
270  * Default is 5|4.
271  *
272  * @param data the container containing the mask where the element should be added
273  * @param s the settings element to read the mask element parameters from
274  *
275  * @author Nicola Coppola
276  * @author Lutz Foucar
277  */
279 {
280  QWriteLocker lock(&data.lock);
281  const index_t center(make_pair(s.value("CenterX",500).toUInt(),
282  s.value("CenterY",500).toUInt()));
283  const index_t::first_type a(s.value("SemiAxisX",5).toUInt());
284  const index_t::first_type b(s.value("SemiAxisY",2).toUInt());
285  const size_t width(data.columns);
286 
287  if ((center.first < a) ||
288  (center.second < b))
289  throw invalid_argument("addCircle(): The semi axis a '" + toString(a) +
290  "' and b '" + toString(b) +
291  "' are choosen to big and do not fit with center ("
292  + toString(center.first) +","
293  + toString(center.second)+")");
294  if((static_cast<int>(data.columns) <= (center.first + a)) ||
295  (static_cast<int>(data.rows) <= (center.second + b)))
296  throw out_of_range("addCircle(): The semi axis boundaries a '" + toString(center.first + a) +
297  "' and b '" + toString(center.second + b) +
298  "' are choosen to big and do not fit with center ("
299  + toString(data.columns) +","
300  + toString(data.rows)+")");
301 
302  const index_t lowerLeft(make_pair(center.first-a, center.second-b));
303  const index_t upperRight(make_pair(center.first+a, center.second+b));
304  const index_t axis_sq(make_pair(a,b)*make_pair(a,b));
305 
306  for (index_t::first_type row(lowerLeft.second); row <= upperRight.second; ++row)
307  {
308  for (index_t::first_type column(lowerLeft.first); column <= upperRight.first; ++column)
309  {
310  /** @todo check whether this works */
311  const index_t idx(make_pair(column,row));
312  const index_t idx_sq((idx - center)*(idx - center));
313  const indexf_t idx_tmp(idx_sq / axis_sq);
314  data.mask[TwoD2OneD(idx,width)] *= !(idx_tmp < 1);
315  }
316  }
317 }
318 
319 /** add a ring
320  *
321  * define the ring by two ellipses; an inner and outer ellipse. The area covered
322  * by the out but not by the inner will be masked. The two ellipsoids can have
323  * different centers and axis. Therefore the ring can take any shape.
324  *
325  * @cassttng PixelDetectors/\%name\%/CorrectionMaps/Mask/\%index\%/{InnerCenterX|InnerCenterY}\n
326  * The central point of the inner ellipse. Default is 500|500.
327  * @cassttng PixelDetectors/\%name\%/CorrectionMaps/Mask/\%index\%/{InnerSemiAxisX|InnerSemiAxisY}\n
328  * The semi axis along x and y of the inner ellipse. By definition the
329  * longer one defines the major axis and the smaller on the minor axis.
330  * Default is 5|4.
331  * @cassttng PixelDetectors/\%name\%/CorrectionMaps/Mask/\%index\%/{OuterCenterX|OuterCenterY}\n
332  * The central point of the outer ellipse. Default is 500|500.
333  * @cassttng PixelDetectors/\%name\%/CorrectionMaps/Mask/\%index\%/{OuterSemiAxisX|OuterSemiAxisY}\n
334  * The semi axis along x and y of the outer ellipse. By definition the
335  * longer one defines the major axis and the smaller on the minor axis.
336  * Default is 20|20.
337  *
338  * @author Lutz Foucar
339  */
341 {
342  QWriteLocker lock(&data.lock);
343  const index_t outer_center(make_pair(s.value("OuterCenterX",500).toUInt(),
344  s.value("OuterCenterY",500).toUInt()));
345  const index_t::first_type outer_a(s.value("OuterSemiAxisX",5).toUInt());
346  const index_t::first_type outer_b(s.value("OuterSemiAxisY",2).toUInt());
347  const index_t inner_center(make_pair(s.value("InnerCenterX",500).toUInt(),
348  s.value("InnerCenterY",500).toUInt()));
349  const index_t::first_type inner_a(s.value("InnerSemiAxisX",20).toUInt());
350  const index_t::first_type inner_b(s.value("InnerSemiAxisY",20).toUInt());
351  const size_t width(data.columns);
352 
353  if ((outer_center.first < outer_a) ||
354  (outer_center.second < outer_b))
355  throw invalid_argument("addCircle(): The outer semi axis x '" + toString(outer_a) +
356  "' and b '" + toString(outer_b) +
357  "' are choosen to big and do not fit with center ("
358  + toString(outer_center.first) +","
359  + toString(outer_center.second)+")");
360  if ((static_cast<int>(data.columns) <= (outer_center.first + outer_a)) ||
361  (static_cast<int>(data.rows) <= (outer_center.second + outer_b)))
362  throw out_of_range("addCircle(): The outer semi axis boundaries a '" + toString(outer_center.first + outer_a) +
363  "' and b '" + toString(outer_center.second + outer_b) +
364  "' are choosen to big and do not fit into image ("
365  + toString(data.columns) +","
366  + toString(data.rows)+")");
367 
368  if ((inner_center.first < inner_a) ||
369  (inner_center.second < inner_b))
370  throw invalid_argument("addCircle(): The inner semi axis x '" + toString(inner_a) +
371  "' and b '" + toString(inner_b) +
372  "' are choosen to big and do not fit with center ("
373  + toString(inner_center.first) +","
374  + toString(inner_center.second)+")");
375 
376  if((static_cast<int>(data.columns) <= (inner_center.first + inner_a)) ||
377  (static_cast<int>(data.rows) <= (inner_center.second + inner_b)))
378  throw out_of_range("addCircle(): The inner semi axis boundaries a '" + toString(inner_center.first + inner_a) +
379  "' and b '" + toString(inner_center.second + inner_b) +
380  "' are choosen to big and do not fit into image ("
381  + toString(data.columns) +","
382  + toString(data.rows)+")");
383 
384  const size_t min_col(min(outer_center.first - outer_a,
385  inner_center.first - inner_a));
386  const size_t max_col(max(outer_center.first + outer_a,
387  inner_center.first + inner_a));
388  const size_t min_row(min(outer_center.second - outer_b,
389  inner_center.second - inner_b));
390  const size_t max_row(max(outer_center.second + outer_b,
391  inner_center.second + inner_b));
392 
393  const index_t outer_axis_sq(make_pair(outer_a,outer_b)*make_pair(outer_a,outer_b));
394  const index_t inner_axis_sq(make_pair(inner_a,inner_b)*make_pair(inner_a,inner_b));
395 
396  for (size_t row(min_row); row <= max_row; ++row)
397  {
398  for (size_t column(min_col); column <= max_col; ++column)
399  {
400  const index_t idx(make_pair(column,row));
401 
402  const index_t idx_sq_inner((idx - inner_center)*(idx - inner_center));
403  const indexf_t idx_tmp_inner(idx_sq_inner / inner_axis_sq);
404  const bool isNotInInner(!(idx_tmp_inner < 1));
405 
406  const index_t idx_sq_outer((idx - outer_center)*(idx - outer_center));
407  const indexf_t idx_tmp_outer(idx_sq_outer / outer_axis_sq);
408  const bool isInOuter(idx_tmp_outer < 1);
409 
410  data.mask[TwoD2OneD(idx,width)] *= !(isInOuter && isNotInInner);
411  }
412  }
413 }
414 
415 /** add a triangluar element to the mask
416  *
417  * To see whether a point is within a triangle one can use barycentric coordinates.
418  * See http://en.wikipedia.org/wiki/Barycentric_coordinates_(mathematics) for
419  * details. A point within barycentric can be defined by converting to these
420  * coordinates. The bayrocentric coordinates are represented by three points
421  * A, B, C. Each point can be represented by
422  * \f$ \vec{P} = \lambda_1\vec{A} + \lambda_2\vec{B} + \lambda_3\vec{C}\f$
423  * where \f$ \lambda_1, \lambda_2, \lambda_3\f$ can be determined from
424  * \f$ \vec{P} \f$ using the components of the triangle points and the wanted point
425  * \f$ \vec{P} = (x,y) ; \vec{A} = (x_1,y_1); \vec{B} = (x_2,y_2); \vec{C} = (x_3,y_3)\f$
426  * with these definition the following equalities are given:
427  * \f{eqnarray*}{
428  * \lambda_1&=&\frac{(y_2-y_3)(x-x_3)+(x_3-x_2)(y-y_3)}{(y_2-y_3)(x_1-x_3)+(x_3-x_2)(y_1-y_3)}\\
429  * \lambda_2&=&\frac{(y_3-y_1)(x-x_3)+(x_1-x_3)(y-y_3)}{(y_2-y_3)(x_1-x_3)+(x_3-x_2)(y_1-y_3)}\\
430  * \lambda_3&=&1-\lambda_1-\lambda_2
431  * \f}
432  * With this we know that \f$ \vec{P} \f$ lies within the triangluar when
433  * \f[ 0 \leq \lambda_i \leq 1 \f]
434  *
435  * @cassttng PixelDetectors/\%name\%/CorrectionMaps/Mask/\%index\%/{PointA_X|PointA_Y}\n
436  * The triangles first point. Default is 500|500.
437  * @cassttng PixelDetectors/\%name\%/CorrectionMaps/Mask/\%index\%/{PointB_X|PointB_Y}\n
438  * The triangles first point. Default is 500|500.
439  * @cassttng PixelDetectors/\%name\%/CorrectionMaps/Mask/\%index\%/{PointC_X|PointC_Y}\n
440  * The triangles first point. Default is 500|500.
441  *
442  * @param data the container containing the mask where the element should be added
443  * @param s the settings element to read the mask element parameters from
444  *
445  * @author Lutz Foucar
446  */
448 {
449  const index_t A(make_pair(s.value("PointA_X",500).toUInt(),
450  s.value("PointA_Y",500).toUInt()));
451  const index_t B(make_pair(s.value("PointB_X",500).toUInt(),
452  s.value("PointB_Y",500).toUInt()));
453  const index_t C(make_pair(s.value("PointC_X",500).toUInt(),
454  s.value("PointC_Y",500).toUInt()));
455 
456  if (A == B ||
457  B == C ||
458  A == C)
459  throw invalid_argument("addTriangle(): the 3 Points "
460  "A("+toString(A.first)+","+toString(A.second)+"), "
461  "B("+toString(B.first)+","+toString(B.second)+"), "
462  "C("+toString(C.first)+","+toString(C.second)+"), "
463  "are inconsistent.");
464 
465  if (static_cast<int>(data.columns) <= A.first ||
466  static_cast<int>(data.columns) <= B.first ||
467  static_cast<int>(data.columns) <= C.first ||
468  static_cast<int>(data.rows) <= A.second ||
469  static_cast<int>(data.rows) <= B.second ||
470  static_cast<int>(data.rows) <= C.second )
471  throw out_of_range("addTriangle(): the 3 Points "
472  "A("+toString(A.first)+","+toString(A.second)+"), "
473  "B("+toString(B.first)+","+toString(B.second)+"), "
474  "C("+toString(C.first)+","+toString(C.second)+"), "
475  "are outside the the mask boundaries "+
476  toString(data.columns) +","+ toString(data.rows));
477 
478  const size_t width(data.columns);
479  const index_t::first_type minX(min(min(A.first,B.first),C.first));
480  const index_t::first_type minY(min(min(A.second,B.second),C.second));
481  const index_t::first_type maxX(max(max(A.first,B.first),C.first));
482  const index_t::first_type maxY(max(max(A.second,B.second),C.second));
483  const index_t lowerLeft(make_pair(minX,minY));
484  const index_t upperRight(make_pair(maxX,maxY));
485  const float x1(A.first);
486  const float x2(B.first);
487  const float x3(C.first);
488  const float y1(A.second);
489  const float y2(B.second);
490  const float y3(C.second);
491  const float denom( (y2-y3)*(x1-x3) + (x3-x2)*(y1-y3) );
492 
493  for (index_t::first_type row(lowerLeft.second); row <= upperRight.second; ++row)
494  {
495  for (index_t::first_type column(lowerLeft.first); column <= upperRight.first; ++column)
496  {
497  const index_t P(make_pair(column,row));
498  const float x(P.first);
499  const float y(P.second);
500 
501  const float l1( ( (y2-y3)*(x-x3) + (x3-x2)*(y-y3) ) / denom );
502  const float l2( ( (y3-y1)*(x-x3) + (x1-x3)*(y-y3) ) / denom );
503  const float l3( 1 - l1 - l2 );
504 
505  data.mask[TwoD2OneD(P,width)] *= !((0<=l1) && (l1<=1) &&
506  (0<=l2) && (l2<=1) &&
507  (0<=l3) && (l3<=1));
508  }
509  }
510 }
511 
513 {
514  map<string,std::tr1::function<void(CommonData&, CASSSettings&)> > functions;
515  functions["circle"] = &addCircle;
516  functions["circ"] = &addCircle;
517  functions["square"] = &addSquare;
518  functions["triangle"] = &addTriangle;
519  functions["ellipse"] = &addEllipse;
520  functions["ring"] = &addRing;
521 
522  /** reset the mask before creating it*/
523  fill(data.mask.begin(),data.mask.end(),1);
524  int size = s.beginReadArray("Mask");
525  for (int i = 0; i < size; ++i)
526  {
527  s.setArrayIndex(i);
528  string type(s.value("MaskElementType","Unknown").toString().toStdString());
529  if (type == "Unknown")
530  continue;
531  if (functions.find(type) == functions.end())
532  throw invalid_argument("createCASSMask(): Unknown Mask Element Type '" +type+ "'");
533  Log::add(Log::DEBUG0,"createCASSMask: add mask element type '" + type +"'");
534  functions[type](data,s);
535  }
536  s.endArray();
537 }
538 
539 }//end namespace pixeldetector
540 }//end namespace cass
pair< int, int > index_t
an index within a matrix
setArrayIndex(int i)
void addRing(CommonData &data, CASSSettings &s)
add a ring
indexf_t operator/(const indexf_t &lhs, const indexf_t &rhs)
operates devides on two indices
void addCircle(CommonData &data, CASSSettings &s)
add a circle to the mask
Settings for CASS.
Definition: cass_settings.h:30
index_t operator*(const index_t &lhs, const index_t &rhs)
operates times on two indices
index_t operator+(const index_t &lhs, const index_t &rhs)
operates a plus on two indices
STL namespace.
things written only at end of run H5Dump ProcessorSummary size
index_t OneD2TwoD(const size_t linearisedIndex, const size_t width)
convert linearised index to matrixindex
static void add(Level level, const std::string &line)
add a string to the log
Definition: log.cpp:31
index_t::first_type dot(const index_t &lhs, const index_t &rhs)
calculate the scalar product of two indices
beginReadArray(const QString &prefix)
void addTriangle(CommonData &data, CASSSettings &s)
add a triangluar element to the mask
size_t columns
the width of the maps
Definition: common_data.h:256
size_t rows
the height of the maps
Definition: common_data.h:259
contains definition of the mask of a pixeldetector
pair< float, float > indexf_t
an index within a matrix but with with floating point precision
std::string toString(const Type &t)
convert any type to a string
Definition: cass.h:63
auxiliary data[Processor]
photon wavelength A
Data used commonly for one AdvancedDetector.
Definition: common_data.h:136
value(const QString &key, const QVariant &defaultValue=QVariant()
bool operator<(const indexf_t &lhs, const indexf_t::first_type rhs)
operates less of an indices to a scalar
size_t TwoD2OneD(const index_t &matrixIndex, const size_t width)
convert matrix index to linearised index
QReadWriteLock lock
lock to synchronize read and write acces to the common data
Definition: common_data.h:253
contains the common data for one advanced pixeldetector
file contains specialized class that do the settings for cass
void addSquare(CommonData &data, CASSSettings &s)
add a square element to the mask
void createCASSMask(CommonData &data, CASSSettings &s)
create the mask
contains a logger for cass
mask_t mask
the detector mask
Definition: common_data.h:280
index_t operator-(const index_t &lhs, const index_t &rhs)
operates a minus on two indices
void addEllipse(CommonData &data, CASSSettings &s)
add a ellipsodial element to the mask