CFEL - ASG Software Suite  2.5.0
CASS
pixel_detector_calibration.cpp
Go to the documentation of this file.
1 // Copyright (C) 2013 Lutz Foucar
2 
3 /**
4  * @file pixel_detector_calibration.cpp processors that do calibrations on pixel
5  * detector data
6  *
7  * @author Lutz Foucar
8  */
9 
10 #include <QtCore/QDateTime>
11 #include <QtCore/QFile>
12 #include <QtCore/QFileInfo>
13 
14 #include <numeric>
15 #include <algorithm>
16 
18 
19 #include "cass_settings.h"
21 #include "log.h"
22 #include "convenience_functions.h"
23 
24 
25 using namespace cass;
26 using namespace std;
27 using tr1::bind;
28 using tr1::placeholders::_1;
29 using tr1::placeholders::_2;
30 using tr1::placeholders::_3;
31 using tr1::placeholders::_4;
32 using tr1::placeholders::_5;
33 
34 
35 
36 //********** offset/noise calibrations ******************
37 
38 pp330::pp330(const name_t &name)
39  : AccumulatingProcessor(name),
40  _lastwritten(0)
41 {
42  loadSettings(0);
43 }
44 
45 void pp330::loadSettings(size_t)
46 {
47  CASSSettings s;
48  s.beginGroup("Processor");
50  _image = setupDependency("RawImage");
51  setupGeneral();
52  bool ret (setupCondition());
53  if (!(_image && ret))
54  return;
55 
56  /** load parameters from the ini file */
57  _autoNoiseSNR = s.value("SNRNoiseAutoBoundaries",4).toFloat();
58  _autoNoiseSNRStat = s.value("SNRNoiseAutoBoundariesStat",4).toFloat();
59  _NoiseLowerBound = s.value("NoiseLowerBoundary",1).toFloat();
60  _NoiseUpperBound = s.value("NoiseUpperBoundary",3).toFloat();
61  _autoOffsetSNR = s.value("SNROffsetAutoBoundaries",-1).toFloat();
62  _autoOffsetSNRStat = s.value("SNROffsetAutoBoundariesStat",4).toFloat();
63  _OffsetLowerBound = s.value("OffsetLowerBoundary",-1e20).toFloat();
64  _OffsetUpperBound = s.value("OffsetUpperBoundary",1e20).toFloat();
65  _minNbrPixels = s.value("MinNbrPixels",90).toFloat()/100.f;
66  _filename = s.value("OutputFilename","NotSet").toString().toStdString();
67  _infilename = s.value("InputFilename","NotSet").toString().toStdString();
68  _write = s.value("WriteCal",true).toBool();
69  _train = s.value("Train",true).toBool();
70  _minTrainImages = s.value("NbrTrainingImages",200).toUInt();
71  _snr = s.value("SNR",4).toFloat();
72  _resetBadPixel = s.value("ResetBadPixels",false).toBool();
73  _update = s.value("UpdateCalibration",true).toBool();
74  string updateType = s.value("UpdateCalibrationType","cummulative").toString().toStdString();
75  _updatePeriod = s.value("UpdateBadPixPeriod",-1).toInt();
76  _updateWritePeriod = s.value("WritePeriod",0).toUInt();
77  _alpha = (2./(s.value("NbrOfImages",200).toFloat()+1.));
78 
79  /** set up the type of update */
80  if (updateType == "cummulative")
81  _updateStatistics = std::tr1::bind(&pp330::cummulativeUpdate,this,_1,_2,_3,_4,_5);
82  else if (updateType == "moving")
83  _updateStatistics = std::tr1::bind(&pp330::movingUpdate,this,_1,_2,_3,_4,_5);
84  else
85  throw invalid_argument("pp330::loadSettings(): '" + name() +"' updateType '" +
86  updateType + "' is unknown.");
87 
88 
89  /** reset the variables */
90  _trainstorage.clear();
91  _counter = 0;
92 
93  /** determine the offset of the output arrays from the size of the input image */
94  result_t::shape_t shape(_image->result().shape());
95  const size_t imagesize(shape.first*shape.second);
96  _meanBeginOffset = MEAN * imagesize;
97  _meanEndOffset = (MEAN + 1) * imagesize;
98  _stdvBeginOffset = STDV * imagesize;
99  _stdvEndOffset = (STDV + 1) * imagesize;
100  _bPixBeginOffset = BADPIX * imagesize;
101  _bPixEndOffset = (BADPIX + 1) * imagesize;
102  _nValBeginOffset = NVALS * imagesize;
103  _nValEndOffset = (NVALS + 1) * imagesize;
104 
107  (new result_t(shape.first,nbrOfOutputs*shape.second)));
108  loadCalibration();
109  /** in case we want updating and no calibration was loaded or the last
110  * calibration is too outdated (now - _lastwritten > _updateWritePeriod),
111  * we need to start training now
112  */
113  const uint32_t now(QDateTime::currentDateTime().toTime_t());
114  if (_update && (_updateWritePeriod <(now - _lastwritten))) _train = true;
115  const string createdAt(_lastwritten ?
116  QDateTime::fromTime_t(_lastwritten).toString("yyyyMMdd_HHmm").toStdString() :
117  "never");
118  Log::add(Log::INFO,"processor " + name() +
119  ": generates the calibration data from images contained in '" +
120  _image->name() +
121  "' autoNoiseSNR '" + toString(_autoNoiseSNR) +
122  "' autoNoiseSNRStat '" + toString(_autoNoiseSNRStat) +
123  "' NoiselowerBound '" + toString(_NoiseLowerBound) +
124  "' NoiseupperBound '" + toString(_NoiseUpperBound) +
125  "' autoOffsetSNR '" + toString(_autoOffsetSNR) +
126  "' autoOffsetSNRStat '" + toString(_autoOffsetSNRStat) +
127  "' OffsetLowerBound '" + toString(_OffsetLowerBound) +
128  "' OffsetUpperBound '" + toString(_OffsetUpperBound) +
129  "' minNbrPixels '" + toString(_minNbrPixels) +
130  "' outputfilename '" + _filename +
131  "' inputfilename '" + _infilename +
132  "'(created '" + createdAt +
133  "') write '" + (_write?"true":"false") +
134  "' train '" + (_train?"true":"false") +
135  "' nbrTrainImages '" + toString(_minTrainImages) +
136  "' SNR '" + toString(_snr) +
137  "' alpha '" + toString(_alpha) +
138  "' updateType '" + updateType +
139  "' updatebadpixperiode '" + toString(_updatePeriod) +
140  "' updatewriteperiode '" + toString(_updateWritePeriod) +
141  "'. Condition is '" + _condition->name() + "'");
142 }
143 
145 {
146  /** If offset filename is a link, try to deduce the real filename
147  * Otherwise check if file exists
148  */
149  string inname(_infilename =="NotSet"? name() + ".lnk" : _infilename);
150  QFileInfo innameInfo(QString::fromStdString(inname));
151  if (innameInfo.isSymLink())
152  {
153  if (innameInfo.exists())
154  inname = innameInfo.symLinkTarget().toStdString();
155  else
156  {
157  Log::add(Log::ERROR,"pp330::loadCalibration() '" + name() +
158  "': The given input filename '" + inname +
159  "' is a link to a non existing file. Skip loading the data!");
160  return;
161  }
162  }
163  else if(!innameInfo.exists())
164  {
165  Log::add(Log::ERROR,"pp330::loadCalibration() '"+ name() +
166  "': The given input filename '" + inname +
167  "' does not exist. Skip loading the data!");
168  return;
169  }
170  /** in case the previous was just a link set the info the real name and get
171  * the creation data
172  */
173  innameInfo.setFile(QString::fromStdString(inname));
174  _lastwritten = innameInfo.created().toTime_t();
175  /** read the data from the file */
176  Log::add(Log::VERBOSEINFO, "pp330::loadCalibration(): '" + name() +
177  "' Load Darkcal data from file '" + inname +"'");
178  ifstream in(inname.c_str(), ios::binary);
179  if (!in.is_open())
180  {
181  Log::add(Log::ERROR,"pp330::loadCalibration() '" + name() +
182  "' Could not open '" + inname + "'. Skip loading the data.");
183  return;
184  }
185  in.seekg(0,std::ios::end);
186  const size_t size(in.tellg() / 2 / sizeof(double));
187  in.seekg(0,std::ios::beg);
188  vector<double> offsets(size);
189  in.read(reinterpret_cast<char*>(&offsets[0]), size*sizeof(double));
190  vector<double> noises(size);
191  in.read(reinterpret_cast<char*>(&noises[0]), size*sizeof(double));
192  /** check if data is of the right size */
194  const size_t sizeOfImage(result.shape().first*result.shape().second/nbrOfOutputs);
195  if (size != sizeOfImage)
196  {
197  Log::add(Log::ERROR,"pp330::loadCalibration() '" + name() +
198  "' The size of the loaded data '" + toString(size) + "' in '" +
199  inname + "' does not match the size of the input image '" +
200  toString(sizeOfImage) + "'. Skip loading the data.");
201  return;
202  }
203  /** copy it to the result container */
204  result_t::iterator meanbegin(result.begin() + _meanBeginOffset);
205  copy(offsets.begin(),offsets.end(),meanbegin);
206  result_t::iterator stdvbegin(result.begin() + _stdvBeginOffset);
207  copy(noises.begin(),noises.end(),stdvbegin);
208  /** set the number of fills to the number of training images */
209  result_t::iterator nValsBegin(result.begin() + _nValBeginOffset);
210  result_t::iterator nValsEnd(result.begin() + _nValEndOffset);
211  fill(nValsBegin,nValsEnd,_minTrainImages);
212  /** set up the bad pixel map */
213  setBadPixMap();
214 }
215 
217 {
218  /** check if a proper name is given otherwise autogenerate a name from the
219  * name of the processor and the current time
220  */
222  string outname;
223  if (_filename == "NotSet")
224  outname = name() + "_" + now.toString("yyyyMMdd_HHmm").toStdString() + ".cal";
225  else
226  outname = _filename;
227 
228  /** write the calibration to the file */
229  ofstream out(outname.c_str(), ios::binary);
230  if (!out.is_open())
231  throw invalid_argument("pp330::writeCalibration(): Error opening file '" +
232  outname + "'");
233 
234  const result_t &result(*_result);
235  const size_t sizeOfImage(result.shape().first*result.shape().second/nbrOfOutputs);
236 
237  vector<double> offsets(sizeOfImage);
238  result_t::const_iterator meanbegin(result.begin() + _meanBeginOffset);
239  result_t::const_iterator meanend(result.begin() + _meanEndOffset);
240  copy(meanbegin,meanend,offsets.begin());
241  out.write(reinterpret_cast<char*>(&offsets[0]), offsets.size()*sizeof(double));
242 
243  vector<double> noises(sizeOfImage);
244  result_t::const_iterator stdvbegin(result.begin() + _stdvBeginOffset);
245  result_t::const_iterator stdvend(result.begin() + _stdvEndOffset);
246  copy(stdvbegin,stdvend,noises.begin());
247  out.write(reinterpret_cast<char*>(&noises[0]), noises.size()*sizeof(double));
248 
249  /** remember when this was written */
250  _lastwritten = now.toTime_t();
251 
252  /** if no proper filename was given, create a link to the current file
253  * with a more general filename
254  */
255  if (_filename == "NotSet")
256  {
257  string linkname(name() +".lnk");
258  if (QFile::exists(QString::fromStdString(linkname)))
259  if(!QFile::remove(QString::fromStdString(linkname)))
260  throw runtime_error("pp330::writeCalibration: '" + name() +
261  "' could not remove already existing link '" +
262  linkname + "'");
264  throw runtime_error("pp330::writeCalibration: '" + name() +
265  "' could not create a link named '"+ linkname +
266  "' that points to the outputfile '" + outname + "'");
267  }
268 }
269 
271 {
272  /** get iterators to the mean, mask, nVals and stdv values */
274  const size_t sizeOfImage(result.shape().first*result.shape().second/nbrOfOutputs);
275 
276  result_t::const_iterator meanBegin(result.begin() + _meanBeginOffset);
277  result_t::const_iterator meanEnd(result.begin() + _meanEndOffset);
278  result_t::const_iterator stdvBegin(result.begin() + _stdvBeginOffset);
279  result_t::const_iterator stdvEnd(result.begin() + _stdvEndOffset);
280  result_t::const_iterator nValsBegin(result.begin() + _nValBeginOffset);
281  result_t::iterator badPixBegin(result.begin() + _bPixBeginOffset);
282 
283  /** boundaries for bad pixels based upon the noise map */
284  float stdvLowerBound(_NoiseLowerBound);
285  float stdvUpperBound(_NoiseUpperBound);
286  if (_autoNoiseSNR > 0.f)
287  {
288  /** calculate the value boundaries for bad pixels from the statistics of
289  * the stdv values remove outliers when calculating the mean and stdv */
291  stat.addDistribution(stdvBegin,stdvEnd);
292  stdvLowerBound = stat.mean() - (_autoNoiseSNR * stat.stdv());
293  stdvUpperBound = stat.mean() + (_autoNoiseSNR * stat.stdv());
294  Log::add(Log::INFO,"pp330::setBadPixMap '" + name() +
295  "': The automatically determined boundaries for bad pixels based " +
296  "upon Noisemap are: low '" + toString(stdvLowerBound) + "' up '" +
297  toString(stdvUpperBound) + "'. (Center '" + toString(stat.mean()) +
298  "', Width '" + toString(stat.stdv()) + "')");
299  }
300 
301  /** boundaries for bad pixels based upon the offset map */
302  float meanLowerBound(_OffsetLowerBound);
303  float meanUpperBound(_OffsetUpperBound);
304  if (_autoOffsetSNR > 0.f)
305  {
306  /** calculate the value boundaries for bad pixels from the statistics of
307  * the stdv values */
309  stat.addDistribution(meanBegin,meanEnd);
310  meanLowerBound = stat.mean() - (_autoOffsetSNR * stat.stdv());
311  meanUpperBound = stat.mean() + (_autoOffsetSNR * stat.stdv());
312  Log::add(Log::INFO,"pp330::setBadPixMap '" + name() +
313  "': The automatically determined boundaries for bad pixels based "+
314  "upon Offsetmap are: low '" + toString(meanLowerBound) + "' up '" +
315  toString(meanUpperBound) + "'. (Center '" + toString(stat.mean()) +
316  "', Width '" + toString(stat.stdv()) + "')");
317  }
318  /** set all pixels as bad, whos noise or offset value is an outlier of the
319  * statistics of the noise values, or offset values.
320  */
321  float minpixels(_minNbrPixels*_counter);
322  for (size_t iPix=0; iPix < sizeOfImage; ++iPix)
323  {
324  bool badpix(false);
325  if (stdvBegin[iPix] < stdvLowerBound ||
326  stdvBegin[iPix] > stdvUpperBound)
327  badpix = true;
328  if (meanBegin[iPix] < meanLowerBound ||
329  meanBegin[iPix] > meanUpperBound)
330  badpix = true;
331  if (nValsBegin[iPix] < minpixels)
332  badpix = true;
333  /** set bad pixel or reset if requested */
334  if (badpix)
335  badPixBegin[iPix] = 1;
336  else if (_resetBadPixel)
337  badPixBegin[iPix] = 0;
338  }
339 }
340 
342 {
343  if (_write)
345 }
346 
347 void pp330::processCommand(string command)
348 {
349  /** if the command orders us to start the darkcal,
350  * clear all variables and start the calibration
351  */
352  if(command == "startDarkcal")
353  {
354  Log::add(Log::INFO,"pp330::processCommand: '" + name() +
355  "'starts collecting data for dark calibration");
356  _trainstorage.clear();
357  _counter = 0;
358  _train = true;
359  }
360 }
361 
363  result_t::iterator meanAr,
364  result_t::iterator stdvAr,
365  result_t::iterator nValsAr,
366  const size_t sizeOfImage)
367 {
368  for(size_t iPix(0); iPix < sizeOfImage; ++iPix)
369  {
370  const float mean(meanAr[iPix]);
371  const float stdv(stdvAr[iPix]);
372  const float pix(image[iPix]);
373 
374  /** if pixel is outlier skip pixel */
375  if(_snr * stdv < pix - mean)
376  return;
377 
378  const float nVals(nValsAr[iPix] + 1);
379  const float delta(pix - mean);
380  const float newmean(mean + (delta / nVals));
381  const float M2(stdv*stdv * (nVals-2));
382  const float newM2(M2 + delta * (pix - mean) );
383  const float newstdv((nVals < 2) ? 0 : sqrt(newM2/(nVals-1)));
384 
385  meanAr[iPix] = newmean;
386  stdvAr[iPix] = newstdv;
387  nValsAr[iPix] = nVals;
388  }
389 }
390 
392  result_t::iterator meanAr,
393  result_t::iterator stdvAr,
394  result_t::iterator nValsAr,
395  const size_t sizeOfImage)
396 {
397  for(size_t iPix(0); iPix < sizeOfImage; ++iPix)
398  {
399  const float mean(meanAr[iPix]);
400  const float stdv(stdvAr[iPix]);
401  const float pix(image[iPix]);
402  const float nVals(nValsAr[iPix] + 1);
403 
404  /** if pixel is outlier skip pixel */
405  if(_snr * stdv < pix - mean)
406  continue;
407 
408  /** update the estimate of the mean and stdv */
409  const float newmean((1-_alpha)*mean + _alpha*pix);
410  const float newstdv(sqrt(_alpha*(pix - mean)*(pix - mean) + (1.f - _alpha)*stdv*stdv));
411 
412  meanAr[iPix] = newmean;
413  stdvAr[iPix] = newstdv;
414  nValsAr[iPix] = nVals;
415  }
416 }
417 
418 void pp330::process(const CASSEvent &evt, result_t &result)
419 {
420  const result_t &image(_image->result(evt.id()));
421  const size_t sizeOfImage(image.shape().first * image.shape().second);
422 
423  result_t::iterator meanAr(result.begin() + _meanBeginOffset);
424  result_t::iterator stdvAr(result.begin() + _stdvBeginOffset);
425  result_t::iterator nValsAr(result.begin() + _nValBeginOffset);
426 
427  QReadLocker lock(&image.lock);
428 
429  if (_train || _update)
430  ++_counter;
431 
432  if (_train)
433  {
434  if (_trainstorage.size() < _minTrainImages)
435  _trainstorage.push_back(image.clone());
436  /** @note we shouldn't use else here, because in this case we need one more,
437  * but unused image to start the calibration
438  */
439  if (_trainstorage.size() == _minTrainImages)
440  {
441  Log::add(Log::INFO,"pp330::process: '" + name() +
442  "' done collecting images for darkcalibration. Calculating maps");
443  //generate the initial calibration
444  for (size_t iPix=0; iPix < sizeOfImage; ++iPix)
445  {
447  for (size_t iStore=0; iStore < _trainstorage.size(); ++iStore)
448  stat.addDatum((*(_trainstorage[iStore]))[iPix]);
449 
450  meanAr[iPix] = stat.mean();
451  stdvAr[iPix] = stat.stdv();
452  nValsAr[iPix] = stat.nbrPointsUsed();
453  }
454  /** mask bad pixels based upon the calibration */
455  setBadPixMap();
456 
457  /** write the calibration */
458  if (_write)
460  /** reset the training variables */
461  _train = false;
462  _trainstorage.clear();
463  Log::add(Log::INFO,"pp330::process: '" + name() +
464  "' done calculating maps");
465  }
466  }
467  else if (_update)
468  {
469  /** add current image to statistics of the calibration */
470  _updateStatistics(image.begin(),meanAr,stdvAr,nValsAr,sizeOfImage);
471 
472  /** update the bad pix map and the file if requested */
473  if ((_counter % _updatePeriod) == 0)
474  setBadPixMap();
475  const uint32_t now(QDateTime::currentDateTime().toTime_t());
476  if (_write && (_updateWritePeriod < (now - _lastwritten)))
478  }
479 }
480 
481 
482 
483 
484 
485 //********** gain calibrations ******************
486 
487 pp331::pp331(const name_t &name)
488  : AccumulatingProcessor(name)
489 {
490  loadSettings(0);
491 }
492 
494 {
495  CASSSettings s;
496  s.beginGroup("Processor");
498  _image = setupDependency("Image");
499  setupGeneral();
500  bool ret (setupCondition());
501  if (!(_image && ret))
502  return;
503 
504  if (_image->result().dim() != 2)
505  throw invalid_argument("pp331::loadSettings: '" + name() + "' input '" +
506  _image->name() + "' is not a 2d histogram");
507 
508  _isPnCCDNoCTE = s.value("IsPnCCDNoCTE",false).toBool();
509 
510  _counter = 0;
511  _nFrames = s.value("NbrOfFrames",-1).toInt();
512  _filename = s.value("Filename","out.cal").toString().toStdString();
513  _write = s.value("WriteCal",true).toBool();
514  _aduRange = make_pair(s.value("ADURangeLow",0).toFloat(),
515  s.value("ADURangeHigh",0).toFloat());
516  _minPhotonCount = s.value("MinimumNbrPhotons",200).toUInt();
517  _constGain = s.value("DefaultGainValue",1).toFloat();
518 
519  const result_t &image(_image->result());
520  result_t::shape_t shape(image.shape());
521  if (_isPnCCDNoCTE && (shape.first != 1024 || shape.second != 1024))
522  throw invalid_argument("pp331::loadSettings(): '" + name() +
523  "' should be a pnCCD, but cols '" +
524  toString(shape.first) + "' and rows '"
525  + toString(shape.second) +
526  "' don't indicate a pnCCD");
527 
528  _sizeOfImage = shape.first * shape.second;
532 
533  createHistList(result_t::shared_pointer(new result_t(shape.first,3*shape.second)));
534 
535  loadCalibration();
536  Log::add(Log::INFO,"processor " + name() +
537  ": generates the gain calibration from images contained in '" +
538  _image->name() + "'. Condition is '" + _condition->name() + "'");
539 }
540 
541 void pp331::processCommand(std::string command)
542 {
543  if (command == "startGain")
544  {
545 
546  }
547 }
548 
550 {
551 
552 }
553 
555 {
556  ofstream out(_filename.c_str(), ios::binary);
557  if (!out.is_open())
558  throw invalid_argument("pp331::writeCalibration(): Error opening file '" +
559  _filename + "'");
560  const result_t &image(*_result);
561  out.write(reinterpret_cast<const char*>(&image.front()), _sizeOfImage*sizeof(float));
562 }
563 
565 {
567  if (_write)
569 }
570 
572 {
573  /** calculate the average of the average pixelvalues, disregarding pixels
574  * that have not seen enough photons in the right ADU range.
575  */
576  int counter(0);
577  double average(0);
578 
579  result_t::iterator gain(gainmap.begin() + _gainOffset);
580  result_t::const_iterator count(gainmap.begin() + _countOffset);
581  result_t::const_iterator ave(gainmap.begin() + _aveOffset);
582  for (size_t i(0); i < _sizeOfImage; ++i, ++count, ++ave)
583  {
584  if (*count < _minPhotonCount)
585  continue;
586  ++counter;
587  average += (*ave - average)/counter;
588  }
589 
590  /** assining the gain value for each pixel that has seen enough statistics.
591  * gain is calculated by formula
592  * \f$ gain = frac{average_average_pixelvalue}{average_pixelvalue} \f$
593  * If not enough photons are in the pixel, set the predefined user value
594  */
595  count = gainmap.begin() + _countOffset;
596  ave = gainmap.begin() + _aveOffset;
597  for (size_t i(0); i < _sizeOfImage; ++i, ++gain, ++count, ++ave)
598  *gain = (*count < _minPhotonCount) ? _constGain : average/(*ave);
599 }
600 
601 void pp331::process(const CASSEvent &evt, result_t &result)
602 {
603  const result_t &image(_image->result(evt.id()));
604  QReadLocker lock(&image.lock);
605 
606  const size_t cols(image.shape().first);
607 
609  result_t::const_iterator ImageEnd(image.end());
610 
611  result_t::iterator gain(result.begin() + _gainOffset);
612  result_t::iterator count(result.begin()+ _countOffset);
613  result_t::iterator ave(result.begin() + _aveOffset);
614 
615  /** go though all pixels of image*/
616  for (size_t i(0); pixel != ImageEnd; ++i, ++pixel, ++gain, ++count, ++ave)
617  {
618  /** check if pixel is within the 1 photon adu range */
619  if (_aduRange.first < *pixel && *pixel < _aduRange.second)
620  {
621  /** calculate the mean pixel value */
622  *count += 1;
623  *ave += ((*pixel - *ave) / *count);
624 
625  /** set the same value as for the pixel for all pixels in the columns
626  * in the quadrant
627  */
628  if (_isPnCCDNoCTE)
629  {
630  /** find out which which column and row we're currently working on */
631  const size_t col (i % cols);
632  const size_t row (i / cols);
633  /** get pointers to the corresponding starts of the maps */
634  result_t::iterator gaincol(result.begin() + _gainOffset + col);
635  result_t::iterator countcol(result.begin()+ _countOffset + col);
636  result_t::iterator avecol(result.begin() + _aveOffset + col);
637  /** when the pixel is in the upper half of the detector advance the
638  * pointer to the upper half
639  */
640  if (row >= 512)
641  {
642  gaincol += 512*1024;
643  countcol += 512*1024;
644  avecol += 512*1024;
645  }
646 
647  const float currentgain(*gain);
648  const float currentcount(*count);
649  const float currentave(*ave);
650  for (int ii=0; ii<512; ++ii)
651  {
652  *gaincol = currentgain;
653  gaincol += 1024;
654 
655  *countcol = currentcount;
656  countcol += 1024;
657 
658  *avecol = currentave;
659  avecol += 1024;
660  }
661  }
662  }
663  }
664 
665  /** if we have reached the requested nbr of frames calculate the gain map */
666  ++_counter;
667  if (_counter % _nFrames == 0)
668  calculateGainMap(result);
669 }
670 
671 
672 
673 
674 
675 
676 
677 
678 //********** hot pixel detection ******************
679 
680 pp332::pp332(const name_t &name)
681  : AccumulatingProcessor(name)
682 {
683  loadSettings(0);
684 }
685 
687 {
688  CASSSettings s;
689  s.beginGroup("Processor");
691  _image = setupDependency("Image");
692  setupGeneral();
693  bool ret (setupCondition());
694  if (!(_image && ret))
695  return;
696 
697  _counter = 0;
698  _nFrames = s.value("NbrOfFrames",-1).toInt();
699  _filename = s.value("Filename","out.cal").toString().toStdString();
700  _write = s.value("WriteCal",true).toBool();
701  _aduRange = make_pair(s.value("ADURangeLow",0).toFloat(),
702  s.value("ADURangeUp",0).toFloat());
703  _maxConsecutiveCount = s.value("MaximumConsecutiveFrames",5).toUInt();
704  _maxADUVal = s.value("MaxADUValue",1e6).toFloat();
705 
706  const result_t &image(_image->result());
707  result_t::shape_t shape(image.shape());
708  createHistList(result_t::shared_pointer(new result_t(shape.first,2*shape.second)));
709  loadHotPixelMap();
710  Log::add(Log::INFO,"processor " + name() +
711  ": generates the hot pixel map from images contained in '" +
712  _image->name() + "'. Condition is '" + _condition->name() + "'");
713 }
714 
716 {
717  ifstream in(_filename.c_str(), ios::binary);
718  if (!in.is_open())
719  {
720  Log::add(Log::WARNING,"pp332::loadHotPixelMap: Could not open '" + _filename +
721  "'. Skipping reading the hot pixels mask.");
722  return;
723  }
724  in.seekg(0,std::ios::end);
725  const int valuesize(sizeof(mask_t));
726  const size_t size = in.tellg() / valuesize;
727  in.seekg(0,std::ios::beg);
728  vector<mask_t> hotpixmask(size);
729  in.read(reinterpret_cast<char*>(&hotpixmask.front()), size*valuesize);
730 
732 
733  const size_t sizeOfImage(result.shape().first*result.shape().second/2);
734  if (sizeOfImage != size)
735  {
736  Log::add(Log::WARNING,"pp332::loadHotPixelMap: Size of mask to load '" +
737  toString(size) + "' does not fit with size of image '" +
738  toString(sizeOfImage) + "'. Skipping reading the hot pixels mask in '" +
739  _filename +"'.");
740  return;
741  }
742  copy(hotpixmask.begin(),hotpixmask.end(),result.begin());
743 }
744 
746 {
747  ofstream out(_filename.c_str(), ios::binary);
748  if (!out.is_open())
749  throw invalid_argument("pp332::writeCalibration(): Error opening file '" +
750  _filename + "'");
751 
752  const result_t &result(*_result);
753  const size_t sizeOfImage(result.shape().first*result.shape().second/2);
754 
755  vector<mask_t> mask(sizeOfImage);
756  copy(result.begin(),result.begin()+sizeOfImage,mask.begin());
757  out.write(reinterpret_cast<char*>(&mask.front()), sizeOfImage*sizeof(mask_t));
758 }
759 
761 {
762  if (_write)
764 }
765 
766 void pp332::process(const CASSEvent &evt, result_t &result)
767 {
768  const result_t &image(_image->result(evt.id()));
769  QReadLocker lock(&image.lock);
770 
772  result_t::const_iterator ImageEnd(image.end());
773  const size_t sizeOfImage(image.shape().first * image.shape().second);
774 
775  result_t::iterator hotpix(result.begin());
776  result_t::iterator count(result.begin()+1*sizeOfImage);
777 
778  /** go though all pixels of image*/
779  for (; pixel != ImageEnd; ++pixel, ++count, ++hotpix)
780  {
781  /** check if pix is not masked as hot */
782  if (fuzzycompare(*hotpix,-1.f))
783  continue;
784 
785  /** check if pixel is within the hot pixel adu range */
786  if (_aduRange.first < *pixel && *pixel < _aduRange.second)
787  {
788  *count += 1;
789  if (_maxConsecutiveCount <= *count)
790  *hotpix = -1;
791  }
792  else
793  *count = 0;
794 
795  /** check if pixel exceeds maximum allowed adu value */
796  if (_maxADUVal < *pixel)
797  {
798  *hotpix = -1;
799  }
800  }
801 
802 // /** if we have reached the requested nbr of frames calculate the gain map */
803 // ++_counter;
804 // if (_counter % _nFrames == 0)
805 // calculateGainMap(result);
806 
807 }
808 
809 
810 
811 
812 
813 
814 
815 
816 //********** common mode background calculation ******************
817 
818 pp333::pp333(const name_t &name)
819  : Processor(name)
820 {
821  loadSettings(0);
822 }
823 
825 {
826  CASSSettings s;
827  s.beginGroup("Processor");
829  _image = setupDependency("Image");
830  setupGeneral();
831  bool ret (setupCondition());
832  if (!(_image && ret))
833  return;
834 
835  _width = s.value("Width",-1).toInt();
836  _snr = s.value("SNR",4).toFloat();
837  string calctype(s.value("CalculationType","mean").toString().toStdString());
838  if(calctype == "mean")
839  _calcCommonmode = std::tr1::bind(&pp333::meanCalc,this,_1,_2);
840  else if(calctype == "median")
841  _calcCommonmode = std::tr1::bind(&pp333::medianCalc,this,_1,_2);
842  else
843  throw invalid_argument("pp333::loadSettings() '" + name() +
844  "': Calculation type '" + calctype + "' is unkown.");
845 
846 
847 // const Histogram2DFloat &image(dynamic_cast<const Histogram2DFloat&>(_image->result()));
848  createHistList(_image->result().clone());
849  Log::add(Log::INFO,"processor " + name() +
850  ": generates the common mode background level of '" +
851  _image->name() + "' using calculation type '" + calctype +
852  "'. Condition is '" + _condition->name() + "'");
853 }
854 
857 {
859  stat.addDistribution(begin,end);
860  return stat.mean();
861 }
862 
865 {
867  stat.addDistribution(begin,end);
868  return stat.median();
869 }
870 
871 void pp333::process(const CASSEvent &evt, result_t &result)
872 {
873  const result_t &image(_image->result(evt.id()));
874  QReadLocker lock(&image.lock);
875 
876  /** retrieve iterators to the storages and the size of the image */
877  result_t::const_iterator imageIt(image.begin());
878  result_t::iterator resultIt(result.begin());
879  const size_t sizeOfImage(image.shape().first * image.shape().second);
880  const size_t parts(sizeOfImage / _width);
881 
882  /** go though all common mode parts of image*/
883  for (size_t part(0); part < parts; ++part)
884  {
885  /** calculate the common mode for the part */
886  result_t::const_iterator startPart_Image(imageIt + part*_width);
887  result_t::const_iterator endPart_Image(startPart_Image + _width);
888  const float commonmodeLevel(_calcCommonmode(startPart_Image,endPart_Image));
889 
890  /** fill the result part with the calculated common mode */
891  result_t::iterator startPart_Res(resultIt + part*_width);
892  result_t::iterator endPart_Res(startPart_Res + _width);
893  fill(startPart_Res, endPart_Res, commonmodeLevel);
894  }
895 }
896 
897 
898 
899 
900 
901 
902 
903 
904 //********** common mode background calculation using histogram **************
905 
906 pp334::pp334(const name_t &name)
907  : Processor(name)
908 {
909  loadSettings(0);
910 }
911 
913 {
914  CASSSettings s;
915  s.beginGroup("Processor");
917  _image = setupDependency("Image");
918  _width = s.value("Width",30).toFloat();
919  _maxDist = s.value("MaxDistance",5).toFloat();
920  _checks = s.value("EnableChecks",false).toBool();
921  setupGeneral();
922  bool ret (setupCondition());
923  if (!(_image && ret))
924  return;
925 
926  result_t::shared_pointer result(_image->result().clone());
927  if (_checks)
928  {
929  result_t::storage_t rows(64*result->shape().first);
930  result->appendRows(rows);
931  }
933  Log::add(Log::INFO,"processor " + name() +
934  ": generates the common mode background level of '" +
935  _image->name() + "' using either histogram or unbonded pixels"+
936  "'. Condition is '" + _condition->name() + "'");
937 }
938 
939 void pp334::process(const CASSEvent &evt, result_t &result)
940 {
941  const result_t &image(_image->result(evt.id()));
942  QReadLocker lock(&image.lock);
943 
944  /** define a few things for the hisogram and asics */
945  const uint32_t nAsics(64);
946  const uint32_t nAsicsPerRow(2);
947  const uint32_t nColsAsic(194);
948  const uint32_t nRowsAsic(185);
949  const uint32_t nColsInput(nAsicsPerRow*nColsAsic);
950  const float low(-60);
951  const float up(100);
952  const int32_t nBins(up-low);
953 
954  /** create list of histograms */
955  typedef vector<double> hists_t;
956  hists_t hists(nAsics*nBins,0);
957 
958  /** iterate through image */
959  for (int i(0); i < static_cast<int>(image.datasize()); ++i)
960  {
961  /** get the pixel value */
962  const result_t::value_t pixelval(image[i]);
963  /** skip pixel if it is masked */
964  if (std::abs(pixelval) < std::numeric_limits<result_t::value_t>::epsilon())
965  continue;
966  /** find out in which row of the image we're */
967  const uint16_t row(i/nColsInput);
968  /** find out where we're on the row */
969  const uint16_t colInRow(i%nColsInput);
970  /** find out on which asic of the chip we're */
971  const uint8_t asicOnChip(colInRow/nColsAsic);
972  /** find out which chip we're on */
973  const uint8_t chip(row/nRowsAsic);
974  /** calc which asic we're on */
975  const uint8_t asic(nAsicsPerRow*chip + asicOnChip);
976  /** determine the bin in which the pixels values will fall */
977  const int32_t bin(static_cast<int32_t>(nBins*(pixelval-low)/(up-low)));
978  /** check if the bin is out of bounds, if so skip it */
979  if ((bin < 0) || (nBins <= bin))
980  continue;
981  /** add the pixel to the histogram */
982  hists[(asic*nBins) + bin] += 1;
983  }
984 
985  /** determine the center of mass of the first peak in each histogram */
986  hists_t histsCMVals(nAsics,0);
987  for (uint32_t asic(0); asic<nAsics; ++asic)
988  {
989  hists_t::const_iterator histStart(hists.begin()+(asic*nBins));
990  hists_t::const_iterator histEnd(histStart+nBins);
991  hists_t::const_iterator pToMax(max_element(histStart,histEnd));
992  int bin(distance(histStart,pToMax));
993  if (((bin-_width) < 0) || ((bin+_width+1) > nBins))
994  {
995  histsCMVals[asic] = 1e6;
996  continue;
997  }
998 
999  hists_t::const_iterator peakBegin(pToMax-_width);
1000  hists_t::const_iterator peakEnd(pToMax+_width+1);
1001  const double integral(accumulate(peakBegin,peakEnd,0.));
1002  hists_t bins;
1003  bins.reserve(_width*2+1);
1004  for (int i(bin-_width); i<bin+_width+1;++i)
1005  bins.push_back(low + (i*(up-low)/nBins));
1006  hists_t weights;
1007  weights.reserve(_width*2+1);
1008  transform(peakBegin,peakEnd,bins.begin(),back_inserter(weights),
1009  multiplies<double>());
1010  const double weight(accumulate(weights.begin(),weights.end(),0.));
1011  const double com(weight/integral);
1012 
1013  histsCMVals[asic] = com;
1014  }
1015 
1016  /** go through unbonded pixels of each asic of image and calculate the mean */
1017  hists_t unbondedPixCMVals(nAsics,0);
1018  const int sizeBetweenAsics(nColsAsic);
1019  const int sizeBetweenUnbondedPixels(3696);
1020  const int sizeBetweenChips(1566);
1021  const int nUBP(19);
1022  const int nChips(32);
1023 
1024  result_t::const_iterator pointer(image.begin());
1025  for (int chip=0; chip<nChips; ++chip)
1026  {
1027  int asic(2*chip);
1028  for (int up=0; up<nUBP-1; ++up)
1029  {
1030  //cout <<"UBP'"<<up<< "', Asic'" << asic << "'(" << pointer<< ")"<<endl;
1031  unbondedPixCMVals[asic] += *pointer;
1032  pointer += sizeBetweenAsics;
1033  //cout <<"UBP'"<<up<< "', Asic'" << asic+1 << "'(" << pointer<< ")"<<endl;
1034  pointer += sizeBetweenUnbondedPixels;
1035  unbondedPixCMVals[asic+1] += *pointer;
1036  }
1037  //cout <<"UBP'"<<18<< "', Asic'" << asic << "'(" << pointer<< ")"<<endl;
1038  unbondedPixCMVals[asic] += *pointer;
1039  pointer += sizeBetweenAsics;
1040  //cout <<"UBP'"<<18<< "', Asic'" << asic+1 << "'(" << pointer<< ")"<<endl;
1041  unbondedPixCMVals[asic+1] += *pointer;
1042  pointer += sizeBetweenChips;
1043  }
1044 
1045  for (uint32_t asic(0); asic < nAsics; ++asic)
1046  {
1047  unbondedPixCMVals[asic] /= static_cast<float>(nUBP);
1048  }
1049 
1050 
1051  /** check if the maximum of the histogram is close to the mean of the unbonded
1052  * pixels, if so than the common mode is the value determined by the
1053  * histogram, otherwise its the mean value of the unbonded pixels
1054  */
1055  hists_t CMVals(nAsics,0);
1056  for (uint32_t asic(0); asic < nAsics; ++asic)
1057  {
1058  CMVals[asic] = (fabs(unbondedPixCMVals[asic]-histsCMVals[asic]) < _maxDist) ?
1059  histsCMVals[asic] : unbondedPixCMVals[asic];
1060  }
1061 
1062  /** set the pixels of the result to the determined common mode value */
1063  /** iterate through image */
1064  for (int i(0); i < static_cast<int>(image.datasize()); ++i)
1065  {
1066  /** get the pixel value of the original image*/
1067  const result_t::value_t pixelval(image[i]);
1068  /** skip pixel if it is masked */
1069  if (std::abs(pixelval) < std::numeric_limits<result_t::value_t>::epsilon())
1070  continue;
1071  /** find out in which row of the image we're */
1072  const uint16_t row(i/nColsInput);
1073  /** find out where we're on the row */
1074  const uint16_t colInRow(i%nColsInput);
1075  /** find out on which asic of the chip we're */
1076  const uint8_t asicOnChip(colInRow/nColsAsic);
1077  /** find out which chip we're on */
1078  const uint8_t chip(row/nRowsAsic);
1079  /** calc which asic we're on */
1080  const uint8_t asic(nAsicsPerRow*chip + asicOnChip);
1081  /** set the common mode value of the pixel */
1082  result[i] = CMVals[asic];
1083  }
1084 
1085  /** if the checks are enabled add them to the end of the result */
1086  if (_checks)
1087  {
1088  for (uint32_t asic(0); asic < nAsics; ++asic)
1089  {
1090  /** set the pos of the output line */
1091  result_t::storage_t::iterator res(result.begin() +
1092  image.datasize() +
1093  asic*image.shape().first);
1094  /** add the histogram */
1095  hists_t::const_iterator histStart(hists.begin()+(asic*nBins));
1096  hists_t::const_iterator histEnd(histStart+nBins);
1097  res = copy(histStart,histEnd,res);
1098  /** add the hist cm value */
1099  *res = histsCMVals[asic];
1100  ++res;
1101  /** add the unbonded pixel cm value */
1102  *res = unbondedPixCMVals[asic];
1103  ++res;
1104  /** add the used cm value */
1105  *res = CMVals[asic];
1106  }
1107  }
1108 }
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
bool _write
flag to tell whether the calibration should be written
size_t _aveOffset
offset to the average part
reference front()
retrieve reference to the first element
Definition: result.hpp:620
void appendRows(const storage_t &rows)
add row(s) to the result
Definition: result.hpp:724
float _autoNoiseSNR
the signal to noise ratio that determines the noise boundaries in case of automatically determining t...
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
char mask_t
define the output mask type
bool fuzzycompare(const T &first, const T &second)
fuzzy compare two floating point variables
pp332(const name_t &)
constructor.
const_iterator end() const
retrieve iterator to the end of storage
Definition: result.hpp:632
float _snr
the value above which outliers are removed from the distribution
pp333(const name_t &)
constructor.
std::vector< value_t > storage_t
the storage of this container
Definition: result.hpp:332
std::tr1::function< float(result_t::const_iterator, result_t::const_iterator)> _calcCommonmode
the function that calculates the commond mode level
std::string _filename
the filename that is used to save the calibration
determine the particle size by the distance between the first minima of the q average[Processor]
toString(const QString &format)
pp331(const name_t &)
constructor.
uint32_t _lastwritten
the time_t value of the last time the calibration was written
pp334(const name_t &)
constructor.
void movingUpdate(result_t::const_iterator image, result_t::iterator meanAr, result_t::iterator stdvAr, result_t::iterator nValsAr, const size_t sizeOfImage)
a moving exponential average and variance calculation
virtual void loadSettings(size_t)
load the settings of this pp
const name_t name() const
retrieve the name of this processor
Definition: processor.h:167
void loadCalibration()
write the calibration data to file
float value_t
the values of this container
Definition: result.hpp:326
int _nFrames
the number of frames after which the gain map is calculted
Settings for CASS.
Definition: cass_settings.h:30
setFile(const QString &file)
value_type mean()
retrieve the mean of the distribution without outliers
std::tr1::shared_ptr< self_type > shared_pointer
a shared pointer of this class
Definition: result.hpp:323
statistics calculator for a cummulative statistic, removes outliers
virtual void loadSettings(size_t)
load the settings of this pp
float _autoNoiseSNRStat
the signal to noise ratio that determines which values will be taken into account when automatically ...
pp330(const name_t &)
constructor.
std::pair< size_type, size_type > shape_t
define the shape of the result
Definition: result.hpp:350
bool _write
flag to tell whether the calibration should be written
float _NoiseLowerBound
the lower noise boundary when determining bad pixels
std::vector< result_t::shared_pointer > _trainstorage
the storage for the training images
STL namespace.
shared_pointer _image
the raw image
float _maxADUVal
the maximum allowed adu value
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
virtual void processCommand(std::string command)
receive commands from the gui
size_t _countOffset
offset to the counts part
statistics calculator for a median
processors that do calibrations on pixel detector data
std::string _filename
the filename that is used to save the calibration
virtual void loadSettings(size_t)
load the settings of this pp
void writeCalibration()
write the calibration data to file
size_t _bPixBeginOffset
the offset to the first point of the bad pixels array in the result
float _snr
the signal to noise ratio in case one uses the mean calculator
int _updatePeriod
the period after which the data should be autosaved
size_t _stdvBeginOffset
the offset to the first point of the stdv array in the result
bool _train
flag telling whether training is needed
fromTime_t(uint seconds)
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
virtual void process(const CASSEvent &, result_t &)
overwrite default behaviour don't do anything
size_t _minTrainImages
the minimum nbr of images necessary for training
count_type nbrPointsUsed()
retrieve the number of points used in the statistics
fromStdString(const std::string &str)
uint32_t _updateWritePeriod
the update time period in s
std::string _infilename
the filename that is used to load the calibration
virtual void process(const CASSEvent &, result_t &)
overwrite default behaviour don't do anything
ForwardIterator max_element(ForwardIterator first, ForwardIterator last)
provide own implementation of min_element to be able to compile
Definition: operations.cpp:41
virtual void process(const CASSEvent &, result_t &)
overwrite default behaviour don't do anything
shared_pointer clone() const
create a copy of the result
Definition: result.hpp:890
int _counter
counter to count how many times this has been called
base class for processors.
Definition: processor.h:39
virtual const result_t & result(const CASSEvent::id_t)
retrieve a result.
Definition: processor.h:333
shared_pointer setupDependency(const std::string &depVarName, const name_t &name="")
setup the dependecy.
Definition: processor.cpp:114
size_t _width
the number of times a pixel is high before masking it as hot pixel
float _constGain
the gain value that will be assinged to the pixel that one could not calculate the gain for ...
size_t _meanEndOffset
the offset to one beyond the last point of the mean array in the result
virtual void loadSettings(size_t)
load the settings of this pp
size_t _sizeOfImage
the size of the input image
float _minNbrPixels
minimum number of pixels in the trainig set that are part of the distribution
void calculateGainMap(result_t &gainmap)
write the calibration data to file
shared_pointer _image
the image to create the hotpixel map from
file contains declaration of classes and functions that help other processors to do their job...
size_t _counter
counter to count the total amount of images
void cummulativeUpdate(result_t::const_iterator image, result_t::iterator meanAr, result_t::iterator stdvAr, result_t::iterator nValsAr, const size_t sizeOfImage)
a cummulative average and variance calculation
void addDistribution(InputIterator first, InputIterator last)
add a number of dati to the distribution
QReadWriteLock lock
lock for locking operations on the data of the container
Definition: result.hpp:954
virtual void aboutToQuit()
write the calibrations before quitting
float meanCalc(result_t::const_iterator begin, result_t::const_iterator end)
function to calulate the common mode level as mean value
range_t _aduRange
the range of adu that indicates whether a pixel is hot
id_t & id()
setters
Definition: cass_event.h:64
float _alpha
the alpha value for the moving average and stdv
void writeHotPixelMap()
write the calibration data to file
std::string toString(const Type &t)
convert any type to a string
Definition: cass.h:63
shared_pointer _image
the image to create the hotpixel map from
bool _isPnCCDNoCTE
flag to tell whether its a pnCCD we are not interested in correction the cte
void loadCalibration()
write the calibration data to file
updateFunc_t _updateStatistics
the function that will update the statistics
size_t _nValBeginOffset
the offset to the first point of the counts array in the result
range_t _aduRange
the range of adu that indicates whether a pixel contains a photon
size_t _minPhotonCount
the number of photons that a pixel should have seen before calculating the gain
size_t _maxConsecutiveCount
the number of times a pixel is high before masking it as hot pixel
size_t _bPixEndOffset
the offset to one beyond the last point of the bad pixels array in the result
virtual void process(const CASSEvent &, result_t &)
overwrite default behaviour don't do anything
value(const QString &key, const QVariant &defaultValue=QVariant()
virtual void aboutToQuit()
write the calibrations before quitting
virtual void loadSettings(size_t)
load the settings of this pp
virtual void createHistList(result_t::shared_pointer result)
create the list of results
Definition: processor.h:348
size_t _stdvEndOffset
the offset to one beyond the last point of the stdv array in the result
void addDatum(const value_type &datum)
add a datum to the container
storage_t::iterator iterator
a iterator on the storage
Definition: result.hpp:335
contains declarations of statistic calculators
float _OffsetLowerBound
the lower offset boundary when determining bad pixels
float _NoiseUpperBound
the upper noise boundary when determining bad pixels
noise and mask[Processor]
float _autoOffsetSNR
the signal to noise ratio that determines the offset boundaries in case of automatically determining ...
void setupGeneral()
general setup of the processor
Definition: processor.cpp:85
file contains specialized class that do the settings for cass
void addDistribution(InputIterator first, InputIterator last)
add a number of dati to the distribution
int _counter
counter to count how many times this has been called
bool _update
flag to tell whether the calibration should be updated after the training has completed.
virtual void processCommand(std::string command)
react on when the gui clients tell this to start the calibration
float medianCalc(result_t::const_iterator begin, result_t::const_iterator end)
function to calulate the common mode level via the median value
void writeCalibration()
write the calibration data to file
value_type median() const
retrieve the median of the distribution
an accumulating processor
Definition: processor.h:289
float _autoOffsetSNRStat
the signal to noise ratio that determines which values will be taken into account when automatically ...
size_t _gainOffset
offset to the gain part
result_t::shared_pointer _result
the result that accumulates the events
Definition: processor.h:356
size_t _meanBeginOffset
the offset to the first point of the mean array in the result
virtual void process(const CASSEvent &, result_t &)
overwrite default behaviour don't do anything
float _maxDist
the maximum distance between the value of the unbonded pxiels and the hist
shared_pointer _condition
pointer to the processor that will contain the condition
Definition: processor.h:277
int _nFrames
the number of frames after which the gain map is calculted
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
bool _resetBadPixel
flag to tell when the bad pixel should be reset
contains a logger for cass
float _OffsetUpperBound
the upper offset boundary when determining bad pixels
int16_t pixel
define a pixel
Definition: hlltypes.hpp:27
float _width
the number of times a pixel is high before masking it as hot pixel
size_t _nValEndOffset
the offset to the first point of the counts array in the result
value_type stdv()
retrieve the standart deviation of the distribution
bool _write
flag to tell whether the calibration should be written
size_type datasize() const
return the size of the data as determined by the axis
Definition: result.hpp:872
std::string _filename
the filename that is used to save the calibration
beginGroup(const QString &prefix)
bool _checks
enable output that allow to check the parameters
shared_pointer _image
the raw image
virtual void aboutToQuit()
write the calibrations before quitting
void setBadPixMap()
set up the bad pixel map
void loadHotPixelMap()
write the calibration data to file
virtual const result_t & result(const CASSEvent::id_t eventid=0)
retrieve a result for a given id.
Definition: processor.cpp:54
shared_pointer _image
the image to create the hotpixel map from