Jpp  17.1.0
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JMuonEnergy.hh
Go to the documentation of this file.
1 #ifndef __JRECONSTRUCTION__JMUONENERGY__
2 #define __JRECONSTRUCTION__JMUONENERGY__
3 
4 #include <string>
5 #include <istream>
6 #include <ostream>
7 #include <iomanip>
8 #include <set>
9 #include <vector>
10 #include <algorithm>
11 #include <cmath>
12 
16 
17 #include "JDetector/JDetector.hh"
20 
21 #include "JTrigger/JHitL0.hh"
22 #include "JTrigger/JHitR1.hh"
23 #include "JTrigger/JBuildL0.hh"
24 
26 
27 #include "JFit/JLine1Z.hh"
28 #include "JFit/JEnergyRegressor.hh"
29 #include "JFit/JFitToolkit.hh"
30 #include "JFit/JModel.hh"
31 #include "JFit/JNPEHit.hh"
32 #include "JFit/JEnergy.hh"
33 
35 #include "JReconstruction/JEvt.hh"
38 
39 #include "JPhysics/JGeane.hh"
40 
41 
42 /**
43  * \author mdejong, azegarelli, scelli
44  */
45 namespace JRECONSTRUCTION {}
46 namespace JPP { using namespace JRECONSTRUCTION; }
47 
48 namespace JRECONSTRUCTION {
49 
52  using JFIT::JRegressor;
53  using JFIT::JEnergy;
54 
55  /**
56  * Auxiliary class to to determine muon energy.
57  */
58  class JMuonEnergy :
60  public JRegressor<JEnergy>
61  {
62  public:
67 
68  using JRegressor_t::operator();
69 
70  /**
71  * Constructor.
72  *
73  * \param parameters parameters
74  * \param router module router
75  * \param summary summary router
76  * \param pdfFile PDF file
77  * \param debug debug
78  */
80  const JModuleRouter& router,
81  const JSummaryRouter& summary,
82  const std::string& pdfFile,
83  const int debug = 0):
84  JMuonEnergyParameters_t(parameters),
85  JRegressor_t(pdfFile),
86  router(router),
87  summary(summary),
88  debug(debug)
89  {
90  using namespace JPP;
91 
94 
95  if (this->getRmax() < roadWidth_m) {
96  roadWidth_m = this->getRmax();
97  }
98 
99  this->estimator.reset(getMEstimator(mestimator));
100 
101  if (!this->estimator.is_valid()) {
102  FATAL("Invalid M-Estimator." << endl);
103  }
104  }
105 
106 
107  /**
108  * Auxiliary class for energy estimation.
109  */
110  struct JResult {
111  /**
112  * Constructor.
113  *
114  * \param x Energy [log(E/GeV)]
115  * \param chi2 chi2
116  */
117  JResult(const JEnergy& x = 0.0,
118  const double chi2 = std::numeric_limits<double>::max())
119  {
120  this->x = x;
121  this->chi2 = chi2;
122  }
123 
124  /**
125  * Type conversion.
126  *
127  * \return true if valid chi2; else false
128  */
129  operator bool() const
130  {
131  return chi2 != std::numeric_limits<double>::max();
132  }
133 
134  JEnergy x; //!< Energy
135  double chi2; //!< chi2
136  };
137 
138 
139  /**
140  * Fit function.
141  *
142  * \param event event
143  * \param in start values
144  * \return fit results
145  */
146  JEvt operator()(const KM3NETDAQ::JDAQEvent& event, const JEvt& in)
147  {
148  using namespace std;
149  using namespace JPP;
150 
151  JEvt out;
152 
153  typedef vector<JHitL0> JDataL0_t;
154  const JBuildL0<JHitL0> buildL0;
155 
157 
158  JDataL0_t dataL0;
159 
160  buildL0(JDAQTimeslice(event, true), router, back_inserter(dataL0));
161 
162  for (JEvt::const_iterator track = in.begin(); track != in.end(); ++track) {
163 
164  const JRotation3D R (getDirection(*track));
165  const JLine1Z tz(getPosition (*track).rotate(R), track->getT());
167 
169 
170  vector<JNPEHit> data;
171 
172  for (JDataL0_t::const_iterator i = dataL0.begin(); i !=dataL0.end(); ++i) {
173 
174  JHitR1 hit(*i);
175 
176  hit.rotate(R);
177 
178  if (match(hit)) {
179  top.insert(i->getPMTIdentifier());
180  }
181  }
182 
183  JRange<double> Z_m;
184 
185  if ( track->hasW(JSTART_LENGTH_METRES) && track->getW(JSTART_LENGTH_METRES) > 0.0 ) {
186  Z_m.setLowerLimit(this->ZMin_m);
187  }
188 
189  const JDetectorSubset_t subdetector(detector, getAxis(*track), roadWidth_m, Z_m);
190 
191  for (JDetector::const_iterator module = subdetector.begin(); module != subdetector.end(); ++module) {
192 
193  if (summary.hasSummaryFrame(module->getID())) {
194 
195  const JDAQSummaryFrame& frame = summary.getSummaryFrame(module->getID());
196 
197  for (size_t i = 0; i != module->size(); ++i) {
198 
199  if (getDAQStatus(frame, *module, i) &&
200  getPMTStatus(frame, *module, i) &&
201  !module->getPMT(i).has(PMT_DISABLE)) {
202 
203  const JDAQPMTIdentifier id(module->getID(), i);
204 
205  const double rate_Hz = summary.getRate(id);
206  const size_t count = top.count(id);
207 
208  data.push_back(JNPEHit(this->getNPE(module->getPMT(i), rate_Hz), count));
209  }
210  }
211  }
212  }
213 
214  const int NDF = distance(data.begin(), data.end()) - 1;
215 
216  if( NDF >= 0 ) {
217 
218  // 5-point search between given limits
219 
220  const int N = 5;
221 
222  JResult result[N];
223 
224  for (int i = 0; i != N; ++i) {
225  result[i].x = EMin_log + i * (EMax_log - EMin_log) / (N-1);
226  }
227 
228  map<double, double> buffer;
229 
230  do {
231 
232  int j = 0;
233 
234  for (int i = 0; i != N; ++i) {
235 
236  if (!result[i]) {
237 
238  const JEnergy x = result[i].x;
239  const double chi2 = (*this)(x, data.begin(), data.end());
240 
241  result[i].chi2 = chi2;
242  buffer[chi2] = x.getE();
243  }
244 
245  if (result[i].chi2 < result[j].chi2) {
246  j = i;
247  }
248  }
249 
250 
251  for (int i = 0; i != N; ++i) {
252  DEBUG(' ' << FIXED(5,2) << result[i].x << ' ' << FIXED(9,3) << result[i].chi2);
253  }
254  DEBUG(endl);
255 
256  // squeeze range
257 
258  switch (j) {
259 
260  case 0:
261  result[4] = result[1];
262  result[2] = result[0];
263  result[0] = JResult(2*result[2].x - result[4].x);
264  break;
265 
266  case 1:
267  result[4] = result[2];
268  result[2] = result[1];
269  break;
270 
271  case 2:
272  result[0] = result[1];
273  result[4] = result[3];
274  break;
275 
276  case 3:
277  result[0] = result[2];
278  result[2] = result[3];
279  break;
280 
281  case 4:
282  result[0] = result[3];
283  result[2] = result[4];
284  result[4] = JResult(2*result[2].x - result[0].x);
285  break;
286  }
287 
288  result[1] = JResult(0.5 * (result[0].x + result[2].x));
289  result[3] = JResult(0.5 * (result[2].x + result[4].x));
290 
291  } while (result[4].x - result[0].x > resolution);
292 
293 
294  if (result[1].chi2 != result[3].chi2) {
295 
296  result[2].x += 0.25 * (result[3].x - result[1].x) * (result[1].chi2 - result[3].chi2) / (result[1].chi2 + result[3].chi2 - 2*result[2].chi2);
297  result[2].chi2 = (*this)(result[2].x, data.begin(), data.end());
298 
299  }
300 
301  const double chi2 = result[2].chi2;
302  const double E = result[2].x.getE();
303 
304  // calculate additional variables
305 
306  double Emin = numeric_limits<double>::max();
307  double Emax = numeric_limits<double>::lowest();
308 
309  for (map<double, double>::const_iterator i = buffer.begin(); i != buffer.end() && i->first <= chi2 + 1.0; ++i) {
310  if (i->second < Emin) { Emin = i->second; }
311  if (i->second > Emax) { Emax = i->second; }
312  }
313 
314  const double mu_range = gWater(E); // range of a muon with the reconstructed energy
315 
316  double noise_likelihood = 0.0; // log-likelihood of every hit being from K40
317  int number_of_hits = 0; // number of hits selected for JEnergy
318 
319  for (vector<JNPEHit>::const_iterator i = data.begin(); i != data.end(); ++i) {
320  noise_likelihood += log10(getP(i->getY0(), i->getN())); // probability of getting the observed multiplicity with K40
321  number_of_hits += i->getN(); // hit multiplicity
322  }
323 
324  out.push_back(JFit(*track).add(JMUONENERGY));
325 
326  out.rbegin()->setE(E);
327 
328  out.rbegin()->setW(track->getW());
329  out.rbegin()->setW(JENERGY_ENERGY, E);
330  out.rbegin()->setW(JENERGY_CHI2, chi2);
331  out.rbegin()->setW(JENERGY_MUON_RANGE_METRES, mu_range);
332  out.rbegin()->setW(JENERGY_NOISE_LIKELIHOOD, noise_likelihood);
333  out.rbegin()->setW(JENERGY_NDF, NDF);
334  out.rbegin()->setW(JENERGY_NUMBER_OF_HITS, number_of_hits);
335  out.rbegin()->setW(JENERGY_MINIMAL_ENERGY, Emin);
336  out.rbegin()->setW(JENERGY_MAXIMAL_ENERGY, Emax);
337  }
338  }
339 
340  return out;
341  }
342 
343  private:
346  int debug;
347  };
348 }
349 
350 #endif
351 
Auxiliary methods to evaluate Poisson probabilities and chi2.
static int debug
debug level (default is off).
Definition: JMessage.hh:45
Template definition of a data regressor of given model.
Definition: JRegressor.hh:68
double getE() const
Get energy.
Definition: JEnergy.hh:170
then usage E
Definition: JMuonPostfit.sh:35
JResult(const JEnergy &x=0.0, const double chi2=std::numeric_limits< double >::max())
Constructor.
Definition: JMuonEnergy.hh:117
double TMin_ns
minimal time w.r.t. Cherenkov hypothesis [ns]
static const int JENERGY_ENERGY
uncorrected energy [GeV] from JEnergy.cc
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
Regressor function object for fit of muon energy.
Template specialisation of L0 builder for JHitL0 data type.
Definition: JBuildL0.hh:102
static const int JENERGY_MAXIMAL_ENERGY
maximal energy [GeV] from JEnergy.cc
Energy loss of muon.
Detector data structure.
Definition: JDetector.hh:89
const JSummaryRouter & summary
Definition: JMuonEnergy.hh:345
Router for direct addressing of module data in detector data structure.
Rotation matrix.
Definition: JRotation3D.hh:111
double getRate() const
Get default rate.
JTRIGGER::JHitR1 hit_type
Definition: JMuonEnergy.hh:64
then JShowerPostfit f $INPUT_FILE o $OUTPUT_FILE N
*fatal Wrong number of arguments esac JCookie sh typeset Z DETECTOR typeset Z SOURCE_RUN typeset Z TARGET_RUN set_variable PARAMETERS_FILE $WORKDIR parameters
Definition: diff-Tuna.sh:38
Template specialisation of class JModel to match hit with muon trajectory along z-axis.
Definition: JFit/JModel.hh:34
static const JGeaneWater gWater
Function object for energy loss of muon in sea water.
Definition: JGeane.hh:381
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:446
const JDAQSummaryFrame & getSummaryFrame() const
Get default summary frame.
JFit & add(const int type)
Add event to history.
static const int JENERGY_CHI2
chi2 from JEnergy.cc
Data structure for detector geometry and calibration.
double resolution
energy resolution [log10(GeV)]
static const int JENERGY_NOISE_LIKELIHOOD
log likelihood of every hit being K40 from JEnergy.cc
JRegressor< JEnergy > JRegressor_t
Definition: JMuonEnergy.hh:63
Basic data structure for L0 hit.
static const int JENERGY_NDF
number of degrees of freedom from JEnergy.cc
static const int JENERGY_MINIMAL_ENERGY
minimal energy [GeV] from JEnergy.cc
JTOOLS::JRange< JEnergy > JEnergyRange
Definition: JMuonEnergy.hh:66
Auxiliary class to extract a subset of optical modules from a detector.
const JModuleRouter & router
Definition: JMuonEnergy.hh:344
Detector file.
Definition: JHead.hh:226
JDirection3D getDirection(const Vec &dir)
Get direction.
static const int JENERGY_NUMBER_OF_HITS
number of hits from JEnergy.cc
set_variable E_E log10(E_{fit}/E_{#mu})"
Data storage class for rate measurements of all PMTs in one module.
JEvt operator()(const KM3NETDAQ::JDAQEvent &event, const JEvt &in)
Fit function.
Definition: JMuonEnergy.hh:146
JAxis3D getAxis(const Trk &track)
Get axis.
return result
Definition: JPolint.hh:743
static JTimeRange T_ns
Time window with respect to Cherenkov hypothesis [ns].
static const int PMT_DISABLE
KM3NeT Data Definitions v2.2.0-12-ge740342 https://git.km3net.de/common/km3net-dataformat.
Definition: pmt_status.hh:12
JPosition3D getPosition(const Vec &pos)
Get position.
Data time slice.
Auxiliary class for simultaneously handling light yields and response of PMT.
Definition: JNPEHit.hh:19
Router for fast addressing of summary data in KM3NETDAQ::JDAQSummaryslice data structure as a functio...
then usage $script[distance] fi case set_variable R
Definition: JDrawLED.sh:43
Range of values.
Definition: JRange.hh:38
Detector subset without binary search functionality.
JMuonEnergy(const JMuonEnergyParameters_t &parameters, const JModuleRouter &router, const JSummaryRouter &summary, const std::string &pdfFile, const int debug=0)
Constructor.
Definition: JMuonEnergy.hh:79
std::vector< hit_type > buffer_type
Definition: JMuonEnergy.hh:65
Data structure for fit parameters.
double getP(const double expval, bool hit)
Get Poisson probability to observe a hit or not for given expectation value for the number of hits...
Definition: JFitToolkit.hh:41
#define FATAL(A)
Definition: JMessage.hh:67
Direct access to module in detector data structure.
Reduced data structure for L1 hit.
bool getPMTStatus(const JStatus &status)
Test status of PMT.
const JClass_t & getReference() const
Get reference to object.
Definition: JReference.hh:38
static const int JSTART_LENGTH_METRES
distance between first and last hits in metres from JStart.cc
Data structure for set of track fit results.
std::vector< int > count
Definition: JAlgorithm.hh:180
bool hasSummaryFrame(const JDAQModuleIdentifier &module) const
Has summary frame.
double EMin_log
minimal energy [log10(GeV)]
then if[[!-f $DETECTOR]] then JDetector sh $DETECTOR fi cat $WORKDIR trigger_parameters txt<< EOFtrigger3DMuon.enabled=1;trigger3DMuon.numberOfHits=5;trigger3DMuon.gridAngle_deg=1;ctMin=0.0;TMaxLocal_ns=15.0;EOF set_variable TRIGGEREFFICIENCY_TRIGGERED_EVENTS_ONLY INPUT_FILES=() for((i=1;$i<=$NUMBER_OF_RUNS;++i));do JSirene.sh $DETECTOR $JPP_DATA/genhen.km3net_wpd_V2_0.evt.gz $WORKDIR/sirene_ ${i}.root JTriggerEfficiency.sh $DETECTOR $DETECTOR $WORKDIR/sirene_ ${i}.root $WORKDIR/trigger_efficiency_ ${i}.root $WORKDIR/trigger_parameters.txt $JPP_DATA/PMT_parameters.txt INPUT_FILES+=($WORKDIR/trigger_efficiency_ ${i}.root) done for ANGLE_DEG in $ANGLES_DEG[*];do set_variable SIGMA_NS 3.0 set_variable OUTLIERS 3 set_variable OUTPUT_FILE $WORKDIR/matrix\[${ANGLE_DEG}\deg\].root $JPP_DIR/examples/JReconstruction-f"$INPUT_FILES[*]"-o $OUTPUT_FILE-S ${SIGMA_NS}-A ${ANGLE_DEG}-O ${OUTLIERS}-d ${DEBUG}--!fiif[[$OPTION=="plot"]];then if((0));then for H1 in h0 h1;do JPlot1D-f"$WORKDIR/matrix["${^ANGLES_DEG}" deg].root:${H1}"-y"1 2e3"-Y-L TR-T""-\^"number of events [a.u.]"-> o chi2
Definition: JMatrixNZ.sh:106
Data structure for fit of straight line paralel to z-axis.
Definition: JLine1Z.hh:27
Reduced data structure for L1 hit.
Definition: JHitR1.hh:31
Data structure for fit of energy.
Definition: JEnergy.hh:28
double getNPE(const Hit &hit)
Get true charge of hit.
double TMax_ns
maximal time w.r.t. Cherenkov hypothesis [ns]
int j
Definition: JPolint.hh:682
Data regression method for JFIT::JEnergy.
Auxiliary class to to determine muon energy.
Definition: JMuonEnergy.hh:58
JMEstimator * getMEstimator(const int type)
Get M-Estimator.
Definition: JMEstimator.hh:203
bool getDAQStatus(const JDAQFrameStatus &frame, const JStatus &status)
Test status of DAQ.
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable INPUT_FILE $argv[2] eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY JAcoustics sh $DETECTOR_ID source JAcousticsToolkit sh CHECK_EXIT_CODE typeset A EMITTERS get_tripods $WORKDIR tripod txt EMITTERS get_transmitters $WORKDIR transmitter txt EMITTERS for EMITTER in
Definition: JCanberra.sh:46
JPosition3D & rotate(const JRotation3D &R)
Rotate.
Definition: JPosition3D.hh:186
static const int JENERGY_MUON_RANGE_METRES
range of a muon with the reconstructed energy [m] from JEnergy.cc
void setLowerLimit(argument_type x)
Set lower limit.
Definition: JRange.hh:224
static const int JMUONENERGY
double EMax_log
maximal energy [log10(GeV)]
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62
Auxiliary class for energy estimation.
Definition: JMuonEnergy.hh:110