CFEL - ASG Software Suite  2.5.0
CASS
mapcreators_online.cpp
Go to the documentation of this file.
1 // Copyright (C) 2012 Lutz Foucar
2 
3 /**
4  * @file mapcreators_online.cpp contains correction map creators that work fast
5  * easy for online purposes.
6  *
7  * @author Lutz Foucar
8  */
9 
10 #include <algorithm>
11 #include <functional>
12 #include <numeric>
13 #include <cmath>
14 
15 #include <QtCore/QTime>
16 #include <QtCore/QtGlobal>
17 
18 #include "mapcreators_online.h"
19 
20 #include "cass_settings.h"
21 #include "common_data.h"
22 #include "advanced_pixeldetector.h"
23 #include "log.h"
25 
26 using namespace cass;
27 using namespace pixeldetector;
28 using namespace std;
29 using tr1::bind;
30 using tr1::placeholders::_1;
31 
32 
34 {
35  Log::add(Log::INFO,"OnlineFixedCreator::controlCalibration(): Start collecting '" +
36  toString(_nbrFrames) + "' frames for calibration");
37  _createMap = std::tr1::bind(&OnlineFixedCreator::buildAndCalc,this,_1);
38 }
39 
41 {
42  QWriteLocker lock(&_commondata->lock);
43  /** as long as there are not enough frames collected build up the specail storage */
44  if (_framecounter < _nbrFrames)
45  {
46  ++_framecounter;
47  _specialstorage.resize(frame.columns * frame.rows);
48  specialstorage_t::iterator storagePixel(_specialstorage.begin());
49  specialstorage_t::const_iterator lastStoragePixel(_specialstorage.end());
50  Detector::frame_t::const_iterator pixel(frame.data.begin()) ;
51  while(storagePixel != lastStoragePixel)
52  (*storagePixel++).push_back(*pixel++);
53  }
54  else
55  {
56  QTime t;
57  t.start();
58  Log::add(Log::INFO,"OnlineFixedCreator::buildAndCalc(): Collected '"
59  + toString(_framecounter) +
60  "' frames. Starting to generate the offset and noise map");
61  specialstorage_t::iterator storagePixels(_specialstorage.begin());
62  specialstorage_t::const_iterator lastStoragePixels(_specialstorage.end());
63  Detector::frame_t::iterator offset(_commondata->offsetMap.begin());
64  Detector::frame_t::iterator noise(_commondata->noiseMap.begin());
65  for (;storagePixels != lastStoragePixels; ++offset, ++noise, ++storagePixels)
66  {
67  /** calc noise and offset from all pixels */
68  specialstorage_t::value_type::iterator pixel(storagePixels->begin());
69  specialstorage_t::value_type::const_iterator lastPixel(storagePixels->end());
70  size_t accumulatedValues(0);
71  Detector::pixel_t tmp_offset(0.);
72  Detector::pixel_t tmp_noise(0.);
73  for(; pixel != lastPixel ; ++pixel)
74  {
75  ++accumulatedValues;
76  const Detector::pixel_t old_offset(tmp_offset);
77  tmp_offset += ((*pixel - tmp_offset) / accumulatedValues);
78  tmp_noise += ((*pixel - old_offset)*(*pixel - tmp_offset));
79  }
80  *offset = tmp_offset;
81  *noise = sqrt(tmp_noise/(accumulatedValues-1));
82  if(qFuzzyCompare(*noise,0.f))
83  {
84  cout << tmp_noise<< " "<< tmp_offset << " "<<accumulatedValues<<endl;
85  Log::add(Log::DEBUG0,"OnlineFixedCreator::buildAndCalc(): the noise of pixel '" +
86  toString(distance(_specialstorage.begin(), storagePixels))
87  + "' is 0 after the first iteration.");
88  }
89  /** calc noise and offset from pixels that do not contain photon hits */
90  pixel = storagePixels->begin();
91  accumulatedValues = 0;
92  tmp_offset = 0.;
93  tmp_noise = 0.;
94  const Detector::pixel_t maxNoise(*noise * _multiplier);
95  for(; pixel != lastPixel ; ++pixel)
96  {
97  const Detector::pixel_t pixel_wo_offset(*pixel - *offset);
98  if ((pixel_wo_offset < maxNoise))
99  {
100  ++accumulatedValues;
101  const Detector::pixel_t old_offset(tmp_offset);
102  tmp_offset += ((*pixel - tmp_offset) / accumulatedValues);
103  tmp_noise += ((*pixel - old_offset)*(*pixel - tmp_offset));
104  }
105  }
106  *offset = tmp_offset;
107  *noise = sqrt(tmp_noise/(accumulatedValues-1));
108  if(accumulatedValues == 0)
109  Log::add(Log::WARNING,"OnlineFixedCreator::buildAndCalc(): for pixel '" +
110  toString(distance(_specialstorage.begin(), storagePixels))
111  + "' did not find any pixel below the maximum Noise of '" +
112  toString(maxNoise) +"'");
113  if(qFuzzyCompare(*noise,0.f))
114  Log::add(Log::WARNING,"OnlineFixedCreator::buildAndCalc(): the noise of pixel '" +
115  toString(distance(_specialstorage.begin(), storagePixels))
116  + "' is 0.");
117  }
118  /** write the maps to file if requested and recreate the correction map.
119  * then reset everything.
120  */
121  if(_writeMaps)
122  _commondata->saveOffsetNoiseMaps();
123  _commondata->createCorMap();
124  _createMap = std::tr1::bind(&OnlineFixedCreator::doNothing,this,_1);
125  _specialstorage.clear();
126  _framecounter = 0;
127  Log::add(Log::INFO,"OnlineFixedCreator::buildAndCalc(): Done creating maps: it took " +
128  toString(t.elapsed()) + " ms.");
129  }
130 }
131 
133 {
134  string detectorname(DetectorName::fromSettings(s));
135  s.beginGroup("FixedOnlineCreator");
136  _commondata = CommonData::instance(detectorname);
137  _nbrFrames = s.value("NbrFrames",200).toUInt();
138  _framecounter = 0;
139  _writeMaps = s.value("WriteMaps",true).toBool();
140  if(s.value("StartInstantly",false).toBool())
141  {
142  Log::add(Log::INFO,"OnlineFixedCreator::loadSettings(): Start collecting '" +
143  toString(_nbrFrames) +"' frames for calibration");
144  _createMap = std::tr1::bind(&OnlineFixedCreator::buildAndCalc,this,_1);
145  }
146  else
147  _createMap = std::tr1::bind(&OnlineFixedCreator::doNothing,this,_1);
148  _multiplier = s.value("Multiplier",4).toFloat();
149  s.endGroup();
150 }
151 
152 
153 
155 {
156  Log::add(Log::INFO,"OnlineFixedCreatorCommonMode::controlCalibration(): Start collecting '" +
157  toString(_nbrFrames) + "' frames for calibration");
158  _createMap = std::tr1::bind(&OnlineFixedCreatorCommonMode::buildAndCalc,this,_1);
159 }
160 
162 {
163  QWriteLocker lock(&_commondata->lock);
164  /** as long as there are not enough frames collected build up the specail storage */
165  if (_framecounter < _nbrFrames)
166  {
167  ++_framecounter;
168  _storage.push_back(frame.data);
169  }
170  else
171  {
172  QTime t;
173  t.start();
174  Log::add(Log::INFO,"OnlineFixedCreatorCommonMode::buildAndCalc(): Collected '"
175  + toString(_framecounter) +
176  "' frames. Starting to generate the offset and noise map");
177  Detector::frame_t::iterator offset(_commondata->offsetMap.begin());
178  Detector::frame_t::const_iterator offsetEnd(_commondata->offsetMap.end());
179  Detector::frame_t::iterator noise(_commondata->noiseMap.begin());
180  size_t idx(0);
181  for (;offset != offsetEnd; ++offset, ++noise, ++idx)
182  {
183  storage_t::iterator storagePixels(_storage.begin());
184  storage_t::const_iterator lastStoragePixels(_storage.end());
185  size_t accumulatedValues(0);
186  Detector::pixel_t tmp_offset(0.);
187  Detector::pixel_t tmp_noise(0.);
188  for (;storagePixels != lastStoragePixels; ++storagePixels)
189  {
190  const Detector::pixel_t pixel((*storagePixels)[idx]);
191  ++accumulatedValues;
192  const Detector::pixel_t old_offset(tmp_offset);
193  tmp_offset += ((pixel - tmp_offset) / accumulatedValues);
194  tmp_noise += ((pixel - old_offset)*(pixel - tmp_offset));
195  }
196  *offset = tmp_offset;
197  *noise = sqrt(tmp_noise/(accumulatedValues-1));
198  if(qFuzzyCompare(*noise,0.f))
199  Log::add(Log::WARNING,"OnlineFixedCreatorCommonMode::buildAndCalc(): the noise of pixel '" +
200  toString(idx) + "' is 0 after the first iteration.");
201  /** calc noise and offset from pixels that do not contain photon hits */
202  storagePixels = _storage.begin();
203  accumulatedValues = 0;
204  tmp_offset = 0.;
205  tmp_noise = 0.;
206  const Detector::pixel_t maxNoise(*noise * _multiplier);
207  for (;storagePixels != lastStoragePixels; ++storagePixels)
208  {
209  const Detector::pixel_t pixel((*storagePixels)[idx]);
210  const Detector::pixel_t pixel_wo_offset(pixel - *offset);
211  if ((pixel_wo_offset < maxNoise))
212  {
213  ++accumulatedValues;
214  const Detector::pixel_t old_offset(tmp_offset);
215  tmp_offset += ((pixel - tmp_offset) / accumulatedValues);
216  tmp_noise += ((pixel - old_offset)*(pixel - tmp_offset));
217  }
218  }
219  *offset = tmp_offset;
220  *noise = sqrt(tmp_noise/(accumulatedValues-1));
221  if(accumulatedValues == 0)
222  Log::add(Log::WARNING,"OnlineFixedCreatorCommonMode::buildAndCalc(): for pixel '" +
223  toString(idx)
224  + "' did not find any pixel below the maximum Noise of '" +
225  toString(maxNoise) +"'");
226  if(qFuzzyCompare(*noise,0.f))
227  Log::add(Log::WARNING,"OnlineFixedCreatorCommonMode::buildAndCalc(): the noise of pixel '" +
228  toString(idx) + "' is 0.");
229  }
230  /** save the values to the map */
231  _commondata->createCorMap();
232  /** now do it again, but this time correct for the common mode level */
233  const commonmode::CalculatorBase &calcCommonMode(*_commonModeCalculator);
234  offset = _commondata->offsetMap.begin();
235  noise = _commondata->noiseMap.begin();
236  idx = 0;
237  Detector::pixel_t commonmodeLevel(0.);
238  const size_t width(calcCommonMode.width());
239  for (;offset != offsetEnd; ++offset, ++noise, ++idx)
240  {
241  storage_t::iterator storagePixels(_storage.begin());
242  storage_t::const_iterator lastStoragePixels(_storage.end());
243  size_t accumulatedValues(0);
244  Detector::pixel_t tmp_offset(0.);
245  Detector::pixel_t tmp_noise(0.);
246  const Detector::pixel_t maxNoise(*noise * _multiplier);
247  for (;storagePixels != lastStoragePixels; ++storagePixels)
248  {
249  if ((idx % width) == 0)
250  commonmodeLevel = calcCommonMode(storagePixels->begin()+idx,idx);
251  const Detector::pixel_t pixel((*storagePixels)[idx]);
252  const Detector::pixel_t pixel_wo_commonmode(pixel - commonmodeLevel);
253  const Detector::pixel_t corectedpixel(pixel_wo_commonmode - *offset);
254  if ((corectedpixel < maxNoise))
255  {
256  ++accumulatedValues;
257  const Detector::pixel_t old_offset(tmp_offset);
258  tmp_offset += ((pixel_wo_commonmode - tmp_offset) / accumulatedValues);
259  tmp_noise += ((pixel_wo_commonmode - old_offset)*(pixel_wo_commonmode - tmp_offset));
260  }
261  }
262  }
263 
264  /** write the maps to file if requested and recreate the correction map.
265  * then reset everything.
266  */
267  if(_writeMaps)
268  _commondata->saveOffsetNoiseMaps();
269  _commondata->createCorMap();
270  _createMap = std::tr1::bind(&OnlineFixedCreatorCommonMode::doNothing,this,_1);
271  _storage.clear();
272  _framecounter = 0;
273  Log::add(Log::INFO,"OnlineFixedCreatorCommonMode::buildAndCalc(): Done creating maps: it took " +
274  toString(t.elapsed()) + " ms.");
275  }
276 }
277 
279 {
280  string detectorname(DetectorName::fromSettings(s));
281  s.beginGroup("FixedOnlineCreatorCommonMode");
282  _commondata = CommonData::instance(detectorname);
283  _nbrFrames = s.value("NbrFrames",200).toUInt();
284  _framecounter = 0;
285  _writeMaps = s.value("WriteMaps",true).toBool();
286  if(s.value("StartInstantly",false).toBool())
287  {
288  Log::add(Log::INFO,"OnlineFixedCreatorTest::loadSettings(): Start collecting '" +
289  toString(_nbrFrames) +"' frames for calibration");
290  _createMap = std::tr1::bind(&OnlineFixedCreatorCommonMode::buildAndCalc,this,_1);
291  }
292  else
293  _createMap = std::tr1::bind(&OnlineFixedCreatorCommonMode::doNothing,this,_1);
294  _multiplier = s.value("Multiplier",4).toFloat();
295  string commonmodetype (s.value("CommonModeCalculationType","simpleMean").toString().toStdString());
296  _commonModeCalculator = commonmode::CalculatorBase::instance(commonmodetype);
297  _commonModeCalculator->loadSettings(s);
298  s.endGroup();
299 }
void doNothing(const Frame &)
a function that just returns and does nothing
contains base class for all common mode calculators.
Settings for CASS.
Definition: cass_settings.h:30
void controlCalibration(const std::string &unused)
start accumulating the maps
void loadSettings(CASSSettings &s)
load the settings of this creator
void loadSettings(CASSSettings &s)
load the settings of this creator
void buildAndCalc(const Frame &frame)
build up storage and then calculate the maps
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 accumulating the maps
size_t width() const
retrieve the number of pixels (or the width of calculation
uint16_t columns
how many columns
static std::string fromSettings(const CASSSettings &s)
retrieve it from the casssettings
Definition: common_data.h:47
std::string toString(const Type &t)
convert any type to a string
Definition: cass.h:63
value(const QString &key, const QVariant &defaultValue=QVariant()
static shared_pointer instance(const std::string &type)
create an instance of the requested functor
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 correction map creators that work fast easy for online purposes.
contains a logger for cass
int16_t pixel
define a pixel
Definition: hlltypes.hpp:27
void doNothing(const Frame &)
a function that just returns and does nothing
base class for all common mode calculators
void buildAndCalc(const Frame &frame)
build up storage and then calculate the maps
beginGroup(const QString &prefix)
set up how to create the noise