CFEL - ASG Software Suite  2.5.0
CASS
gaincalibration.cpp
Go to the documentation of this file.
1 // Copyright (C) 2013 Lutz Foucar
2 
3 /**
4  * @file gaincalibration.cpp contains a gain calibration functor
5  *
6  * @author Lutz Foucar
7  */
8 
9 #include <algorithm>
10 #include <functional>
11 #include <numeric>
12 #include <cmath>
13 
14 #include "gaincalibration.h"
15 
16 #include "cass_settings.h"
17 #include "common_data.h"
18 #include "advanced_pixeldetector.h"
19 #include "log.h"
20 
21 using namespace cass;
22 using namespace pixeldetector;
23 using namespace std;
24 using tr1::bind;
25 using tr1::placeholders::_1;
26 using tr1::placeholders::_2;
27 
28 
30 {
31  QWriteLocker lock (&_commondata->lock);
32 
33  ++_counter;
34  _statistics.resize(frame.data.size(),make_pair(0,0.));
35  vector<statistics_t>::iterator stat(_statistics.begin());
36  vector<statistics_t>::const_iterator statEnd(_statistics.end());
37 
38  Detector::frame_t::const_iterator pixel(frame.data.begin());
39  Detector::frame_t::const_iterator offset(_commondata->offsetMap.begin());
40 
41  /** average the common mode and offset corrected pixelvalues per pixel that
42  * lie within the given adu range
43  */
44  const commonmode::CalculatorBase &commonMode(*_commonModeCalculator);
45  const size_t length(commonMode.width());
46  const size_t parts(frame.data.size() / length);
47  size_t idx(0);
48  for (size_t part(0); part < parts; ++part)
49  {
50  const Detector::pixel_t cmode(commonMode(pixel,idx));
51  for (size_t i(0); i < length; ++i, ++stat, ++pixel, ++idx)
52  {
53  const Detector::pixel_t pixval(*pixel - *offset++ - cmode);
54 
55  if (pixval < _range.first || _range.second < pixval)
56  continue;
57 
58  double &ave((*stat).second);
59  const double N(static_cast<double>(++(*stat).first));
60  ave = ave + (pixval - ave)/N;
61  }
62  }
63 
64  /** check the median nbr of photons per pixel. Use this or the number of
65  * frames processed so far as criteria whether to generate the gain map.
66  */
67  vector<statistics_t> statcpy(_statistics);
68  const size_t medianPos(0.5*statcpy.size());
69  nth_element(statcpy.begin(),statcpy.begin() + medianPos, statcpy.end(),
70  std::tr1::bind(less<statistics_t::first_type>(),
71  std::tr1::bind<statistics_t::first_type>(&statistics_t::first,_1),
72  std::tr1::bind<statistics_t::first_type>(&statistics_t::first,_2)));
73  if (statcpy[medianPos].first < _minMedianCounts || _counter == _nFrames)
74  return;
75 
76  /** calculate the average of the average pixelvalues, disregarding pixels
77  * that have not seen enough photons in the right ADU range.
78  */
79  int count(0);
80  double ave(0);
81  stat = _statistics.begin();
82  while (stat != statEnd)
83  {
84  const statistics_t &s(*stat++);
85  if (s.first < _minPhotonCount)
86  continue;
87  ++count;
88  ave = ave + (s.second - ave)/count;
89  }
90 
91  /** assing the gain value for each pixel that has seen enough statistics.
92  * gain is calculated by formula
93  * \f$ gain = frac{average_average_pixelvalue}{average_pixelvalue} \f$
94  * If not enough photons are in the pixel, set the predefined user value
95  */
96  Detector::frame_t::iterator gain(_commondata->gain_cteMap.begin());
97  stat = _statistics.begin();
98  while (stat != statEnd)
99  {
100  const statistics_t &s(*stat++);
101  *gain++ = (s.first < _minPhotonCount) ? _constGain : ave/s.second;
102  }
103 
104  /** if requested write the gain map to file, reset the calibration */
105  if (_writeFile)
106  _commondata->saveGainMap();
107  fill(_statistics.begin(),_statistics.end(),make_pair(0,0.));
108  _createMap = std::tr1::bind(&GainCalibration::doNothing,this,_1);
109 }
110 
112 {
113  string detectorname(DetectorName::fromSettings(s));
114  s.beginGroup("GainFixedADURange");
115  _commondata = CommonData::instance(detectorname);
116  _minPhotonCount = s.value("MinimumPhotonCount",50).toInt();
117  _minMedianCounts = s.value("MinimumMedianCounts",200).toInt();
118  _range = make_pair(s.value("MinADURange",0).toUInt(),
119  s.value("MaxADURange",1000).toUInt());
120  _writeFile = s.value("SaveCalibration",true).toBool();
121  _counter = 0;
122  _nFrames = s.value("NbrFrames",-1).toInt();
123  if (s.value("StartInstantly",false).toBool())
124  _createMap = std::tr1::bind(&GainCalibration::generateCalibration,this,_1);
125  else
126  _createMap = std::tr1::bind(&GainCalibration::doNothing,this,_1);
127  string commonmodetype (s.value("CommonModeCalculationType","none").toString().toStdString());
128  _commonModeCalculator = commonmode::CalculatorBase::instance(commonmodetype);
129  _commonModeCalculator->loadSettings(s);
130  s.endGroup();
131 }
132 
133 
134 void GainCalibration::controlCalibration(const string &/*unused*/)
135 {
136  Log::add(Log::INFO,"GainCalibration::controlCalibration(): start collecting statistics for gain calibration'");
137  _counter=0;
138  _createMap = std::tr1::bind(&GainCalibration::generateCalibration,this,_1);
139 }
140 
std::pair< int, double > statistics_t
define a conatiner for a statistics of a pixel
contains a gain calibration functor
Settings for CASS.
Definition: cass_settings.h:30
void loadSettings(CASSSettings &s)
load the settings of this creator
STL namespace.
static void add(Level level, const std::string &line)
add a string to the log
Definition: log.cpp:31
float pixel_t
define a pixel of the pixel detector
void controlCalibration(const std::string &unused)
start the gain calibration
static std::string fromSettings(const CASSSettings &s)
retrieve it from the casssettings
Definition: common_data.h:47
void generateCalibration(const Frame &frame)
generate gain calibration data
value(const QString &key, const QVariant &defaultValue=QVariant()
static shared_pointer instance(const std::string &type)
create an instance of the requested functor
void doNothing(const Frame &)
a function that just returns and does nothing
A Frame of an advance Pixel Detector.
Detector::frame_t data
the frame data
contains the common data for one advanced pixeldetector
file contains specialized class that do the settings for cass
static shared_pointer instance(const instancesmap_t::key_type &detector)
static function creating instance of this.
offset
advanced pixeldetectors
contains a logger for cass
int16_t pixel
define a pixel
Definition: hlltypes.hpp:27
base class for all common mode calculators
beginGroup(const QString &prefix)