Jpp  15.0.1-rc.2-highQE
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JHVInterpolator.hh
Go to the documentation of this file.
1 #ifndef __JCALIBRATE_JHVINTERPOLATOR__
2 #define __JCALIBRATE_JHVINTERPOLATOR__
3 
4 #include "JLang/JException.hh"
5 
6 #include "JTools/JRange.hh"
7 
8 #include "JCalibrate/JFitToT.hh"
9 
10 #include "TKey.h"
11 #include "TGraph.h"
12 #include "TGraphErrors.h"
13 #include "TMultiGraph.h"
14 #include "TAttMarker.h"
15 #include "TColor.h"
16 
17 
18 /**
19  * \author bjung
20  */
21 
22 namespace JCALIBRATE {
23 
24  using JTOOLS::JRange;
26 
27  static const std::string HVINTERPOLATOR_SUFFIX = ".HVxG";
28 
29  static const char* HVINTERPOLATOR_DATA = "HVINTERPOLATOR_DATA";
30  static const char* HVINTERPOLATOR_RESULT = "HVINTERPOLATOR_RESULT";
31 
32  /**
33  * Auxiliary data structure to store high-voltage versus gain data and interpolate the nominal high-voltage.
34  */
36  {
37  /**
38  * Constructor.
39  *
40  * \param object TMultiGraph object
41  */
42  JHVInterpolator(TMultiGraph& object) :
43  data(&object)
44  {}
45 
46 
47  /**
48  * Add point to diagram.
49  *
50  * \param HV high-voltage [V]
51  * \param gain gain value
52  * \param gainError error on gain value
53  */
54  void AddPoint(Double_t HV, Double_t gain, Double_t gainError)
55  {
56  TGraphErrors* g1 = getData();
57 
58  const Int_t N = g1->GetN();
59 
60  g1->SetPoint (N, fabs(HV), gain);
61  g1->SetPointError(N, 0.0, gainError);
62  }
63 
64 
65  /**
66  * Set point with index i.
67  *
68  * \param i index of point
69  * \param HV high-voltage [V]
70  * \param gain gain value
71  * \param gainError error on gain value
72  */
73  void SetPoint(Int_t i, Double_t HV, Double_t gain, Double_t gainError)
74  {
75  TGraphErrors* g1 = getData();
76 
77  g1->SetPoint (i, fabs(HV), gain);
78  g1->SetPointError(i, 0.0, gainError);
79  }
80 
81 
82  /**
83  * Checks whether high-voltage is within range
84  *
85  * \param HV high-voltage [V]
86  * \return true if high-voltage is within range; else false
87  */
88  const bool checkHV(const double HV) const
89  {
90  return (HV > hvRange.getLowerLimit() &&
91  HV < hvRange.getUpperLimit());
92  }
93 
94 
95  /**
96  * Checks whether two high-voltage values are different.
97  *
98  * \param HV1 first high-voltage [V]
99  * \param HV2 second high-voltage [V]
100  * \return true if absolute difference is greater than minimal required difference; else false
101  */
102  const bool checkHV(const double HV1, const double HV2) const
103  {
104  return (fabs(HV1 - HV2) > dHVmin);
105  }
106 
107 
108  /**
109  * Checks if gain is within range.
110  *
111  * \param gain gain value
112  * \return true if gain within allowed range; else false
113  */
114  const bool checkGain(const double gain) const
115  {
116  return (gain > gainRange.getLowerLimit() &&
117  gain < gainRange.getUpperLimit());
118  }
119 
120 
121  /**
122  * Checks whether the gains of two points are strictly increasing as function of their absolute high-voltage
123  *
124  * \param i index of first point
125  * \param j index of second point
126  * \return true if gains of given points are strictly increasing\n
127  * as function of the absolute high-voltage; else false
128  */
129  const bool areIncreasing(const Int_t i, const Int_t j)
130  {
131  TGraphErrors* g1 = getData();
132 
133  if ((i >= 0 && i < g1->GetN()) &&
134  (j >= 0 && i < g1->GetN())) {
135 
136  return ((g1->GetPointX(i) > g1->GetPointX(j) && g1->GetPointY(i) > g1->GetPointY(j)) ||
137  (g1->GetPointX(i) < g1->GetPointX(j) && g1->GetPointY(i) < g1->GetPointY(j)));
138 
139  } else {
140 
141  return false;
142  }
143  }
144 
145 
146  /**
147  * Checks whether two points are valid for inter-/extrapolation.
148  *
149  * \param i index of first point
150  * \param j index of second point
151  * \return true if valid for inter-/extrapolation; else false
152  */
153  const bool areValid(const Int_t i, const Int_t j)
154  {
155  TGraphErrors* g1 = getData();
156 
157  if ((i >= 0 && i < g1->GetN()) &&
158  (j >= 0 && i < g1->GetN())) {
159 
160  const double HV_i = -fabs(g1->GetPointX(i));
161  const double HV_j = -fabs(g1->GetPointX(j));
162  const double gain_i = g1->GetPointY(i);
163  const double gain_j = g1->GetPointY(j);
164 
165  return (areIncreasing( i, j) && checkHV(HV_i) && checkGain(gain_i) &&
166  checkHV (HV_i, HV_j) && checkHV(HV_j) && checkGain(gain_j));
167 
168  } else {
169 
170  return false;
171  }
172  }
173 
174 
175  /**
176  * Inter-/Extrapolate the high-voltage value corresponding to the target gain value.
177  *
178  * \param gainTarget target gain value for inter-/extrapolation
179  * \return true if inter-/extrapolation successful; else false
180  */
181  bool interpolate(const double gainTarget)
182  {
183  TGraphErrors* g1 = getData();
184 
185  if (g1->GetN() < 2 || !checkGain(gainTarget)) {
186  return false;
187  }
188 
189  // Search for valid inter-/extrapolation points
190 
191  Int_t i = 0;
192  Int_t j = 1;
193 
194  for (Int_t k = 1; k < g1->GetN(); ++k) {
195 
196  const double dGain_i = fabs(g1->GetPointY(i) - gainTarget);
197  const double dGain_j = fabs(g1->GetPointY(j) - gainTarget);
198  const double dGain_k = fabs(g1->GetPointY(k) - gainTarget);
199 
200  if (dGain_k < dGain_i) {
201 
202  j = (areValid(i, k) ? i : j);
203  i = k;
204 
205  } else if ((dGain_k < dGain_j || !areValid(i, j)) &&
206  areValid(i, k)) {
207  j = k;
208  }
209  }
210 
211  // Inter-/Extrapolate high-voltage corresponding to given gain
212 
213  if (areValid(i, j)) {
214 
215  const double logHV0 = log(fabs(g1->GetPointX(i)));
216  const double logHV1 = log(fabs(g1->GetPointX(j)));
217 
218  const double logG0 = log(g1->GetPointY(i));
219  const double logG1 = log(g1->GetPointY(j));
220  const double elogG0 = g1->GetErrorY(i) / g1->GetPointY(i);
221  const double elogG1 = g1->GetErrorY(j) / g1->GetPointY(j);
222 
223  const double dlogG0 = log(gainTarget) - logG0;
224  const double dlogG1 = log(gainTarget) - logG1;
225 
226  const double slope = (logG1 - logG0) / (logHV1 - logHV0);
227 
228  const double HVnom = exp(dlogG0 / slope + logHV0);
229  const double eHVnom = HVnom * sqrt(dlogG1 * dlogG1 * elogG0 * elogG0 +
230  dlogG0 * dlogG0 * elogG1 * elogG1) / fabs(slope * (logG1 - logG0));
231 
232  const double distance = fabs((log(HVnom) - logHV0) / (logHV0 - logHV1));
233  static const double maxDist = 2.0;
234 
235  if (checkHV(-HVnom) && distance < maxDist) {
236 
237  TGraphErrors* g0 = getResult();
238 
239  g0->SetPoint (0, HVnom, gainTarget);
240  g0->SetPointError(0, eHVnom, 0.0);
241 
242  return true;
243  }
244  }
245 
246  return false;
247  }
248 
249 
250  /**
251  * Get high-voltage corresponding to given target gain value.
252  *
253  * \param gainTarget target gain value for inter-/extrapolation
254  * \return inter-/extrapolated high-voltage\n
255  * corresponding to target gain value [V]
256  */
257  double getTargetHV(const double gainTarget)
258  {
259  static const double precision = 1e-3;
260 
261  TGraphErrors* g0 = getResult();
262 
263  if ((g0->GetN() > 0 && fabs(g0->GetPointY(0) - gainTarget) < precision) || interpolate(gainTarget)) {
264 
265  return g0->GetPointX(0);
266 
267  } else {
268 
269  THROW(JValueOutOfRange, "JHVInterpolator::getTargetError(): No valid inter-/extrapolation candidate found for given target gain of " << gainTarget << '.');
270  }
271  }
272 
273 
274  /**
275  * Get error estimate on high-voltage corresponding to given target gain value.
276  *
277  * \param gainTarget target gain value for inter-/extrapolation
278  * \return error on inter-/extrapolated high-voltage\n
279  * corresponding to the target gain value [V]
280  */
281  double getTargetHVError(const double gainTarget)
282  {
283  static const double precision = 1e-3;
284 
285  TGraphErrors* g0 = getResult();
286 
287  if ((g0->GetN() > 0 && fabs(g0->GetPointY(0) - gainTarget) < precision) || interpolate(gainTarget)) {
288 
289  return g0->GetErrorX(0);
290 
291  } else {
292 
293  THROW(JValueOutOfRange, "JHVInterpolator::getTargetError(): No valid inter-/extrapolation candidate found for given target gain of " << gainTarget << '.');
294  }
295  }
296 
297 
298  /**
299  * Get graph with the input data for the interpolation.
300  *
301  * \return pointer to graph with input data
302  */
303  TGraphErrors* getData()
304  {
305  TGraphErrors* g1;
306 
307  TList* list = data->GetListOfGraphs();
308 
309  if (list != NULL && list->FindObject(HVINTERPOLATOR_DATA) != NULL) {
310 
311  g1 = (TGraphErrors*)list->FindObject(HVINTERPOLATOR_DATA);
312 
313  } else {
314 
315  g1 = new TGraphErrors();
316 
317  g1->SetName(HVINTERPOLATOR_DATA);
318 
319  g1->SetMarkerStyle(kFullDotSmall);
320 
321  g1->Set(0);
322 
323  data->Add(g1);
324  }
325 
326  return g1;
327  }
328 
329 
330  /**
331  * Get graph with the interpolation result.
332  *
333  * \return pointer to graph with the interpolation result
334  */
335  TGraphErrors* getResult()
336  {
337  TGraphErrors* g0;
338 
339  TList* list = data->GetListOfGraphs();
340 
341  if (list != NULL && list->FindObject(HVINTERPOLATOR_RESULT) != NULL) {
342 
343  g0 = (TGraphErrors*)list->FindObject(HVINTERPOLATOR_RESULT);
344 
345  } else {
346 
347  g0 = new TGraphErrors();
348 
349  g0->SetName(HVINTERPOLATOR_RESULT);
350 
351  g0->SetLineColor (kRed);
352  g0->SetMarkerColor(kRed);
353  g0->SetMarkerStyle(kFullDotSmall);
354 
355  g0->Set(0);
356 
357  data->Add(g0);
358  }
359 
360  return g0;
361  }
362 
363 
364  /**
365  * Set minimal separation distance for high-voltage.
366  *
367  * \param minDist minimal separation distance for high-voltage
368  */
369  static void setMinHVDistance(const double minDist)
370  {
371  dHVmin = minDist;
372  }
373 
374 
375  /**
376  * Set valid gain range.
377  *
378  * \param range valid high-voltage range [V]
379  */
380  static void setHVRange(const JRange<double> range)
381  {
382  hvRange = range;
383  }
384 
385 
386  /**
387  * Set valid gain range.
388  *
389  * \param range valid gain range
390  */
391  static void setGainRange(const JRange<double> range)
392  {
393  gainRange = range;
394  }
395 
396 
397  private:
398 
399  TMultiGraph* data; //!< HV-versus-gain data
400 
401  static double dHVmin; //!< Minimal high-voltage difference between two points [V]
402  static JRange<double> hvRange; //!< Allowed high-voltage range [V]
403  static JRange<double> gainRange; //!< Allowed gain range
404  };
405 
406 
407  /**
408  * Default values.
409  */
410  double JHVInterpolator::dHVmin = 2 * 3.14;
414 }
415 
416 #endif
void SetPoint(Int_t i, Double_t HV, Double_t gain, Double_t gainError)
Set point with index i.
Exceptions.
then fatal No hydrophone data file $HYDROPHONE_TXT fi sort gr k
static const char * HVINTERPOLATOR_RESULT
T getLowerLimit() const
Get lower limit.
Definition: JRange.hh:202
TGraphErrors * getResult()
Get graph with the interpolation result.
double getTargetHVError(const double gainTarget)
Get error estimate on high-voltage corresponding to given target gain value.
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
TGraphErrors * getData()
Get graph with the input data for the interpolation.
static const double FITTOT_GAIN_MAX
Default maximal gain.
Definition: JFitToT.hh:44
static const double FITTOT_GAIN_MIN
Default minimal gain.
Definition: JFitToT.hh:43
const bool areValid(const Int_t i, const Int_t j)
Checks whether two points are valid for inter-/extrapolation.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:670
static void setGainRange(const JRange< double > range)
Set valid gain range.
then JShowerPostfit f $INPUT_FILE o $OUTPUT_FILE N
static const std::string HVINTERPOLATOR_SUFFIX
static JRange< double > hvRange
Allowed high-voltage range [V].
double getTargetHV(const double gainTarget)
Get high-voltage corresponding to given target gain value.
static void setHVRange(const JRange< double > range)
Set valid gain range.
static JRange< double > gainRange
Allowed gain range.
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable STRING $argv[2] set_array QUANTILES set_variable FORMULA *[0] exp(-0.5 *(x-[1])*(x-[1])/([2]*[2]))" set_variable MODULE `getModule -a $DETECTOR -L "$STRING 0"` typeset -Z 4 STRING JOpera1D -f hydrophone.root
const bool checkHV(const double HV) const
Checks whether high-voltage is within range.
TMultiGraph * data
HV-versus-gain data.
static void setMinHVDistance(const double minDist)
Set minimal separation distance for high-voltage.
bool interpolate(const double gainTarget)
Inter-/Extrapolate the high-voltage value corresponding to the target gain value. ...
const bool checkGain(const double gain) const
Checks if gain is within range.
Auxiliary data structure to store high-voltage versus gain data and interpolate the nominal high-volt...
T getUpperLimit() const
Get upper limit.
Definition: JRange.hh:213
const bool areIncreasing(const Int_t i, const Int_t j)
Checks whether the gains of two points are strictly increasing as function of their absolute high-vol...
Range of values.
Definition: JRange.hh:38
static const char * HVINTERPOLATOR_DATA
z range($ZMAX-$ZMIN)< $MINIMAL_DZ." fi fi typeset -Z 4 STRING typeset -Z 2 FLOOR JPlot1D -f $
then $JPP_DIR examples JDetector JToT o $OUTPUT_FILE n N $NPE P gain
Definition: JToT.sh:47
Auxiliary class to define a range between two values.
static double dHVmin
Minimal high-voltage difference between two points [V].
JHVInterpolator(TMultiGraph &object)
Constructor.
int j
Definition: JPolint.hh:666
Exception for accessing a value in a collection that is outside of its range.
Definition: JException.hh:162
const bool checkHV(const double HV1, const double HV2) const
Checks whether two high-voltage values are different.
void AddPoint(Double_t HV, Double_t gain, Double_t gainError)
Add point to diagram.
Double_t g1(const Double_t x)
Function.
Definition: JQuantiles.cc:25