Pottu
Calibrator.hpp
Go to the documentation of this file.
1 
8 #ifndef H_CALIBRATOR
9 #define H_CALIBRATOR
10 
11 
12 #include "DetectorEvent.hpp"
13 #include "ContextBase.hpp"
14 #include "StageDetectorEvent.hpp"
15 
16 #include <fmt/format.h>
17 
18 #include <cstdlib>
19 #include <cstdio>
20 #include <random>
21 #include <array>
22 #include <string>
23 #include <cstdint>
24 #include <cassert>
25 #include <fstream>
26 #include <stdexcept>
27 #include <iostream>
28 #include <bitset>
29 
30 
31 
32 namespace pottu {
33 
46  class Calibrator : public StageDetectorEvent {
47  public:
48 
56  struct item_t {
58  float c0{0};
60  float c1{1};
62  float c2{0};
64  uint32_t time_correction{0};
65  };
66 
73  : _ctxh( ContextBase::getActive().createHandle("Calibrator") )
74  {}
75 
88  void readFromGainsFile( const std::string &filename ) {
89  std::fstream fsgains;
90  fsgains.open( filename, std::fstream::in );
91  if( !fsgains.is_open() ) {
92  _ctxh->logError( fmt::format("read_from_gains_file(): Couldn't open file \'{}\'!", filename ) );
93  throw std::runtime_error( "File could not be opened" );
94  }
95 
96  _ctxh->logInfo( fmt::format("Opening gains file (grain compatible) {}.", filename ) );
97 
98  unsigned int row = 0;
99  unsigned int channel;
100  double cc[3];
101  int timecorr;
102  int tmp;
103  uint32_t numImported{0};
104  std::string s_line, s_tmp;
105  std::bitset<4096> foundChannels;
106  while( !fsgains.eof() ) {
107  ++row;
108  std::getline( fsgains, s_line );
109  tmp = sscanf( s_line.c_str(), " %d = %lf %lf %lf %d", &channel, cc, cc+1, cc+2, &timecorr );
110  if( tmp == 5 ) {
111  if( channel >= _items.size() ) {
112  _ctxh->logError( fmt::format(
113  "Calibrator::readFromGainsFile():\n"
114  " Too big channel number!\n"
115  " Error on gains file \'{}\' on line {}!\n"
116  " Line: \'{}\'"
117  , filename, row, s_line ) );
118  throw std::runtime_error( "Too big channel number. Max is 4095." );
119  }
120  if( foundChannels[channel] ) {
121  _ctxh->logWarning( fmt::format("Overwriting existing gains for channel {}.", channel ) );
122  } else {
123  ++numImported;
124  foundChannels.set(channel);
125  }
126  _items[channel].c0 = cc[0];
127  _items[channel].c1 = cc[1];
128  _items[channel].c2 = cc[2];
129  _items[channel].time_correction = timecorr;
130  }
131  if( tmp != 5 && tmp != 0 && tmp != EOF ) {
132  _ctxh->logError( fmt::format(
133  "Calibrator::readFromGainsFile():\n"
134  " Error on gains file \'{}\' on line {}!\n"
135  " Line \'{}\'",
136  filename, row, s_line ) );
137  throw std::runtime_error( "Syntax error when reading gains file" );
138  }
139  }
140  _ctxh->logInfo( fmt::format("Set gains for {} unique channels.", numImported ) );
141  }
142 
143 
154  inline double getCalibratedValue( unsigned int ch, int data ) noexcept {
155  const double d_data = double(data) + _udist( _re );
156  const item_t &item = _items[ch];
157  return item.c0 + item.c1*d_data + item.c2*d_data*d_data;
158  }
159 
170  inline void fillCalibratedEnergy( DetectorEvent &event ) noexcept {
171  event.e = getCalibratedValue( event.ch, event.adc );
172  }
173 
174 
175 
186  virtual void process( std::vector<DetectorEvent> &data ) noexcept {
187  auto proci = _ctxh->processInstance();
188 
189  for( auto &event : data ) {
190  const double d_data = double(event.adc) + _udist( _re );
191  const item_t &item = _items[event.ch];
192  event.e = item.c0 + item.c1*d_data + item.c2*d_data*d_data;
193  }
194  }
195 
196 
204  void setCoefficients( unsigned int ch, float c0, float c1, float c2 ) noexcept {
205  if( ch > 4095 )
206  exit(EXIT_FAILURE);
207  _items[ch].c0 = c0;
208  _items[ch].c1 = c1;
209  _items[ch].c2 = c2;
210  _items[ch].time_correction = 0;
211  }
212 
213 
214  private:
215  ContextHandle *_ctxh;
216 
217  std::array<item_t,4096> _items;
218  std::minstd_rand _re;
219  std::uniform_real_distribution<> _udist {-0.5, 0.5};
220  };
221 
222 
223 }
224 
225 
226 #endif
Pipeline stage which applies second order calibration.
Definition: Calibrator.hpp:46
void readFromGainsFile(const std::string &filename)
Reads grain-compatible gains file.
Definition: Calibrator.hpp:88
virtual void process(std::vector< DetectorEvent > &data) noexcept
Assigns calibrated energies to all events.
Definition: Calibrator.hpp:186
Calibrator()
Constructor.
Definition: Calibrator.hpp:72
double getCalibratedValue(unsigned int ch, int data) noexcept
Returns a calibrated value for a ch and adc value.
Definition: Calibrator.hpp:154
void fillCalibratedEnergy(DetectorEvent &event) noexcept
Returns a calibrated value for a detector event.
Definition: Calibrator.hpp:170
void setCoefficients(unsigned int ch, float c0, float c1, float c2) noexcept
Sets the coefficient for the channel.
Definition: Calibrator.hpp:204
Handle to context used by specific class.
Definition: ContextBase.hpp:188
Event containing event information of one daq channel.
Definition: DetectorEvent.hpp:47
Abstract baseclass for all stages which uses or modifies detector events.
Definition: StageDetectorEvent.hpp:20
Definition: mainpage.dox:6
Struct holding the calibration coefficients.
Definition: Calibrator.hpp:56
uint32_t time_correction
Time correction. Not used by Calibrator.
Definition: Calibrator.hpp:64
float c0
Offset.
Definition: Calibrator.hpp:58
float c1
First order coefficient.
Definition: Calibrator.hpp:60
float c2
Second order coefficient.
Definition: Calibrator.hpp:62
Default context for printing and collecting statistics.
Definition: ContextBase.hpp:41