Jpp 20.0.0-rc.1
the software that should make you happy
Loading...
Searching...
No Matches
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
22
24
25#include "JTrigger/JHitR0.hh"
26#include "JTrigger/JBuildL0.hh"
27
29
30#include "JFit/JLine1Z.hh"
32#include "JFit/JFitToolkit.hh"
33#include "JFit/JModel.hh"
34#include "JFit/JNPEHit.hh"
35#include "JFit/JEnergy.hh"
36
43
44#include "JPhysics/JGeane.hh"
45
46
47/**
48 * \author mdejong, azegarelli, scelli
49 */
50namespace JRECONSTRUCTION {}
51namespace JPP { using namespace JRECONSTRUCTION; }
52
53namespace JRECONSTRUCTION {
54
61 using JFIT::JRegressor;
62 using JFIT::JEnergy;
64
65
66 /**
67 * Auxiliary class to to determine muon energy.
68 */
69 class JMuonEnergy :
71 public JRegressor<JEnergy>
72 {
73 public:
77
78 using JRegressor_t::operator();
79
80 /**
81 * Input data type.
82 */
83 struct input_type :
84 public JDAQEventHeader
85 {
86 /**
87 * Default constructor.
88 */
90 {}
91
92
93 /**
94 * Constructor.
95 *
96 * \param header header
97 * \param in start values
98 * \param coverage coverage
99 */
101 const JEvt& in,
102 const coverage_type& coverage) :
103 JDAQEventHeader(header),
104 in(in)
105 {}
106
110 };
111
112
113 /**
114 * Constructor.
115 *
116 * \param parameters parameters
117 * \param storage storage
118 * \param pmtParameters PMT parameters
119 * \param correct energy correction
120 * \param debug debug
121 */
123 const storage_type& storage,
126 const int debug = 0):
127 JMuonEnergyParameters_t(parameters),
128 JRegressor_t (storage),
131 {
132 using namespace JPP;
133
134 if (this->getRmax() < roadWidth_m) {
135 roadWidth_m = this->getRmax();
136 }
137
138 JRegressor_t::debug = debug;
139
140 this->estimator.reset(getMEstimator(mestimator));
141 }
142
143
144 /**
145 * Get input data.
146 *
147 * \param router module router
148 * \param summary summary data
149 * \param event event
150 * \param in start values
151 * \param coverage coverage
152 * \return input data
153 */
155 const JSummaryRouter& summary,
156 const JDAQEvent& event,
157 const JEvt& in,
158 const coverage_type& coverage) const
159 {
160 using namespace std;
161 using namespace JTRIGGER;
162
163 input_type input(event.getDAQEventHeader(), in, coverage);
164
165 const JBuildL0 <JHitR0> buildL0;
167
168 const JDAQTimeslice timeslice(event, true);
169
170 JSuperFrame2D<JHit> buffer;
171
172 for (JDAQTimeslice::const_iterator i = timeslice.begin(); i != timeslice.end(); ++i) {
173
174 if (router.hasModule(i->getModuleID())) {
175
176 buffer(*i, router.getModule(i->getModuleID()));
177
178 buildL0(buffer, back_inserter(data[i->getModuleID()]));
179 }
180 }
181
182 for (const auto& module : router.getReference()) {
183 if (!module.empty()) {
184 input.data.push_back(module_type(module, summary.getSummaryFrame(module.getID(), R_Hz), data[module.getID()]));
185 }
186 }
187
188 return input;
189 }
190
191
192 /**
193 * Auxiliary class for energy estimation.
194 */
195 struct JResult {
196 /**
197 * Constructor.
198 *
199 * \param x Energy [log(E/GeV)]
200 * \param chi2 chi2
201 */
202 JResult(const JEnergy& x = 0.0,
203 const double chi2 = std::numeric_limits<double>::max())
204 {
205 this->x = x;
206 this->chi2 = chi2;
207 }
208
209 /**
210 * Type conversion.
211 *
212 * \return true if valid chi2; else false
213 */
214 operator bool() const
215 {
216 return chi2 != std::numeric_limits<double>::max();
217 }
218
219 JEnergy x; //!< Energy
220 double chi2; //!< chi2
221 };
222
223
224 /**
225 * Fit function.
226 *
227 * \param input input data
228 * \return fit results
229 */
231 {
232 using namespace std;
233 using namespace JPP;
234
235 JEvent event(JMUONENERGY);
236
237 JEvt out;
238
239 // select start values
240
241 JEvt in = input.in;
242
244
245 if (!in.empty()) {
246 in.select(JHistory::is_event(in.begin()->getHistory()));
247 }
248
249 for (JEvt::const_iterator track = in.begin(); track != in.end(); ++track) {
250
251 const JRotation3D R (getDirection(*track));
252 const JLine1Z tz(getPosition (*track).rotate(R), track->getT());
253
254 double zmin = numeric_limits<double>::lowest();
255
256 if (track->hasW(JSTART_LENGTH_METRES) && track->getW(JSTART_LENGTH_METRES) > 0.0) {
257 zmin = this->ZMin_m;
258 }
259
260 vector<JNPEHit> data;
261
262 for (const auto& module : input.data) {
263
264 JPosition3D pos(module->getPosition());
265
266 pos.transform(R, tz.getPosition());
267
268 if (pos.getX() <= roadWidth_m) {
269
270 const double z1 = pos.getZ() - pos.getX() / getTanThetaC();
271 const double t1 = tz .getT() + (pos.getZ() + pos.getX() * getKappaC()) * getInverseSpeedOfLight();
272
273 if (z1 >= zmin) {
274
275 for (size_t i = 0; i != module->size(); ++i) {
276
277 if (module.getStatus(i)) {
278
279 const struct {
280
281 bool operator()(const JHitR0& hit) const
282 {
283 return (hit.getPMT() == pmt && T_ns(hit.getT()));
284 }
285
286 const JTimeRange T_ns;
287 const size_t pmt;
288
289 } match = { T_ns + t1, i };
290
291 const JPMTIdentifier id(module->getID(), i);
292
294
295 JPMT pmt = module->getPMT(i);
296
297 pmt.transform(R, tz.getPosition());
298
299 const JNPEHit hit(this->getNPE(pmt, module.frame.getRate(i)), count_if(module.begin(), module.end(), match), ps);
300
301 DEBUG("hit: " << setw(8) << module->getID() << '.' << FILL(2,'0') << i << ' '
302 << FIXED(7,3) << hypot(pmt.getX(), pmt.getY()) << ' '
303 << FIXED(7,3) << module.frame.getRate(i) * 1.0e-3 << ' '
304 << SCIENTIFIC(9,3) << hit.getY0() << ' '
305 << SCIENTIFIC(9,3) << hit.getY1() << ' '
306 << SCIENTIFIC(9,3) << hit.getYA() << ' '
307 << SCIENTIFIC(9,3) << hit.getYB() << ' '
308 << setw(2) << hit.getN() << endl);
309
310 data.push_back(hit);
311 }
312 }
313 }
314 }
315 }
316
317 const int NDF = distance(data.begin(), data.end()) - 1;
318
319 if (NDF >= 0) {
320
321 // 5-point search between given limits
322
323 const int N = 5;
324
325 JResult result[N];
326
327 for (int i = 0; i != N; ++i) {
328 result[i].x = EMin_log + i * (EMax_log - EMin_log) / (N-1);
329 }
330
331 map<double, double> buffer;
332
333 do {
334
335 int j = 0;
336
337 for (int i = 0; i != N; ++i) {
338
339 if (!result[i]) {
340
341 const JEnergy x = result[i].x;
342 const double chi2 = (*this)(x, data.begin(), data.end());
343
344 result[i].chi2 = chi2;
345 buffer[chi2] = x.getE();
346 }
347
348 if (result[i].chi2 < result[j].chi2) {
349 j = i;
350 }
351 }
352
353
354 for (int i = 0; i != N; ++i) {
355 DEBUG(' ' << FIXED(5,2) << result[i].x << ' ' << FIXED(9,3) << result[i].chi2);
356 }
357 DEBUG(endl);
358
359 // squeeze range
360
361 switch (j) {
362
363 case 0:
364 result[4] = result[1];
365 result[2] = result[0];
366 result[0] = JResult(2*result[2].x - result[4].x);
367 break;
368
369 case 1:
370 result[4] = result[2];
371 result[2] = result[1];
372 break;
373
374 case 2:
375 result[0] = result[1];
376 result[4] = result[3];
377 break;
378
379 case 3:
380 result[0] = result[2];
381 result[2] = result[3];
382 break;
383
384 case 4:
385 result[0] = result[3];
386 result[2] = result[4];
387 result[4] = JResult(2*result[2].x - result[0].x);
388 break;
389 }
390
391 result[1] = JResult(0.5 * (result[0].x + result[2].x));
392 result[3] = JResult(0.5 * (result[2].x + result[4].x));
393
394 } while (result[4].x - result[0].x > resolution);
395
396
397 if (result[1].chi2 != result[3].chi2) {
398
399 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);
400 result[2].chi2 = (*this)(result[2].x, data.begin(), data.end());
401
402 }
403
404 const double chi2 = result[2].chi2;
405 const double E = result[2].x.getE();
406
407 // calculate additional variables
408
409 double Emin = numeric_limits<double>::max();
410 double Emax = numeric_limits<double>::lowest();
411
412 for (map<double, double>::const_iterator i = buffer.begin(); i != buffer.end() && i->first <= chi2 + 1.0; ++i) {
413 if (i->second < Emin) { Emin = i->second; }
414 if (i->second > Emax) { Emax = i->second; }
415 }
416
417 const double mu_range = gWater(E); // range of a muon with the reconstructed energy
418
419 double noise_likelihood = 0.0; // log-likelihood of every hit being from K40
420 int number_of_hits = 0; // number of hits selected for JEnergy
421
422 for (vector<JNPEHit>::const_iterator i = data.begin(); i != data.end(); ++i) {
423 noise_likelihood += log10(getP(i->getY0(), i->getN())); // probability of getting the observed multiplicity with K40
424 number_of_hits += i->getN(); // hit multiplicity
425 }
426
427 JFit fit = *track;
428
429 fit.push_back(event());
430
431 // set corrected energy
432
433 fit.setE(pow(10.0, correct(log10(E))));
434
435 out.push_back(fit);
436
437 // set additional values
438
439 out.rbegin()->setW(track->getW());
440 out.rbegin()->setW(JENERGY_ENERGY, E);
441 out.rbegin()->setW(JENERGY_CHI2, chi2);
442 out.rbegin()->setW(JENERGY_MUON_RANGE_METRES, mu_range);
443 out.rbegin()->setW(JENERGY_NOISE_LIKELIHOOD, noise_likelihood);
444 out.rbegin()->setW(JENERGY_NDF, NDF);
445 out.rbegin()->setW(JENERGY_NUMBER_OF_HITS, number_of_hits);
446 out.rbegin()->setW(JENERGY_MINIMAL_ENERGY, Emin);
447 out.rbegin()->setW(JENERGY_MAXIMAL_ENERGY, Emax);
448 out.rbegin()->setW(JPP_COVERAGE_ORIENTATION, input.coverage.orientation);
449 out.rbegin()->setW(JPP_COVERAGE_POSITION, input.coverage.position);
450 }
451 }
452
453 // apply default sorter
454
455 sort(out.begin(), out.end(), qualitySorter);
456
457 copy(input.in.begin(), input.in.end(), back_inserter(out));
458
459 return out;
460 }
461
463
465 };
466}
467
468#endif
469
Coverage of dynamical detector calibration.
Auxiliary class to extract a subset of optical modules from a detector.
Data structure for detector geometry and calibration.
Data regression method for JFIT::JEnergy.
Auxiliary methods to evaluate Poisson probabilities and chi2.
Energy loss of muon.
Basic data structure for L0 hit.
#define DEBUG(A)
Message macros.
Definition JMessage.hh:62
int debug
debug level
Definition JSirene.cc:72
Direct access to module in detector data structure.
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
Router for direct addressing of module data in detector data structure.
bool hasModule(const JObjectID &id) const
Has module.
const JModule & getModule(const JObjectID &id) const
Get module parameters.
Data structure for a composite optical module.
Definition JModule.hh:75
Auxiliary class for map of PMT parameters.
const JPMTParameters & getPMTParameters(const JPMTIdentifier &id) const
Get PMT parameters.
Data structure for PMT geometry, calibration and status.
Definition JPMT.hh:49
Data structure for fit of energy.
Data structure for set of track fit results.
void select(const JSelector_t &selector)
Select fits.
Data structure for track fit results with history and optional associated values.
void setE(const double E)
Set energy.
Data structure for fit of straight line paralel to z-axis.
Definition JLine1Z.hh:29
double getT(const JVector3D &pos) const
Get arrival time of Cherenkov light at given position.
Definition JLine1Z.hh:114
void transform(const JAxis3D &axis)
Transform axis to reference frame of given axis.
Definition JAxis3D.hh:359
Data structure for position in three dimensions.
void transform(const JRotation3D &R, const JVector3D &pos)
Transform position.
JPosition3D & rotate(const JRotation3D &R)
Rotate.
const JPosition3D & getPosition() const
Get position.
double getY() const
Get y position.
Definition JVector3D.hh:104
double getZ() const
Get z position.
Definition JVector3D.hh:115
double getX() const
Get x position.
Definition JVector3D.hh:94
const JClass_t & getReference() const
Get reference to object.
Definition JReference.hh:38
Auxiliary class for correction of energy determined by JEnergy.cc.
Auxiliary class to to determine muon energy.
const JPMTParametersMap & pmtParameters
JEvt operator()(const input_type &input)
Fit function.
JRegressor< JEnergy > JRegressor_t
std::vector< module_type > detector_type
input_type getInput(const JModuleRouter &router, const JSummaryRouter &summary, const JDAQEvent &event, const JEvt &in, const coverage_type &coverage) const
Get input data.
JMuonEnergy(const JMuonEnergyParameters_t &parameters, const storage_type &storage, const JPMTParametersMap &pmtParameters, const JEnergyCorrection &correct, const int debug=0)
Constructor.
Router for fast addressing of summary data in KM3NETDAQ::JDAQSummaryslice data structure as a functio...
const JDAQSummaryFrame & getSummaryFrame(const JDAQModuleIdentifier &module) const
Get summary frame.
Reduced data structure for L0 hit.
Definition JHitR0.hh:27
JPMT_t getPMT() const
Get PMT.
Definition JHitR0.hh:60
double getT() const
Get calibrated time of hit.
2-dimensional frame with time calibrated data from one optical module.
const JDAQEventHeader & getDAQEventHeader() const
Get DAQ event header.
Data storage class for rate measurements of all PMTs in one module.
static const int JENERGY_NDF
number of degrees of freedom from JMuonEnergy
static const int JENERGY_ENERGY
uncorrected energy [GeV] from JMuonEnergy
static const int JENERGY_NOISE_LIKELIHOOD
log likelihood of every hit being K40 from JMuonEnergy
static const int JENERGY_CHI2
chi2 from JMuonEnergy
static const int JENERGY_MUON_RANGE_METRES
range of a muon with the reconstructed energy [m] from JMuonEnergy
static const int JPP_COVERAGE_POSITION
coverage of dynamic position calibration from any Jpp application
static const int JENERGY_NUMBER_OF_HITS
number of hits from JMuonEnergy
static const int JSTART_LENGTH_METRES
distance between projected positions on the track of optical modules for which the response does not ...
static const int JPP_COVERAGE_ORIENTATION
coverage of dynamic orientation calibration from any Jpp application
static const int JENERGY_MINIMAL_ENERGY
minimal energy [GeV] from JMuonEnergy
static const int JENERGY_MAXIMAL_ENERGY
maximal energy [GeV] from JMuonEnergy
double getNPE(const Hit &hit)
Get true charge of hit.
double getSurvivalProbability(const JPMTParameters &parameters)
Get model dependent probability that a one photo-electron hit survives the simulation of the PMT assu...
JMEstimator * getMEstimator(const int type)
Get M-Estimator.
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.
T pow(const T &x, const double y)
Power .
Definition JMath.hh:97
double getKappaC()
Get average R-dependence of arrival time of Cherenkov light (a.k.a.
const double getInverseSpeedOfLight()
Get inverse speed of light.
static const JGeaneWater gWater
Function object for energy loss of muon in sea water.
Definition JGeane.hh:381
double getTanThetaC()
Get average tangent of Cherenkov angle of water corresponding to group velocity.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
JPosition3D getPosition(const JFit &fit)
Get position.
void copy(const JFIT::JEvt::const_iterator __begin, const JFIT::JEvt::const_iterator __end, Evt &out)
Copy tracks.
bool qualitySorter(const JFit &first, const JFit &second)
Comparison of fit results.
JDirection3D getDirection(const JFit &fit)
Get direction.
return result
Definition JPolint.hh:862
int j
Definition JPolint.hh:801
Auxiliary classes and methods for triggering.
Auxiliary data structure for sequence of same character.
Definition JManip.hh:330
Auxiliary data structure for floating point format specification.
Definition JManip.hh:448
Data structure for coverage of detector by dynamical calibrations.
Definition JCoverage.hh:19
double position
coverage of detector by available position calibration [0,1]
Definition JCoverage.hh:42
double orientation
coverage of detector by available orientation calibration [0,1]
Definition JCoverage.hh:41
Auxiliary class for historical event.
Definition JHistory.hh:40
Auxiliary class to test history.
Definition JHistory.hh:157
double getY0() const
Get light yield due to random background.
Definition JK40.hh:49
Auxiliary class for simultaneously handling light yields and response of PMT.
Definition JNPEHit.hh:21
size_t getN() const
Get number of hits.
Definition JNPEHit.hh:53
double getYB() const
Get light yield due to bremsstrahlung.
Definition JNPE.hh:93
double getY1() const
Get light yield due to minimum ionizing particle.
Definition JNPE.hh:71
double getYA() const
Get light yield due to delta-rays.
Definition JNPE.hh:82
Template definition of a data regressor of given model.
Definition JRegressor.hh:70
Auxiliary class for handling module response.
Definition JModuleL0.hh:45
double resolution
energy resolution [log10(GeV)]
double EMin_log
minimal energy [log10(GeV)]
double EMax_log
maximal energy [log10(GeV)]
Auxiliary class for energy estimation.
JResult(const JEnergy &x=0.0, const double chi2=std::numeric_limits< double >::max())
Constructor.
input_type(const JDAQEventHeader &header, const JEvt &in, const coverage_type &coverage)
Constructor.
Auxiliary data structure for floating point format specification.
Definition JManip.hh:488