CFEL - ASG Software Suite  2.5.0
CASS
image_manipulation.cpp
Go to the documentation of this file.
1 // Copyright (C) 2012, 2013 Lutz Foucar
2 
3 /**
4  * @file image_manipulation.cpp file contains processors that will manipulate
5  * 2d histograms
6  *
7  * @author Lutz Foucar
8  */
9 
10 #include <algorithm>
11 #include <tr1/functional>
12 
13 #include <QtCore/QString>
14 
15 #include "image_manipulation.h"
16 
17 #include "convenience_functions.h"
18 #include "cass_settings.h"
19 #include "log.h"
20 
21 using namespace cass;
22 using namespace std;
23 using tr1::bind;
24 using tr1::placeholders::_1;
25 using tr1::placeholders::_2;
26 using tr1::placeholders::_3;
27 using tr1::placeholders::_4;
28 using tr1::placeholders::_5;
29 
30 namespace cass
31 {
32 /** convert the index for rows and cols into the index of linareized array
33  *
34  * @return the linearized index
35  * @param col the Column index of the element
36  * @param row the Row index of the element
37  * @param nCols the number of columns in the matrix
38  */
39 size_t toLinearized(size_t col, size_t row, size_t nCols)
40 {
41  return (nCols*row + col);
42 }
43 
44 /** calculate the corresponding indezes for 90 deg ccw rotation
45  *
46  * convert the calculated indizes into the index of the linearized matrix and
47  * return it
48  *
49  * @return index of the src as linearized index
50  * @param destCol the column index of the destination matrix
51  * @param destRow the row index of the destination matrix
52  * @param size the size of the destination matrix
53  *
54  * @author Lutz Foucar
55  */
56 size_t Rotate90DegCCW(size_t destCol, size_t destRow, pair<size_t,size_t> size)
57 {
58  const size_t nDestCols(size.first);
59  const size_t nSrcCols(size.second);
60  const size_t srcCol(destRow);
61  const size_t srcRow(nDestCols - destCol - 1);
62  return toLinearized(srcCol,srcRow,nSrcCols);
63 }
64 
65 /** calculate the corresponding indezes for 180 deg rotation
66  *
67  * convert the calculated indizes into the index of the linearized matrix and
68  * return it
69  *
70  * @return index of the src as linearized index
71  * @param destCol the column index of the destination matrix
72  * @param destRow the row index of the destination matrix
73  * @param size the size of the destination matrix
74  *
75  * @author Lutz Foucar
76  */
77 size_t Rotate180Deg(size_t destCol, size_t destRow, pair<size_t,size_t> size)
78 {
79  const size_t nDestCols(size.first);
80  const size_t nDestRows(size.second);
81  const size_t nSrcCols(size.first);
82  const size_t srcCol(nDestCols - destCol - 1);
83  const size_t srcRow(nDestRows - destRow - 1);
84  return toLinearized(srcCol,srcRow,nSrcCols);
85 }
86 
87 /** calculate the corresponding indezes for 270 deg ccw (90 cw) rotation
88  *
89  * convert the calculated indizes into the index of the linearized matrix and
90  * return it
91  *
92  * @return index of the src as linearized index
93  * @param destCol the column index of the destination matrix
94  * @param destRow the row index of the destination matrix
95  * @param size the size of the destination matrix
96  *
97  * @author Lutz Foucar
98  */
99 size_t Rotate270DegCCW(size_t destCol, size_t destRow, pair<size_t,size_t> size)
100 {
101  const size_t nDestRows(size.second);
102  const size_t nSrcCols(size.first);
103  const size_t srcCol(nDestRows - destRow - 1);
104  const size_t srcRow(destCol);
105  return toLinearized(srcCol,srcRow,nSrcCols);
106 }
107 
108 /** transpose the indizes
109  *
110  * convert the calculated indizes into the index of the linearized matrix and
111  * return it
112  *
113  * @return index of the src as linearized index
114  * @param destCol the column index of the destination matrix
115  * @param destRow the row index of the destination matrix
116  * @param size the size of the destination matrix
117  *
118  * @author Lutz Foucar
119  */
120 size_t Transpose(size_t destCol, size_t destRow, pair<size_t,size_t> size)
121 {
122  const size_t nSrcCols(size.second);
123  const size_t srcCol(destRow);
124  const size_t srcRow(destCol);
125  return toLinearized(srcCol,srcRow,nSrcCols);
126 }
127 
128 /** flip matrix horizontally
129  *
130  * convert the calculated indizes into the index of the linearized matrix and
131  * return it
132  *
133  * @return index of the src as linearized index
134  * @param destCol the column index of the destination matrix
135  * @param destRow the row index of the destination matrix
136  * @param size the size of the destination matrix
137  *
138  * @author Lutz Foucar
139  */
140 size_t FlipHorizontal(size_t destCol, size_t destRow, pair<size_t,size_t> size)
141 {
142  const size_t nSrcCols(size.first);
143  const size_t nDestRows(size.second);
144  const size_t srcCol(destCol);
145  const size_t srcRow(nDestRows - destRow - 1);
146  return toLinearized(srcCol,srcRow,nSrcCols);
147 }
148 
149 /** flip matrix vertically
150  *
151  * convert the calculated indizes into the index of the linearized matrix and
152  * return it
153  *
154  * @return index of the src as linearized index
155  * @param destCol the column index of the destination matrix
156  * @param destRow the row index of the destination matrix
157  * @param size the size of the destination matrix
158  *
159  * @author Lutz Foucar
160  */
161 size_t FlipVertical(size_t destCol, size_t destRow, pair<size_t,size_t> size)
162 {
163  const size_t nSrcCols(size.first);
164  const size_t nDestCols(size.first);
165  const size_t srcCol(nDestCols - destCol -1);
166  const size_t srcRow(destRow);
167  return toLinearized(srcCol,srcRow,nSrcCols);
168 }
169 
170 
171 /** copy from a source matrix to a destination matrix in user wanted way
172  *
173  * a functor that will copy segments of a source matrix into the dest matrix in
174  * defined a orientation.
175  *
176  * @author Lutz Foucar
177  */
179 {
180 public:
181  /** contructor
182  *
183  * sets up the boundaries for the src and dest matrices
184  *
185  * @param srcCols the number of colums in the src matrix
186  * @param srcRows the number of rows in the src matrix
187  * @param destCols the number of columns in the dest matrix.
188  */
189  SegmentCopier(const int srcCols, const int srcRows, const int destCols)
190  : _srcCols(srcCols),
191  _srcRows(srcRows),
192  _destCols(destCols)
193  {}
194 
195  /** copy the selected segment of the src matrix to the destination matrix
196  *
197  * @param src iterator to the beginning of the linearized source matrix
198  * @param dest reference to the beginning of the linearized destination matrix
199  * @param segment the index of the segment to be copied
200  * @param destColStart dest column index where the src segment starts
201  * @param destRowStart dest row index where the src segment starts
202  * @param rot refernce to the rotor element that tells how the src segement is
203  * oriented in the dest matrix.
204  */
207  const int segment,
208  const int destColStart, const int destRowStart,
209  const Rotor &rot) const
210  {
211  int destRow = destRowStart;
212  int destCol = destColStart;
213 
214  const int srcRowStart(segment*_srcRows);
215  const int srcRowStop((segment+1)*_srcRows);
216  for (int srcRow = srcRowStart; srcRow < srcRowStop; ++srcRow)
217  {
218  destCol = (((destCol - destColStart)) % _srcCols) + destColStart;
219  destRow = (((destRow - destRowStart)) % _srcCols) + destRowStart;
220  for (int srcCol = 0; srcCol < _srcCols; ++srcCol)
221  {
222  dest[destRow*_destCols + destCol] = src[srcRow*_srcCols + srcCol];
223  destCol += rot.incDestColPerSrcCol;
224  destRow += rot.incDestRowPerSrcCol;
225  }
226  destCol += rot.incDestColPerSrcRow;
227  destRow += rot.incDestRowPerSrcRow;
228  }
229  }
230 
231 private:
232  /** the number of colums in the src matrix */
233  const int _srcCols;
234 
235  /** the number of rows that one segement in the src matrix consists of */
236  const int _srcRows;
237 
238  /** the number of columns in the dest matrix */
239  const int _destCols;
240 };
241 
242 
243 }//end namespace cass
244 
245 
246 
247 pp55::pp55(const name_t &name)
248  : Processor(name)
249 {
250  _functions["90DegCCW"] = make_pair(&cass::Rotate90DegCCW,true);
251  _functions["270DegCW"] = make_pair(&cass::Rotate90DegCCW,true);
252  _functions["180Deg"] = make_pair(&cass::Rotate180Deg,false);
253  _functions["270DegCCW"] = make_pair(&cass::Rotate270DegCCW,true);
254  _functions["90DegCW"] = make_pair(&cass::Rotate270DegCCW,true);
255  _functions["Transpose"] = make_pair(&cass::Transpose,true);
256  _functions["FlipVertical"] = make_pair(&cass::FlipVertical,true);
257  _functions["FlipHorizontal"] = make_pair(&cass::FlipHorizontal,true);
258  loadSettings(0);
259 }
260 
261 void pp55::loadSettings(size_t)
262 {
263  CASSSettings s;
264  s.beginGroup("Processor");
266  setupGeneral();
267  _one = setupDependency("ImageName");
268  bool ret (setupCondition());
269  if (!(_one && ret)) return;
270  _operation = s.value("Operation","90DegCCW").toString().toStdString();
271  if (_functions.find(_operation) == _functions.end())
272  throw invalid_argument("pp55 (" + name() +"): Operation '" + _operation +
273  "' is not supported.");
274  _pixIdx = _functions[_operation].first;
275  if (_functions[_operation].second)
276  {
277  const result_t::axe_t& xaxis(_one->result().axis(result_t::xAxis));
278  const result_t::axe_t& yaxis(_one->result().axis(result_t::yAxis));
279  _size = make_pair(_one->result().shape().second,
280  _one->result().shape().first);
281  createHistList (result_t::shared_pointer (new result_t(yaxis,xaxis)));
282  }
283  else
284  {
285  createHistList(_one->result().clone());
286  _size = _one->result().shape();
287  }
288 
289  Log::add(Log::INFO,"Processor '" + name() + "' will do '" + _operation +
290  "' on Histogram in Processor '" + _one->name() +
291  "'. Condition is '" + _condition->name() + "'");
292 }
293 
294 void pp55::process(const CASSEvent &evt, result_t &result)
295 {
296  const result_t &src(_one->result(evt.id()));
297  QReadLocker lock(&src.lock);
298 
299  result_t::iterator dest(result.begin());
300 
301  for (size_t row(0); row < _size.second; ++row)
302  for (size_t col(0); col < _size.first; ++col)
303  *dest++ = src[_pixIdx(col,row,_size)];
304 }
305 
306 
307 
308 
309 
310 // --------------convert cspad 2 cheetah--------------------
311 
312 pp1600::pp1600(const name_t &name)
313  : Processor(name),
314  _nx(194),
315  _ny(185),
316  _na(8)
317 {
318  loadSettings(0);
319 }
320 
322 {
323  CASSSettings s;
324  s.beginGroup("Processor");
326  setupGeneral();
327  _one = setupDependency("ImageName");
328  bool ret (setupCondition());
329  if (!(_one && ret)) return;
330 
333  (new result_t(_na*_nx,_na*_ny)));
334 
335  Log::add(Log::INFO,"Processor '" + name() + "' will convert Histogram in " +
336  "Processor '" + _one->name() + " into the format that cheetah is using."
337  ". Condition is '" + _condition->name() + "'");
338 }
339 
340 void pp1600::process(const CASSEvent &evt, result_t &dest)
341 {
342  // Get the input histogram
343  const result_t &src(_one->result(evt.id()));
344  QReadLocker lock(&src.lock);
345 
346  const size_t pix_per_quad(8*_ny*2*_nx);
347  for(size_t quadrant=0; quadrant<4; quadrant++)
348  {
349  for(size_t k=0; k < pix_per_quad; k++)
350  {
351  const size_t i = k % (2*_nx) + quadrant*(2*_nx);
352  const size_t j = k / (2*_nx);
353  const size_t ii = i+(_na*_nx)*j;
354  dest[ii] = src[quadrant * pix_per_quad + k];
355  }
356  }
357 }
358 
359 
360 
361 
362 
363 
364 // --------------convert cspad 2 quasi laboratory --------------------
365 
366 
367 pp1601::pp1601(const name_t &name)
368  : Processor(name),
369  _LRTB( 1, 0, 0,-1),
370  _RLBT(-1, 0, 0, 1),
371  _TBRL( 0,-1,-1, 0),
372  _BTLR( 0, 1, 1, 0),
373  _nx(194),
374  _ny(185)
375 {
376  loadSettings(0);
377 }
378 
380 {
381  CASSSettings s;
382  s.beginGroup("Processor");
384  setupGeneral();
385  _one = setupDependency("ImageName");
386  bool ret (setupCondition());
387  if (!(_one && ret)) return;
388 
391  (new result_t(2*(2*_nx+2*_ny),2*(2*_nx+2*_ny))));
392 
394  std::tr1::shared_ptr<SegmentCopier>
395  (new SegmentCopier(2*_nx, _ny, 2*(2*_nx+2*_ny)));
396 
397  Log::add(Log::INFO,"Processor '" + name() + "' will convert cspad image in " +
398  "Processor '" + _one->name() + " into a condensed real layout, " +
399  " looking from upstream."
400  ". Condition is '" + _condition->name() + "'");
401 }
402 
403 void pp1601::process(const CASSEvent &evt, result_t &dest)
404 {
405  // Get the input histogram
406  const result_t &src(_one->result(evt.id()));
407  QReadLocker lock(&src.lock);
408 
409 
410 // const size_t pix_per_seg(2*_nx*_ny);
411 // const size_t pix_per_quad(8*pix_per_seg);
412 
413 // Rotor LRBT={ 1, 0, 0, 1};
414 // Rotor LRTB={ 1, 0, 0,-1};
415 // Rotor RLBT={-1, 0, 0, 1};
416 // Rotor RLTB={-1, 0, 0,-1};
417 
418 // Rotor TBRL={ 0,-1,-1, 0};
419 // Rotor TBLR={ 0, 1,-1, 0};
420 // Rotor BTRL={ 0,-1, 1, 0};
421 // Rotor BTLR={ 0, 1, 1, 0};
422 
423  const SegmentCopier& copySegment(*_copyMatrixSegment);
424 
425  //q0//
426  copySegment(src.begin(),dest.begin(), 0, 2*_nx+0*_ny , 2*_nx+2*_ny ,_BTLR);
427  copySegment(src.begin(),dest.begin(), 0, 2*_nx+0*_ny , 2*_nx+2*_ny ,_BTLR);
428  copySegment(src.begin(),dest.begin(), 1, 2*_nx+1*_ny , 2*_nx+2*_ny ,_BTLR);
429  copySegment(src.begin(),dest.begin(), 2, 0*_nx+0*_ny , 2*_nx+4*_ny -1 ,_LRTB);
430  copySegment(src.begin(),dest.begin(), 3, 0*_nx+0*_ny , 2*_nx+3*_ny -1 ,_LRTB);
431  copySegment(src.begin(),dest.begin(), 4, 0*_nx+2*_ny -1 , 4*_nx+4*_ny -1 ,_TBRL);
432  copySegment(src.begin(),dest.begin(), 5, 0*_nx+1*_ny -1 , 4*_nx+4*_ny -1 ,_TBRL);
433  copySegment(src.begin(),dest.begin(), 6, 0*_nx+2*_ny , 4*_nx+4*_ny -1 ,_LRTB);
434  copySegment(src.begin(),dest.begin(), 7, 0*_nx+2*_ny , 4*_nx+3*_ny -1 ,_LRTB);
435 
436  //q1//
437  copySegment(src.begin(),dest.begin(), 8, 2*_nx+2*_ny , 2*_nx+4*_ny -1 ,_LRTB);
438  copySegment(src.begin(),dest.begin(), 9, 2*_nx+2*_ny , 2*_nx+3*_ny -1 ,_LRTB);
439  copySegment(src.begin(),dest.begin(),10, 2*_nx+4*_ny -1 , 4*_nx+4*_ny -1 ,_TBRL);
440  copySegment(src.begin(),dest.begin(),11, 2*_nx+3*_ny -1 , 4*_nx+4*_ny -1 ,_TBRL);
441  copySegment(src.begin(),dest.begin(),12, 4*_nx+4*_ny -1 , 4*_nx+2*_ny ,_RLBT);
442  copySegment(src.begin(),dest.begin(),13, 4*_nx+4*_ny -1 , 4*_nx+3*_ny ,_RLBT);
443  copySegment(src.begin(),dest.begin(),14, 4*_nx+4*_ny -1 , 4*_nx+2*_ny -1 ,_TBRL);
444  copySegment(src.begin(),dest.begin(),15, 4*_nx+3*_ny -1 , 4*_nx+2*_ny -1 ,_TBRL);
445 
446  //q2//
447  copySegment(src.begin(),dest.begin(),16, 2*_nx+4*_ny -1 , 2*_nx+2*_ny -1 ,_TBRL);
448  copySegment(src.begin(),dest.begin(),17, 2*_nx+3*_ny -1 , 2*_nx+2*_ny -1 ,_TBRL);
449  copySegment(src.begin(),dest.begin(),18, 4*_nx+4*_ny -1 , 2*_nx+0*_ny ,_RLBT);
450  copySegment(src.begin(),dest.begin(),19, 4*_nx+4*_ny -1 , 2*_nx+1*_ny ,_RLBT);
451  copySegment(src.begin(),dest.begin(),20, 4*_nx+2*_ny , 0*_nx+0*_ny ,_BTLR);
452  copySegment(src.begin(),dest.begin(),21, 4*_nx+3*_ny , 0*_nx+0*_ny ,_BTLR);
453  copySegment(src.begin(),dest.begin(),22, 4*_nx+2*_ny -1 , 0*_nx+0*_ny ,_RLBT);
454  copySegment(src.begin(),dest.begin(),23, 4*_nx+2*_ny -1 , 0*_nx+1*_ny ,_RLBT);
455 
456  //q3//
457  copySegment(src.begin(),dest.begin(),24, 2*_nx+2*_ny -1 , 2*_nx+0*_ny ,_RLBT);
458  copySegment(src.begin(),dest.begin(),25, 2*_nx+2*_ny -1 , 2*_nx+1*_ny ,_RLBT);
459  copySegment(src.begin(),dest.begin(),26, 2*_nx+0*_ny , 0*_nx+0*_ny ,_BTLR);
460  copySegment(src.begin(),dest.begin(),27, 2*_nx+1*_ny , 0*_nx+0*_ny ,_BTLR);
461  copySegment(src.begin(),dest.begin(),28, 0*_nx+0*_ny , 0*_nx+2*_ny -1 ,_LRTB);
462  copySegment(src.begin(),dest.begin(),29, 0*_nx+0*_ny , 0*_nx+1*_ny -1 ,_LRTB);
463  copySegment(src.begin(),dest.begin(),30, 0*_nx+0*_ny , 0*_nx+2*_ny ,_BTLR);
464  copySegment(src.begin(),dest.begin(),31, 0*_nx+1*_ny , 0*_nx+2*_ny ,_BTLR);
465 }
466 
467 
468 
469 // --------------convert cspad 2 laboratory --------------------
470 
471 pp1602::pp1602(const name_t &name)
472  : Processor(name)
473 {
474  loadSettings(0);
475 }
476 
478 {
479  CASSSettings s;
480  s.beginGroup("Processor");
482  setupGeneral();
483  _imagePP = setupDependency("ImageName");
484  bool ret (setupCondition());
485  if (!(_imagePP && ret)) return;
486 
487  _filename = s.value("GeometryFilename","cspad.geom").toString().toStdString();
488  _convertCheetahToCASSLayout = s.value("ConvertCheetahToCASSLayout",true).toBool();
489  _backgroundValue = s.value("BackgroundValue",0).toFloat();
490 
491  setup(_imagePP->result());
492 
493 }
494 
495 void pp1602::setup(const result_t &srcImageHist)
496 {
497  _lookupTable =
499  srcImageHist.size(),
500  srcImageHist.shape().first,
504  (new result_t
507 
508  Log::add(Log::INFO,"Processor '" + name() + "' will convert Histogram in " +
509  "Processor '" + _imagePP->name() + " into lab frame" +
510  ". Geometry Filename '" + _filename + "'"
511  ". convert from cheetah to cass '" + (_convertCheetahToCASSLayout?"true":"false") + "'"
512  ". Beam center is '" + toString(-_lookupTable.min.x) + " x " + toString(-_lookupTable.min.y) + "' pixels"+
513  ". Condition is '" + _condition->name() + "'");
514 }
515 
516 void pp1602::process(const CASSEvent &evt, result_t &destImage)
517 {
518  /** Get the input histogram and its memory */
519  const result_t &srcImage(_imagePP->result(evt.id()));
520  QReadLocker lock(&srcImage.lock);
521 
522  /** fill the result with the background value */
523  fill(destImage.begin(),destImage.end(),_backgroundValue);
524 
525  /** iterate through the src image and put its pixels at the location in the
526  * destination that is directed in the lookup table
527  */
528  result_t::const_iterator srcpixel(srcImage.begin());
529  result_t::const_iterator srcImageEnd(srcImage.end()-8);
530 
531  vector<size_t>::const_iterator idx(_lookupTable.lut.begin());
532 
533  for (; srcpixel != srcImageEnd; ++srcpixel, ++idx)
534  destImage[*idx] = *srcpixel;
535 
536  /** relfect that only 1 event was processed and release resources */
537 }
538 
539 
540 
541 
542 
543 
544 
545 
546 
547 
548 //************ radial average of Q values from det image ***************
549 
550 pp90::pp90(const name_t &name)
551  : Processor(name)
552 {
553  loadSettings(0);
554 }
555 
556 void pp90::loadSettings(size_t)
557 {
558  CASSSettings s;
559  s.beginGroup("Processor");
561  setupGeneral();
562  _imagePP = setupDependency("ImageName");
563  bool ret (setupCondition());
564  /** setup the method to be used */
565  string method(s.value("Output","Q").toString().toStdString());
566  if (method == "Q")
567  _getBin = std::tr1::bind(&pp90::Q,this,_1,_2,_3,_4);
568  else if (method == "Resolution")
569  _getBin = std::tr1::bind(&pp90::R,this,_1,_2,_3,_4);
570  else if (method == "Radius")
571  _getBin = std::tr1::bind(&pp90::Rad,this,_1,_2,_3,_4);
572  else
573  throw invalid_argument("pp90::loadSettings() " + name() +
574  ": requested output type '" + method + "' unknown.");
575 
576  _filename = s.value("GeometryFilename","cspad.geom").toString().toStdString();
577  _convertCheetahToCASSLayout = s.value("ConvertCheetahToCASSLayout",true).toBool();
578  _np_m = s.value("PixelSize_m",110.e-6).toDouble();
579  _badPixVal = s.value("BadPixelValue",0.f).toFloat();
580 
581  string output("Processor '" + name() + "' will generate an average " +
582  "using Output '" + method +
583  ". Geometry Filename '" + _filename + "'" +
584  ", Convert from cheetah to cass '" +
585  (_convertCheetahToCASSLayout?"true":"false") +
586  "', Pixel Size in um '" + toString(_np_m));
587 
588  if (method != "Radius")
589  {
590  /** use fixed value for wavelength if value can be converted to double,
591  * otherwise use the wavelength from the processor
592  */
593  bool wlIsDouble(false);
594  QString wlkey("Wavelength_A");
595  QString wlparam(s.value(wlkey,"1").toString());
596  double wlval(wlparam.toDouble(&wlIsDouble));
597  if (wlIsDouble)
598  {
599  _wavelength = wlval;
600  _getWavelength = std::tr1::bind(&pp90::wlFromConstant,this,_1);
601  }
602  else
603  {
604  _wavelengthPP = setupDependency(wlkey.toStdString());
605  ret = _wavelengthPP && ret;
606  _getWavelength = std::tr1::bind(&pp90::wlFromProcessor,this,_1);
607  }
608  output += (", Wavelength in Angstroem '" + wlparam.toStdString() + "'");
609 
610  /** use fixed value for detector distance if value can be converted to double,
611  * otherwise use the detector distance from the processor
612  */
613  bool ddIsDouble(false);
614  QString ddkey("DetectorDistance_m");
615  QString ddparam(s.value(ddkey,"60e-2").toString());
616  double ddval(ddparam.toDouble(&ddIsDouble));
617  if (ddIsDouble)
618  {
619  _detdist = ddval;
620  _getDetectorDistance = std::tr1::bind(&pp90::ddFromConstant,this,_1);
621  }
622  else
623  {
624  _detdistPP = setupDependency(ddkey.toStdString());
625  ret = _detdistPP && ret;
626  _getDetectorDistance = std::tr1::bind(&pp90::ddFromProcessor,this,_1);
627  }
628  output += (", Detector Distance in m '" + ddparam.toStdString() + "'");
629  }
630  /** if the method is radius, assign dummy entries (but non-zero) to the
631  * wavelength and detector distance
632  */
633  else
634  {
635  _wavelength = 1;
636  _getWavelength = std::tr1::bind(&pp90::wlFromConstant,this,_1);
637  _detdist = 1;
638  _getDetectorDistance = std::tr1::bind(&pp90::ddFromConstant,this,_1);
639  }
640 
641  if (!(_imagePP && ret)) return;
642 
643  /** check if the input processors have the correct type */
644  if (_imagePP->result().dim() != 2)
645  throw invalid_argument("pp208:loadSettings '" +name() +
646  "': input image '" + _imagePP->name() +
647  "' is not a 2d result");
648  if (method != "Radius")
649  {
650  if (_wavelengthPP && _wavelengthPP->result().dim() != 0)
651  throw invalid_argument("pp208:loadSettings '" +name() +
652  "': wavelength processor '" + _wavelengthPP->name() +
653  "' is not a 0d result");
654  if (_detdistPP && _detdistPP->result().dim() != 0)
655  throw invalid_argument("pp208:loadSettings '" +name() +
656  "': detector distance processor '" + _detdistPP->name() +
657  "' is not a 0d result");
658  }
659 
660  output += (". The operation will be done on output from Processor '" +
661  _imagePP->name() + "'");
662 
663  /** setup the pixel position map */
664  const result_t &srcImage(_imagePP->result());
666  (_filename,
667  srcImage.size(),
668  srcImage.shape().first,
670  for (size_t i(0); i < _pixPositions_m.size(); ++i)
671  {
672  _pixPositions_m[i].x *= _np_m;
673  _pixPositions_m[i].y *= _np_m;
674  }
675 
676  /** create the output histogram the storage where to put the normfactors*/
679 
680  output += (". Condition is '" + _condition->name() + "'");
681  Log::add(Log::INFO,output);
682 }
683 
685 {
686  const result_t &wavelength(_wavelengthPP->result(id));
687  QReadLocker lock(&wavelength.lock);
688  return wavelength.getValue();
689 }
690 
692 {
693  const result_t &detdist(_detdistPP->result(id));
694  QReadLocker lock(&detdist.lock);
695  return detdist.getValue();
696 }
697 
698 pp90::temp_t pp90::Q(const double lambda, const double D,
699  const result_t::value_t &pixval,
700  const GeometryInfo::pos_t &pixpos)
701 {
702  temp_t tmp;
703  // calculate the q value from the position, wavlength and distance
704  const result_t::value_t pixrad_m(sqrt(pixpos.x*pixpos.x + pixpos.y*pixpos.y));
705  const result_t::value_t Q(4.*3.1415/lambda * sin(0.5*atan(pixrad_m/D)));
706  // get the corresponding bin and set the output parameters
707  tmp.bin = histogramming::bin(_axis,Q);
708  // return when the pixel is marked to be a bad pixel
709  if(fuzzycompare(pixval,_badPixVal))
710  {
711  tmp.fill = 0;
712  tmp.weight = 0;
713  }
714  else
715  {
716  tmp.fill = 1;
717  tmp.weight = pixval;
718  }
719  return tmp;
720 }
721 
722 pp90::temp_t pp90::R(const double lambda, const double D,
723  const result_t::value_t &pixval,
724  const GeometryInfo::pos_t &pixpos)
725 {
726  temp_t tmp;
727  // calculate the crystallograher q-value from the position, wavlength and distance
728  const result_t::value_t pixrad_m(sqrt(pixpos.x*pixpos.x + pixpos.y*pixpos.y));
729  const result_t::value_t Q(2./lambda * sin(0.5*atan(pixrad_m/D)));
730  // from the q-val calculate the resolution
731  const result_t::value_t R(1./Q);
732  // get the corresponding bin and set the output parameters
733  tmp.bin = histogramming::bin(_axis,R);
734  // return when the pixel is marked to be a bad pixel
735  if(fuzzycompare(pixval,_badPixVal))
736  {
737  tmp.fill = 0;
738  tmp.weight = 0;
739  }
740  else
741  {
742  tmp.fill = 1;
743  tmp.weight = pixval;
744  }
745  return tmp;
746 }
747 
748 pp90::temp_t pp90::Rad(const double, const double,
749  const result_t::value_t &pixval,
750  const GeometryInfo::pos_t &pixpos)
751 {
752  temp_t tmp;
753  tmp.bin = histogramming::bin(_axis,sqrt(pixpos.x*pixpos.x + pixpos.y*pixpos.y));
754  // return when the pixel is marked to be a bad pixel
755  if(fuzzycompare(pixval,_badPixVal))
756  {
757  tmp.fill = 0;
758  tmp.weight = 0;
759  }
760  else
761  {
762  tmp.fill = 1;
763  tmp.weight = pixval;
764  }
765  return tmp;
766 }
767 
768 struct savedivides : std::binary_function<double,double,double>
769 {
770  double operator()(const double x, const double y)const
771  {
772  double retval = x/y;
773  if (!std::isfinite(retval))
774  retval = 0;
775  return retval;
776  }
777 };
778 
779 void pp90::process(const CASSEvent &evt, result_t &result)
780 {
781  /** Get the input histogram and its memory */
782  const result_t &srcImage(_imagePP->result(evt.id()));
783  QReadLocker lock(&(srcImage.lock));
784 
785  /** get the wavelenth and detector distance and return if they are bad */
786  const double lambda(_getWavelength(evt.id()));
787  const double D(_getDetectorDistance(evt.id()));
788  if (fuzzyIsNull(lambda) || fuzzyIsNull(D))
789  return;
790 
791  /** iterate through the src image and determine the pixels bin in the
792  * result only when they are not masked
793  */
794  const size_t imageSize(srcImage.datasize());
795  tempArray_t temparr(srcImage.datasize());
796  transform(srcImage.begin(),srcImage.begin()+imageSize,
797  _pixPositions_m.begin(),
798  temparr.begin(),
799  std::tr1::bind(_getBin,lambda,D,_1,_2));
800 
801  /** now put the weights into the correct bins and create the nomralization
802  * factors
803  */
804  normfactors_t normfactors(result.datasize(),0);
805  for (size_t i(0); i<imageSize; ++i)
806  {
807  result[temparr[i].bin] += temparr[i].weight;
808  normfactors[temparr[i].bin] += temparr[i].fill;
809  }
810 
811  /** normalize by the number of fills for each bin */
812  transform(result.begin(),result.begin()+result.datasize(),
813  normfactors.begin(),
814  result.begin(),
815  savedivides());
816 
817 // normfactors_t normfactors(result.size(),0);
818 // const double lambda(_getWavelength(evt.id()));
819 // const double D(_getDetectorDistance(evt.id()));
820 // if (fuzzyIsNull(lambda) || fuzzyIsNull(D))
821 // return;
822 // const double firstFactor(4.*3.1415/lambda);
823 // vector<tuple<size_t,float,int> > tmparr(_src2labradius.size());
824 //
825 //#ifdef _OPENMP
826 //#pragma omp for
827 //#endif
828 // for (size_t i=0; i<ImageSize; ++i)
829 // {
830 // const double Q(firstFactor * sin(0.5*atan(_src2labradius[i]*_np_m/D)));
831 // const size_t bin(histogramming::bin(result.axis(result_t::xAxis),Q));
832 // get<0>(tmparr[i]) = bin;
833 // if(fuzzycompare(srcImage[i],_badPixVal))
834 // {
835 // get<1>(tmparr[i]) = 0;
836 // get<2>(tmparr[i]) = 0;
837 // }
838 // else
839 // {
840 // get<1>(tmparr[i]) = srcImage[i];
841 // get<2>(tmparr[i]) = 1;
842 // }
843 // }
844 //
845 // for (size_t i(0); i<ImageSize; ++i)
846 // {
847 // result[get<0>(tmparr[i])] += get<1>(tmparr[i]);
848 // normfactors[get<0>(tmparr[i])] += get<2>(tmparr[i]);
849 // }
850 //
851 // /** normalize by the number of fills for each bin */
852 // transform(result.begin(),result.end(),normfactors.begin(),result.begin(),savedivides());
853 }
double _np_m
the size of one pixel in m
size_t FlipVertical(size_t destCol, size_t destRow, pair< size_t, size_t > size)
flip matrix vertically
double operator()(const double x, const double y) const
CachedList::item_type result_t
define the results
Definition: processor.h:52
storage_t::const_iterator const_iterator
a const iterator on the storage
Definition: result.hpp:338
const int _srcCols
the number of colums in the src matrix
GeometryInfo::lookupTable_t _lookupTable
the lookup table
std::string _filename
filename of the geometry file
const size_t _nx
nbr bins in x of asic
std::pair< size_t, size_t > _size
the size of the original histogram
Event to store all LCLS Data.
Definition: cass_event.h:32
virtual void createHistList(result_t::shared_pointer result)
create result list.
Definition: processor.cpp:79
bool fuzzycompare(const T &first, const T &second)
fuzzy compare two floating point variables
const_iterator end() const
retrieve iterator to the end of storage
Definition: result.hpp:632
pp1600(const name_t &)
constructor
virtual void process(const CASSEvent &evt, result_t &)
process event
pp55(const name_t &)
constructor
size_t Rotate270DegCCW(size_t destCol, size_t destRow, pair< size_t, size_t > size)
calculate the corresponding indezes for 270 deg ccw (90 cw) rotation
shared_pointer _one
pp containing 2d histogram
result_t::value_t weight
virtual void process(const CASSEvent &evt, result_t &)
process event
const name_t name() const
retrieve the name of this processor
Definition: processor.h:167
float value_t
the values of this container
Definition: result.hpp:326
result_t::axe_t _axis
the axis of the result
virtual void loadSettings(size_t unused)
load the settings of this pp
Settings for CASS.
Definition: cass_settings.h:30
const Rotor _TBRL
the rotation matrix if x of src goes from (T)op to (B)ottom in dest and y of the src goes from (R)igh...
std::tr1::shared_ptr< self_type > shared_pointer
a shared pointer of this class
Definition: result.hpp:323
double _wavelength
the wavelength in case its fixed
float _badPixVal
value of the bad pixels
std::map< std::string, std::pair< func_t, bool > > _functions
container for all functions
std::string _operation
the user chosen operation
file contains processors that will manipulate 2d histograms
size_type size() const
return the raw size of the storage
Definition: result.hpp:881
uint64_t id_t
define the id type
Definition: cass_event.h:52
func_t _pixIdx
function that will calc the corresponding bin
size_t FlipHorizontal(size_t destCol, size_t destRow, pair< size_t, size_t > size)
flip matrix horizontally
STL namespace.
size_t Rotate180Deg(size_t destCol, size_t destRow, pair< size_t, size_t > size)
calculate the corresponding indezes for 180 deg rotation
an axis of a more than 0 dimensional container
Definition: result.hpp:29
size_t bin(const Axis< AxisPrecessionType > &xaxis, const ResultValueType &value)
calculate the index of the lineared array
Definition: result.hpp:143
things written only at end of run H5Dump ProcessorSummary size
std::tr1::function< temp_t(const double, const double, const result_t::value_t &, const GeometryInfo::pos_t &)> _getBin
function to map the pixel to histogram bin, value and fill flag
double _detdist
the detector distance in case its fixed
const Rotor _LRTB
the rotation matrix if x of src goes from (L)eft to (R)ight in dest and y of the src goes from (T)op ...
SegmentCopier(const int srcCols, const int srcRows, const int destCols)
contructor
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
static void add(Level level, const std::string &line)
add a string to the log
Definition: log.cpp:31
const_iterator begin() const
retrieve a iterator for read access to beginning
Definition: result.hpp:608
std::tr1::function< double(const CASSEvent::id_t &)> _getDetectorDistance
function that gets the detectordistance
const size_t _nx
nbr bins in x of asic
fromStdString(const std::string &str)
char incDestRowPerSrcCol
steps to increase in the dest row when src column is increased by one
float _backgroundValue
the value with wich the background should be filled
temp_t Rad(const double lambda, const double D, const result_t::value_t &pixval, const GeometryInfo::pos_t &pixpos)
get the bin when the radius of the pixel is asked
bool _convertCheetahToCASSLayout
flag whether to convert the positions in the src from cheetah to cass layout
matrix rotation struct
virtual void loadSettings(size_t unused)
load the settings of this pp
shared_pointer _imagePP
pp containing 2d histogram
base class for processors.
Definition: processor.h:39
shared_pointer setupDependency(const std::string &depVarName, const name_t &name="")
setup the dependecy.
Definition: processor.cpp:114
virtual void process(const CASSEvent &evt, result_t &)
process event
temp_t R(const double lambda, const double D, const result_t::value_t &pixval, const GeometryInfo::pos_t &pixpos)
get the bin when the resolution value of the pixel is asked
const axis_t & axis() const
read access to the axis
Definition: result.hpp:449
virtual void loadSettings(size_t unused)
load the settings of this pp
define the table row of a single output
file contains declaration of classes and functions that help other processors to do their job...
size_t Rotate90DegCCW(size_t destCol, size_t destRow, pair< size_t, size_t > size)
calculate the corresponding indezes for 90 deg ccw rotation
pp90(const name_t &)
constructor
result_t::value_t fill
pp1602(const name_t &)
constructor
const size_t _ny
nbr bins in y of asic
QReadWriteLock lock
lock for locking operations on the data of the container
Definition: result.hpp:954
pp1601(const name_t &)
constructor
char incDestColPerSrcRow
steps to increase in the dest columns when src row is increased by one
std::vector< temp_t > tempArray_t
define the matrix
bool fuzzyIsNull(const T &val)
fuzzy compare a floating point number to 0
id_t & id()
setters
Definition: cass_event.h:64
GeometryInfo::conversion_t _pixPositions_m
the pixel positions
size_t toLinearized(size_t col, size_t row, size_t nCols)
convert the index for rows and cols into the index of linareized array
std::string toString(const Type &t)
convert any type to a string
Definition: cass.h:63
const int _srcRows
the number of rows that one segement in the src matrix consists of
char incDestRowPerSrcRow
steps to increase in the dest row when src row is increased by one
std::vector< result_t::value_t > normfactors_t
define the normalization factors
value(const QString &key, const QVariant &defaultValue=QVariant()
std::string _filename
filename of the geometry file
double wlFromConstant(const CASSEvent::id_t &)
retrieve the constant wavelength
void setup(const result_t &srcImageHist)
generate the lookup table by parsing the geom file
storage_t::iterator iterator
a iterator on the storage
Definition: result.hpp:335
virtual void process(const CASSEvent &evt, result_t &)
process event
void setupGeneral()
general setup of the processor
Definition: processor.cpp:85
const Rotor _RLBT
the rotation matrix if x of src goes from (R)ight to (L)eft in dest and y of the src goes from (B)ott...
std::tr1::shared_ptr< SegmentCopier > _copyMatrixSegment
void operator()(Processor::result_t::const_iterator src, Processor::result_t::iterator dest, const int segment, const int destColStart, const int destRowStart, const Rotor &rot) const
copy the selected segment of the src matrix to the destination matrix
copy from a source matrix to a destination matrix in user wanted way
virtual void loadSettings(size_t unused)
load the settings of this pp
file contains specialized class that do the settings for cass
bool _convertCheetahToCASSLayout
flag whether to convert the positions in the src from cheetah to cass layout
shared_pointer _one
pp containing 2d histogram
char incDestColPerSrcCol
steps to increase in the dest columns when src column is increased by one
const size_t _na
magic cheetah number
virtual void loadSettings(size_t)
load the settings of this pp
const int _destCols
the number of columns in the dest matrix
virtual void process(const CASSEvent &evt, result_t &)
process event
double ddFromProcessor(const CASSEvent::id_t &id)
retrieve the detector distance from the processor
shared_pointer _imagePP
pp containing 2d histogram
shared_pointer _condition
pointer to the processor that will contain the condition
Definition: processor.h:277
shared_pointer _wavelengthPP
pp containing wavelength in case its not fixed
Processor::result_t::shared_pointer set1DHist(const Processor::name_t &name)
function to set the 1d histogram properties from the ini file.
shape_t shape() const
return the shape of the result
Definition: result.hpp:811
bool setupCondition(bool defaultConditionType=true)
setup the condition.
Definition: processor.cpp:94
std::string name_t
define the name type
Definition: processor.h:46
shared_pointer _one
pp containing 2d histogram
contains a logger for cass
temp_t Q(const double lambda, const double D, const result_t::value_t &pixval, const GeometryInfo::pos_t &pixpos)
get the bin when the q-value of the pixel is asked
shared_pointer _detdistPP
pp containing detector distance in case its not fixed
std::tr1::function< double(const CASSEvent::id_t &)> _getWavelength
function that gets the wavelength
size_type datasize() const
return the size of the data as determined by the axis
Definition: result.hpp:872
double wlFromProcessor(const CASSEvent::id_t &id)
retrieve the wavelength from the processor
size_t Transpose(size_t destCol, size_t destRow, pair< size_t, size_t > size)
transpose the indizes
const size_t _ny
nbr bins in y of asic
beginGroup(const QString &prefix)
double ddFromConstant(const CASSEvent::id_t &)
retrieve the constant detector distance
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
virtual const result_t & result(const CASSEvent::id_t eventid=0)
retrieve a result for a given id.
Definition: processor.cpp:54
const Rotor _BTLR
the rotation matrix if x of src goes from (B)ottom to (T)op in dest and y of the src goes from (L)eft...