FACT++  1.0
int StateMachineFeedback::HandleCalibration ( const EventImp evt)
inlineprivate

Definition at line 203 of file feedback.cc.

References __attribute__, count, end, i, Feedback::State::kCalibrated, BIAS::kNumChannels, BIAS::State::kVoltageOn, EventImp::Ptr(), Dim::SendCommandNB(), DimDescribedService::setData(), DimState::state(), t, and DimDescribedService::Update().

204  {
206  return GetCurrentState();
207 
208  const uint16_t dac = 256+512*fCalibStep; // Command value
209 
210  // Only the channels which are no spare channels are ramped
211  // Due to the shortcut, only 319 channels are ramped, so only
212  // 320 and not 319 are expected to have the correct day setting
213  if (std::count(fBiasDac.begin(), fBiasDac.end(), dac)!=319/*320*/)
214  return GetCurrentState();
215 
216  const auto rc = AverageCurrents(evt.Ptr<int16_t>(), fNumCalibRequests);
217  if (rc.first.size()==0)
218  {
219  Dim::SendCommandNB("BIAS_CONTROL/REQUEST_STATUS");
220  return GetCurrentState();
221  }
222 
223  const vector<float> &avg = rc.first;
224  const vector<float> &rms = rc.second;
225 
226  // Current through resistor R8
227  fCalibCurrentMes[fCalibStep] = avg; // [A]
229 
230  // ------------------------- Update calibration data --------------------
231 
232  struct cal_data
233  {
234  uint32_t dac;
235  float U[BIAS::kNumChannels];
236  float Iavg[BIAS::kNumChannels];
237  float Irms[BIAS::kNumChannels];
238 
239  cal_data() { memset(this, 0, sizeof(cal_data)); }
240  } __attribute__((__packed__));
241 
242  cal_data cal;
243  cal.dac = dac;
244  memcpy(cal.U, fBiasVolt.data(), BIAS::kNumChannels*sizeof(float));
245  memcpy(cal.Iavg, avg.data(), BIAS::kNumChannels*sizeof(float));
246  memcpy(cal.Irms, rms.data(), BIAS::kNumChannels*sizeof(float));
247 
250 
251  // -------------------- Start next calibration steo ---------------------
252 
253  if (++fCalibStep<6)
254  {
256  fCurrentsAvg.assign(BIAS::kNumChannels, 0);
257  fCurrentsRms.assign(BIAS::kNumChannels, 0);
258 
259  // Ramp all channels to the calibration setting except the one
260  // with a shortcut
261  vector<uint16_t> vec(BIAS::kNumChannels, uint16_t(256+512*fCalibStep));
262  vec[272] = 0;
263  Dim::SendCommandNB("BIAS_CONTROL/SET_ALL_CHANNELS_DAC", vec);
264 
265  //Dim::SendCommandNB("BIAS_CONTROL/SET_GLOBAL_DAC", uint16_t(256+512*fCalibStep));
266 
267  return GetCurrentState();
268  }
269 
270  // --------------- Calculate old style calibration ----------------------
271 
273 
274  float *pavg = fCalibration.data();
275  float *prms = fCalibration.data()+BIAS::kNumChannels;
276  float *pres = fCalibration.data()+BIAS::kNumChannels*2;
277  float *pUmes = fCalibration.data()+BIAS::kNumChannels*3;
278 
279  for (int i=0; i<BIAS::kNumChannels; i++)
280  {
281  const double I = fCalibCurrentMes[5][i]; // [A]
282  const double U = fBiasVolt[i]; // [V]
283 
284  pavg[i] = I*1e6; // [uA]
285  prms[i] = rms[i]*1e6; // [uA]
286  pres[i] = U/I; // [Ohm]
287  pUmes[i] = U; // [V]
288  }
289 
292 
293  // -------------------- New style calibration --------------------------
294 
295  fCalibDeltaI.resize(BIAS::kNumChannels);
296  fCalibR8.resize(BIAS::kNumChannels);
297 
298  // Linear regression of the values at 256+512*N for N={ 3, 4, 5 }
299  for (int i=0; i<BIAS::kNumChannels; i++)
300  {
301  // x: Idac
302  // y: Iadc
303 
304  double x = 0;
305  double y = 0;
306  double xx = 0;
307  double xy = 0;
308 
309  const int beg = 3;
310  const int end = 5;
311  const int len = end-beg+1;
312 
313  for (int j=beg; j<=end; j++)
314  {
315  const double Idac = (256+512*j)*1e-3/4096;
316 
317  x += Idac;
318  xx += Idac*Idac;
319  y += fCalibCurrentMes[j][i];
320  xy += fCalibCurrentMes[j][i]*Idac;
321  }
322 
323  const double m1 = xy - x*y / len;
324  const double m2 = xx - x*x / len;
325 
326  const double m = m2==0 ? 0 : m1/m2;
327 
328  const double t = (y - m*x) / len;
329 
330  fCalibDeltaI[i] = t; // [A]
331  fCalibR8[i] = 100/m; // [Ohm]
332  }
333 
334  vector<float> v;
335  v.reserve(BIAS::kNumChannels*2);
336  v.insert(v.end(), fCalibDeltaI.begin(), fCalibDeltaI.end());
337  v.insert(v.end(), fCalibR8.begin(), fCalibR8.end());
338 
341 
342  // ---------------------------------------------------------------------
343 
344  Info("Calibration successfully done.");
345  Dim::SendCommandNB("BIAS_CONTROL/SET_ZERO_VOLTAGE");
346 
348  }
DimDescribedState fDimBias
Definition: feedback.cc:38
int GetCurrentState() const
return the current state of the machine
int i
Definition: db_dim_client.c:21
DimDescribedService fDimCalibration2
Definition: feedback.cc:41
DimDescribedService fDimCalibration
Definition: feedback.cc:40
uint16_t fCalibStep
Definition: feedback.cc:82
vector< float > fCalibR8
Definition: feedback.cc:59
const int32_t & state() const
Definition: DimState.h:80
vector< int64_t > fCurrentsAvg
Definition: feedback.cc:49
vector< float > fCalibDeltaI
Definition: feedback.cc:58
pair< vector< float >, vector< float > > AverageCurrents(const int16_t *ptr, int n)
Definition: feedback.cc:174
uint16_t fNumCalibIgnore
Definition: feedback.cc:80
uint16_t fNumCalibRequests
Definition: feedback.cc:81
vector< uint16_t > fBiasDac
Definition: feedback.cc:55
void setData(const void *ptr, size_t sz)
vector< int64_t > fCurrentsRms
Definition: feedback.cc:50
typedef __attribute__
void SendCommandNB(const std::string &command)
Definition: Dim.h:30
double end
int count
Definition: db_dim_server.c:18
vector< float > fCalibration
Definition: feedback.cc:57
TT t
Definition: test_client.c:26
vector< float > fCalibVoltage[6]
Definition: feedback.cc:47
int Info(const std::string &str)
Definition: MessageImp.h:47
vector< float > fCalibCurrentMes[6]
Definition: feedback.cc:46
vector< float > fBiasVolt
Definition: feedback.cc:53
DimDescribedService fDimCalibrationR8
Definition: feedback.cc:42
const T * Ptr(size_t offset=0) const
Definition: EventImp.h:74

+ Here is the call graph for this function: