CFEL - ASG Software Suite  2.5.0
CASS
mapcreators.cpp
Go to the documentation of this file.
1 // Copyright (C) 2011 Lutz Foucar
2 
3 /**
4  * @file mapcreators.cpp contains all correction map creators.
5  *
6  * @author Lutz Foucar
7  */
8 
9 #include <algorithm>
10 #include <functional>
11 #include <numeric>
12 #include <cmath>
13 
14 #include "mapcreators.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 
27 
28 namespace cass
29 {
30 namespace pixeldetector
31 {
32 /** create the list of pixels that are non events
33  *
34  * create a list of all pixels from the storage. Exclude all
35  * pixels that might contain an event (photon or other).
36  *
37  * @param offset the offset for the pixel at index pixel
38  * @param noise the noise for the pixel at index pixel
39  * @param storage the container for all the frames data
40  * @param pixel index of the pixel that one wants to create the pixel list for.
41  * @param exclude flag to show whether to exclude the pixels that potentially
42  * a photon hit
43  * @param[out] pixellist the list of pixels the are non events
44  *
45  * @author Lutz Foucar
46  */
47 void createPixelList(const Detector::frame_t::value_type &offset,
48  const Detector::frame_t::value_type &noise,
49  const MapCreatorBase::storage_t& storage,
50  size_t pixel,
51  bool exclude,
52  Detector::frame_t &pixellist)
53 {
54  MapCreatorBase::storage_t::const_iterator frame(storage.begin());
55  MapCreatorBase::storage_t::const_iterator frameEnd(storage.end());
56  for (; frame != frameEnd ; ++frame)
57  {
58  if ((*frame)[pixel] - offset < noise || !exclude)
59  pixellist.push_back((*frame)[pixel]);
60  }
61 }
62 
63 /** calulate the standart deviation of distribution
64  *
65  * @return the standart deviation
66  * @param values the values to calc the standart deviation from the mean value
67  * @param mean the mean value to calc the standart deviation from
68  *
69  * @author Lutz Foucar
70  */
71 Detector::frame_t::value_type calcNoise(const Detector::frame_t& values, const Detector::frame_t::value_type& mean)
72 {
73  Detector::frame_t zero_mean(values);
74  transform( zero_mean.begin(), zero_mean.end(),
75  zero_mean.begin(),bind2nd( minus<Detector::frame_t::value_type>(), mean ) );
76 
77  Detector::frame_t::value_type deviation
78  (inner_product( zero_mean.begin(),zero_mean.end(), zero_mean.begin(), 0.0f ));
79  deviation = sqrt( deviation / ( values.size() - 1 ) );
80  return deviation;
81 }
82 
83 /** calculate the mean of the distribution
84  *
85  * before calulating the mean value of the distribution remove the nbr of elements
86  * that have the lowest values and the nbr of elements with the hightest values.
87  *
88  * @return the mean value
89  * @param values the values to calculate the mean from
90  * @param mindisregard the number of minimum values to disregard
91  * @param maxdisregard the number of maximum values to disregard
92  *
93  * @author Lutz Foucar
94  */
95 Detector::frame_t::value_type calcMean(Detector::frame_t& values, size_t mindisregard, size_t maxdisregard)
96 {
97  sort(values.begin(),values.end());
98  Detector::frame_t::iterator begin(values.begin());
99  Detector::frame_t::iterator end(values.end());
100  advance(begin,mindisregard);
101  advance(end,-1*(maxdisregard));
102  return (accumulate(begin,end,0) / static_cast<Detector::frame_t::value_type>(distance(begin,end)));
103 }
104 
105 /** calculate the median of the distribution
106  *
107  * before calulating the median value of the distribution remove the nbr of
108  * elements that have the lowest values and the nbr of elements with the
109  * hightest values.
110  *
111  * @return the median value
112  * @param values the values to calculate the median from
113  * @param mindisregard the number of minimum values to disregard
114  * @param maxdisregard the number of maximum values to disregard
115  *
116  * @author Lutz Foucar
117  */
118 Detector::frame_t::value_type calcMedian(Detector::frame_t& values,
119  size_t mindisregard,
120  size_t maxdisregard)
121 {
122  const int nbrElementsOfInterest
123  (values.size() - mindisregard - maxdisregard);
124  size_t median = 0.5*nbrElementsOfInterest + mindisregard;
125  nth_element(values.begin(),values.begin()+median,values.end());
126  return (values[median]);
127 }
128 }//end namespace pixeldetector
129 }//end namespace cass
130 
131 
132 
133 
134 void FixedMaps::operator ()(const Frame &frame)
135 {
136  if(!_createMaps)
137  return;
138  else
139  {
140  QWriteLocker lock(&_commondata->lock);
141  if (_storage.size() < _nbrFrames)
142  _storage.push_back(frame.data);
143  else
144  {
145  Detector::frame_t pixels;
146  Detector::frame_t::iterator offset(_commondata->offsetMap.begin());
147  Detector::frame_t::iterator offsetEnd(_commondata->offsetMap.end());
148  Detector::frame_t::iterator noise(_commondata->noiseMap.begin());
149  size_t idx(0);
150  for (;offset != offsetEnd; ++offset, ++noise, ++idx)
151  {
152  pixels.clear();
153  for (size_t i=0; i < 2; ++i)
154  {
155  createPixelList(*offset,*noise,_storage,idx,i,pixels);
156  if(!pixels.empty())
157  {
158  *offset = _calcOffset(pixels,_minDisregarded,_maxDisregarded);
159  *noise = calcNoise(pixels, *offset);
160  }
161  }
162  }
163  _createMaps = false;
164  _storage.clear();
165  _commondata->saveOffsetNoiseMaps();
166  _commondata->createCorMap();
167  }
168  }
169 }
170 
172 {
173  string detectorname(DetectorName::fromSettings(s));
174  s.beginGroup("FixedCreator");
175  _commondata = CommonData::instance(detectorname);
176  _nbrFrames = s.value("NbrFrames",200).toUInt();
177  _maxDisregarded = s.value("DisregardedHighValues",5).toUInt();
178  _minDisregarded = s.value("DisregardedLowValues",0).toUInt();
179  _createMaps = s.value("StartInstantly",false).toBool();
180  _writeMaps = s.value("WriteMaps",true).toBool();
181  if(s.value("UseMedian",false).toBool())
182  _calcOffset = &calcMedian;
183  else
184  _calcOffset = &calcMean;
185  s.endGroup();
186 }
187 
188 
189 void MovingMaps::controlCalibration(const string &/*unused*/)
190 {
191  Log::add(Log::INFO,"MovingMaps::controlCalibration(): start training by collecting '" +
192  toString(_trainingsize) + "' Frames");
193  _framecounter = 0;
194  _createMap = std::tr1::bind(&MovingMaps::train,this,_1);
195 }
196 
197 void MovingMaps::train(const Frame &frame)
198 {
199  QWriteLocker lock(&_commondata->lock);
200  if (_framecounter++ < _trainingsize)
201  {
202  _storage.push_back(frame.data);
203  }
204  else
205  {
206  Log::add(Log::INFO,"MovingMaps::train(): collected '" + toString(_framecounter) +
207  "' frames; building intial offset and noise map");
208  Detector::frame_t::iterator offset(_commondata->offsetMap.begin());
209  Detector::frame_t::iterator offsetEnd(_commondata->offsetMap.end());
210  Detector::frame_t::iterator noise(_commondata->noiseMap.begin());
211  storage_t::const_iterator storageBegin(_storage.begin());
212  storage_t::const_iterator storageEnd(_storage.end());
213  size_t pixelIdx(0);
214  for (;offset != offsetEnd; ++offset, ++noise, ++pixelIdx)
215  {
216  size_t accumulatedValues(0);
217  Detector::pixel_t tmp_offset(0.);
218  Detector::pixel_t tmp_noise(0.);
219  for (storage_t::const_iterator iFrame(storageBegin); iFrame != storageEnd ; ++iFrame)
220  {
221  Detector::pixel_t pixel((*iFrame)[pixelIdx]);
222  ++accumulatedValues;
223  const Detector::pixel_t old_offset(tmp_offset);
224  tmp_offset += ((pixel - tmp_offset) / accumulatedValues);
225  tmp_noise += ((pixel - old_offset)*(pixel - tmp_offset));
226  }
227  *offset = tmp_offset;
228  *noise = sqrt(tmp_noise/(accumulatedValues - 1));
229 
230  accumulatedValues = 0;
231  tmp_offset = 0.;
232  tmp_noise = 0.;
233  const Detector::pixel_t maxNoise(*noise * _multiplier);
234  for (storage_t::const_iterator iFrame(storageBegin); iFrame != storageEnd ; ++iFrame)
235  {
236  Detector::pixel_t pixel((*iFrame)[pixelIdx]);
237  if ((pixel - *offset < maxNoise))
238  {
239  ++accumulatedValues;
240  const Detector::pixel_t old_offset(tmp_offset);
241  tmp_offset += ((pixel - tmp_offset) / accumulatedValues);
242  tmp_noise += ((pixel - old_offset)*(pixel - tmp_offset));
243  }
244  }
245  *offset = tmp_offset;
246  *noise = sqrt(tmp_noise/(accumulatedValues - 1));
247  }
248  _commondata->saveOffsetNoiseMaps();
249  _commondata->createCorMap();
250  _createMap = std::tr1::bind(&MovingMaps::updateMaps,this,_1);
251  Log::add(Log::INFO,"MovingMaps::train(): Done training.");
252  }
253 }
254 
255 void MovingMaps::updateMaps(const Frame &frame)
256 {
257  QWriteLocker lock(&_commondata->lock);
258  Detector::frame_t::const_iterator pixel(frame.data.begin());
259  Detector::frame_t::const_iterator pixelEnd(frame.data.end());
260  Detector::frame_t::iterator offset(_commondata->offsetMap.begin());
261  Detector::frame_t::iterator noise(_commondata->noiseMap.begin());
262  for(;pixel != pixelEnd; ++pixel, ++offset, ++noise)
263  {
264 // diff := x - mean
265 // incr := alpha * diff
266 // mean := mean + incr
267 // variance := (1 - alpha) * (variance + diff * incr)
268  const Detector::pixel_t diff(*pixel - *offset);
269  const Detector::pixel_t incr(_alpha * diff);
270  *offset = *offset + incr;
271  *noise = sqrt((1 - _alpha) * (square(*noise) + (diff * incr)));
272  }
273  ++_framecounter;
274  if ((_framecounter % _frameSave) == 0)
275  {
276  _commondata->saveOffsetNoiseMaps();
277  _commondata->createCorMap();
278  }
279 }
280 
282 {
283  string detectorname(DetectorName::fromSettings(s));
284  s.beginGroup("ChangingCreator");
285  _framecounter = 0;
286  _commondata = CommonData::instance(detectorname);
287  _trainingsize = s.value("NbrTrainingFrames",50).toUInt();
288  if (s.value("DoTraining",false).toBool())
289  {
290  Log::add(Log::INFO,"MovingMaps::loadSettings(): Start collecting '" +
291  toString(_trainingsize) + "' Frames for training.");
292  _createMap = std::tr1::bind(&MovingMaps::train,this,_1);
293  }
294  else
295  _createMap = std::tr1::bind(&MovingMaps::updateMaps,this,_1);
296  _frameSave = s.value("AutoSaveSize",1e6).toUInt();
297  size_t average(s.value("NbrOfAverages", 50).toUInt());
298  _alpha = 2./static_cast<float>(average+1.);
299  _multiplier = s.value("Multiplier",4).toFloat();
300  s.endGroup();
301 }
302 
303 
305 {
306  QWriteLocker lock(&_commondata->lock);
307  Detector::frame_t::const_iterator pixel(frame.data.begin());
308  Detector::frame_t::const_iterator pixelEnd(frame.data.end());
309  Detector::frame_t::iterator offset(_commondata->offsetMap.begin());
310  Detector::frame_t::iterator cor(_commondata->correctionMap.begin());
311  CommonData::mask_t::iterator hotpix(_commondata->hotpixels.begin());
312  while(pixel != pixelEnd)
313  {
314  const Detector::pixel_t pix(*pixel++ - *offset++);
315  if (*hotpix != -1)
316  {
317  *hotpix = (_aduThreshold < pix)? ++(*hotpix) : 0;
318  if(_hotpixThreshold < *hotpix)
319  {
320  *hotpix = -1;
321  *cor = 0;
322  }
323  }
324  ++cor;
325  ++hotpix;
326  }
327 // ++_framecounter;
328 // if ((_framecounter % _frameSave) == 0)
329 // {
330 // _commondata->saveOffsetNoiseMaps();
331 // _commondata->createCorMap();
332 // }
333 }
334 
336 {
337  string detectorname(DetectorName::fromSettings(s));
338  s.beginGroup("HotPixelFinder");
339  _commondata = CommonData::instance(detectorname);
340  _aduThreshold = s.value("ADUThreshold",3000).toFloat();
341  _hotpixThreshold = s.value("NbrConsecutiveFrames",5).toInt();
342  Log::add(Log::INFO,"HitPixelsFinder::loadSettings() '" + detectorname +
343  "': Find pixels with adu above '" + toString(_aduThreshold) +
344  "' When pixel values exeeds threshold for '" + toString(_hotpixThreshold) +
345  "' consecutive frames its marked as bad.");
346  s.endGroup();
347 }
void operator()(const Frame &frame)
build map from frame
std::vector< Detector::frame_t > storage_t
the type of storage used
void loadSettings(CASSSettings &s)
load the settings of this creator
determine the particle size by the distance between the first minima of the q average[Processor]
void createPixelList(const Detector::frame_t::value_type &offset, const Detector::frame_t::value_type &noise, const MapCreatorBase::storage_t &storage, size_t pixel, bool exclude, Detector::frame_t &pixellist)
create the list of pixels that are non events
Definition: mapcreators.cpp:47
void train(const Frame &frame)
train the maps
void loadSettings(CASSSettings &s)
load the settings of this creator
Settings for CASS.
Definition: cass_settings.h:30
void controlCalibration(const std::string &unused)
start the training
STL namespace.
Detector::frame_t::value_type calcMean(Detector::frame_t &values, size_t mindisregard, size_t maxdisregard)
calculate the mean of the distribution
Definition: mapcreators.cpp:95
T square(const T &val)
multiply number by itself
Definition: cass.h:78
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 loadSettings(CASSSettings &s)
load the settings of this creator
void operator()(const Frame &frame)
build map from frame
contains all correction map creators.
std::vector< pixel_t > frame_t
a frame is a vector of pixels
Detector::frame_t::value_type calcNoise(const Detector::frame_t &values, const Detector::frame_t::value_type &mean)
calulate the standart deviation of distribution
Definition: mapcreators.cpp:71
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()
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
void updateMaps(const Frame &frame)
update the existing map with the incomming frame inforamtion
contains a logger for cass
int16_t pixel
define a pixel
Definition: hlltypes.hpp:27
beginGroup(const QString &prefix)
Detector::frame_t::value_type calcMedian(Detector::frame_t &values, size_t mindisregard, size_t maxdisregard)
calculate the median of the distribution
set up how to create the noise