54 inline double getMuonWeight(
const double E,
71 inline double getMuonWeight(
const double E,
79 return R *
exp(+R/l_att) * getMuonWeight(E, npe);
90 inline double getNeutrinoWeight(
const double E,
105 inline double getNeutrinoWeight(
const double E,
109 static const double l_att = 45.0;
111 return D*D *
exp(+D/l_att) * getNeutrinoWeight(E, npe);
126 return first.second > second.second;
137 inline TH1D* makeSortedH1(TH1D*
in,
const TString&
name)
146 for (Int_t ix = 1; ix <= in->GetXaxis()->GetNbins(); ++ix) {
148 const Int_t
x = (Int_t) in->GetXaxis()->GetBinCenter(ix);
149 const Double_t
y = in->GetBinContent(ix);
152 data.push_back(make_pair(x, y));
158 sort(
data.begin(),
data.end(), compare);
162 TH1D* out =
new TH1D(name, NULL,
data.size(), -0.5,
data.size() - 0.5);
164 for (Int_t
i = 0;
i < (Int_t)
data.size();
i++) {
166 const Int_t ix =
i + 1;
169 out->SetBinContent(ix,
data[
i].second);
183 int main(
int argc,
char **argv)
201 JParser<> zap(
"Example program to verify Monte Carlo data.");
204 zap[
'n'] =
make_field(numberOfEvents) = JLimit::max();
212 catch(
const exception &error) {
213 FATAL(error.what() << endl);
223 if (detectorFile !=
"") {
244 NOTICE(
"Apply detector offset " << offset << endl);
255 NOTICE(
"JDomino: Instrumented volume dimensions (x, y, r, zmin, zmax): " << inst_vol << endl);
269 if (header.is_valid(&JHead::cut_nu)) {
270 xmin =
log10(header.cut_nu.E.getLowerLimit());
271 xmax =
log10(header.cut_nu.E.getUpperLimit());
272 }
else if (header.is_valid(&JHead::cut_in)) {
273 xmin =
log10(header.cut_in.E.getLowerLimit());
274 xmax =
log10(header.cut_in.E.getUpperLimit());
276 const int nx = (int) ((
xmax -
xmin) / 0.1);
278 const Double_t
T[] = { -50.0, -20.0, -10.0, -5.0, -2.0, 0.0, +2.0, +5.0, +10.0, +15.0, +20.0, +30.0, +40.0, +50.0,
279 +75.0, +100.0, +150.0, +200.0, +250.0, +300.0, +400.0, +500.0, 1000.0 };
285 TH1D hits(
"hits", NULL, 100, 0.0, 8.0);
286 TH1D trks(
"trks", NULL, 10001, -5000.5, 5000.5);
287 TH1D job (
"job" , NULL, 10001, -5000.5, 5000.5);
289 TProfile hits_per_E_in (
"hits_per_E_in",
"average number of hits per E_{#nu} inside instrumented volume", nx,
xmin,
xmax);
290 TProfile hits_per_E_out(
"hits_per_E_out",
"average number of hits per E_{#nu} outside instrumented volume", nx,
xmin,
xmax);
294 JManager_t npe_per_type(
new TH1D(
"npe[%]", NULL, 5000, 0.5, 5000.5),
'%', ios::fmtflags(ios::showpos));
296 TH1D npe_per_pmt (
"pmt", NULL, 100001, -0.5, 100000.5);
303 TH2D nuExD(
"nuExD", NULL, nx,
xmin,
xmax, 100, 0.0, 1000.0);
304 TH2D* nuExD_tmp = (TH2D*) nuExD.Clone(
"nuExD.tmp");
306 TH2D nuExc(
"nuExc", NULL, nx,
xmin,
xmax, 100, -1.0, +1.0);
307 TH2D* nuExc_tmp = (TH2D*) nuExc.Clone(
"nuExc.tmp");
309 TH2D nuDxc(
"nuDxc", NULL, 50, 0.0, 1000.0, 100, -1.0, +1.0);
310 TH2D* nuDxc_tmp = (TH2D*) nuDxc.Clone(
"nuDxc.tmp");
312 TH2D nuDxU(
"nuDxU", NULL, 50, 0.0, 1000.0, 100, -1.0, +1.0);
313 TH2D* nuDxU_tmp = (TH2D*) nuDxU.Clone(
"nuDxU.tmp");
315 TH2D nuDxT(
"nuDxT", NULL, 50, 0.0, 1000.0,
getSize(
T) - 1,
T);
316 TH2D* nuDxT_tmp = (TH2D*) nuDxT.Clone(
"nuDxT.tmp");
329 TH2D muExR(
"muExR", NULL, nx,
xmin,
xmax, 30, 0.0, 300.0);
330 TH2D* muExR_tmp = (TH2D*) muExR.Clone(
"muExR.tmp");
332 TH2D muRxU(
"muRxU", NULL, 15, 0.0, 300.0, 100, -1.0, +1.0);
333 TH2D* muRxU_tmp = (TH2D*) muRxU.Clone(
"muRxU.tmp");
335 TH2D muRxT(
"muRxT", NULL, 15, 0.0, 300.0,
getSize(
T) - 1,
T);
336 TH2D* muRxT_tmp = (TH2D*) muRxT.Clone(
"muRxT.tmp");
347 while (inputFile.hasNext()) {
349 STATUS(
"event: " << setw(10) << inputFile.getCounter() <<
'\r');
DEBUG(endl);
351 const Evt*
event = inputFile.next();
359 hits.Fill(
log10((Double_t) event->mc_hits.size()));
362 trks.Fill(track->type);
383 const int type = hit->type;
384 const double t1 =
getTime(*hit);
385 const double npe =
getNPE (*hit);
387 npe_pmt[hit->pmt_id].put(npe);
389 npe_type[0] .put(npe);
390 npe_type[
type].put(npe);
392 if (hit_types.empty() || hit_types.count(type) != 0) {
395 event->mc_trks.end(),
398 if (track == event->mc_trks.end()) {
399 ERROR(
"Hit " << *hit <<
" has no origin." << endl);
403 if (count_if(event->mc_trks.begin(),
404 event->mc_trks.end(),
406 ERROR(
"Hit " << *hit <<
" has ambiguous origin." << endl);
410 job.Fill((
double) track->type, npe);
412 if (router.
hasPMT(hit->pmt_id)) {
420 const double E = muon.
getE();
421 const double x =
log10(E);
423 const double t0 = muon.
getT (pmt);
424 const double ct1 = muon.
getDot (pmt);
426 muExR.Fill(x, R, getMuonWeight(E, npe));
427 muRxU.Fill(R, ct1, getMuonWeight(E, R, npe));
428 muRxT.Fill(R, t1 - t0, getMuonWeight(E, R, npe));
432 const double E = neutrino.
getE();
433 const double x =
log10(E);
435 const double t0 = vertex.
getT(pmt);
437 const double ct1 = vertex.
getDot(pmt);
439 nuExD.Fill(x, D, getNeutrinoWeight(E, npe));
440 nuExc.Fill(x, ct0, getNeutrinoWeight(E, npe));
441 nuDxc.Fill(D, ct0, getNeutrinoWeight(E, D, npe));
442 nuDxU.Fill(D, ct1, getNeutrinoWeight(E, D, npe));
443 nuDxT.Fill(D, t1 - t0, getNeutrinoWeight(E, D, npe));
454 for (map_type::const_iterator
i = npe_pmt.begin();
i != npe_pmt.end(); ++
i) {
455 npe_per_pmt.Fill(
i->second.getTotal());
458 for (map_type::const_iterator
i = npe_type.begin();
i != npe_type.end(); ++
i) {
459 npe_per_type[
i->first]->Fill(
i->second.getTotal());
473 const double E = muon.
getE();
474 const double x =
log10(E);
476 for (JDetector::const_iterator module =
detector.begin(); module !=
detector.end(); ++module) {
480 muExR_tmp->Fill(x, R, module->size());
482 if (R < muRxU.GetXaxis()->GetXmax()) {
483 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
484 muRxU_tmp->Fill(R, muon.
getDot(*pmt));
488 if (R < muRxT.GetXaxis()->GetXmax()) {
489 for (Int_t iy = 1; iy <= muRxT_tmp->GetYaxis()->GetNbins(); ++iy) {
490 muRxT_tmp->Fill(R, muRxT_tmp->GetYaxis()->GetBinCenter(iy), muRxT_tmp->GetYaxis()->GetBinWidth(iy));
504 const double E = neutrino.
getE();
505 const double x =
log10(E);
507 if (inst_vol.is_inside(vertex))
508 hits_per_E_in .Fill(x, NPE);
510 hits_per_E_out.Fill(x, NPE);
512 for (JDetector::const_iterator module =
detector.begin(); module !=
detector.end(); ++module) {
515 const double ct0 = neutrino.
getDot(module->getPosition());
517 nuExD_tmp->Fill(x, D, module->size());
518 nuExc_tmp->Fill(x, ct0, module->size());
519 nuDxc_tmp->Fill(D, ct0, module->size());
521 if (D < nuDxU.GetXaxis()->GetXmax()) {
522 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
523 nuDxU_tmp->Fill(D, neutrino.
getDot(*pmt));
527 if (D < nuDxT.GetXaxis()->GetXmax()) {
528 for (Int_t iy = 1; iy <= nuDxT_tmp->GetYaxis()->GetNbins(); ++iy) {
529 nuDxT_tmp->Fill(D, nuDxT_tmp->GetYaxis()->GetBinCenter(iy), nuDxT_tmp->GetYaxis()->GetBinWidth(iy));
543 TH1D *job_sorted = makeSortedH1(&job,
"hits_by_pdg");
544 TH1D *trks_sorted = makeSortedH1(&trks,
"trks_sorted");
546 if (inputFile.getCounter() != 0) {
548 const Double_t W = 1.0 / ((Double_t) inputFile.getCounter());
550 for (TH1D* p : { &hits, &npe_per_pmt, &job, &trks, job_sorted, trks_sorted }) {
554 for (JManager_t::iterator
i = npe_per_type.begin();
i != npe_per_type.end(); ++
i) {
558 nuExD.Divide(nuExD_tmp);
559 nuExc.Divide(nuExc_tmp);
560 nuDxc.Divide(nuDxc_tmp);
561 nuDxU.Divide(nuDxU_tmp);
562 nuDxT.Divide(nuDxT_tmp);
564 muExR.Divide(muExR_tmp);
565 muRxU.Divide(muRxU_tmp);
566 muRxT.Divide(muRxT_tmp);
576 out << hits << job << *job_sorted << trks << *trks_sorted << hits_per_E_in << hits_per_E_out << npe_per_type << npe_per_pmt;
578 out << nuExD << nuExc << nuDxc << nuDxU << nuDxT;
579 out << muExR << muRxU << muRxT;
Router for direct addressing of PMT data in detector data structure.
Utility class to parse command line options.
JPredicate< JResult_t T::*, JComparison::eq > make_predicate(JResult_t T::*member, const JResult_t value)
Helper method to create predicate for data member.
int main(int argc, char *argv[])
ROOT TTree parameter settings of various packages.
then usage $script< input file >[option[primary[working directory]]] nWhere option can be E
Vec getOffset(const JHead &header)
Get offset.
JTrack3E getTrack(const Trk &track)
Get track.
double geanc()
Equivalent muon track length per unit shower energy.
bool has_neutrino(const Evt &evt)
Test whether given event has an incoming neutrino.
bool is_muon(const Trk &track)
Test whether given track is a (anti-)muon.
double getDot(const JAxis3D &axis) const
Get cosine angle of impact of Cherenkov light on PMT.
#define MAKE_CSTRING(A)
Make C-string.
bool hasPMT(const JObjectID &id) const
Has PMT.
const JPMT & getPMT(const JPMTAddress &address) const
Get PMT.
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
static const JGeaneWater gWater
Function object for energy loss of muon in sea water.
Dynamic ROOT object management.
double getTime(const Hit &hit)
Get true time of hit.
double getDistance(const JVector3D &pos) const
Get distance to point.
size_t getSize(T(&array)[N])
Get size of c-array.
Data structure for detector geometry and calibration.
then echo The file $DIR KM3NeT_00000001_00000000 root already please rename or remove it first
Head getHeader(const JMultipleFileScanner_t &file_list)
Get Monte Carlo header.
Auxiliary class for defining the range of iterations of objects.
The Vec class is a straightforward 3-d vector, which also works in pyroot.
Auxiliary class to manage set of compatible ROOT objects (e.g. histograms) using unique keys...
I/O formatting auxiliaries.
double getE() const
Get energy.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
set_variable E_E log10(E_{fit}/E_{#mu})"
do set_variable OUTPUT_DIRECTORY $WORKDIR T
Data structure for PMT geometry, calibration and status.
JPosition3D getPosition(const Vec &pos)
Get position.
Direct access to PMT in detector data structure.
const JPosition3D & getPosition() const
Get position.
double getT(const JVector3D &pos) const
Get arrival time of Cherenkov light at given position.
General purpose messaging.
then fatal The output file must have the wildcard in the name
virtual double getB() const override
Get energy loss constant.
Scanning of objects from multiple files according a format that follows from the extension of each fi...
JVertex3D getVertex() const
Get vertex of this track.
then JCookie sh JDataQuality D $DETECTOR_ID R
double getDistance(const JVector3D &pos) const
Get distance.
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
General purpose class for object reading from a list of file names.
then fatal The output file must have the wildcard in the e g root fi 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
Utility class to parse command line options.
then set_variable DETECTOR set_variable OUTPUT_FILE set_variable DAQ_FILE set_variable PMT_FILE else fatal Wrong number of arguments fi JPrintTree f $DAQ_FILE type
double getNPE(const Hit &hit)
Get true charge of hit.
const JLimit & getLimit() const
Get limit.
std::map< int, range_type > map_type
const Trk & get_neutrino(const Evt &evt)
Get incoming neutrino.
do set_variable DETECTOR_TXT $WORKDIR detector
double getT(const JVector3D &pos) const
Get arrival time of Cherenkov light at given position.
do echo Generating $dir eval D
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"` source JAcousticsToolkit.sh typeset -A TRIPODS get_tripods $WORKDIR/tripod.txt TRIPODS XMEAN
double getDot(const JAxis3D &axis) const
Get cosine angle of impact of Cherenkov light on PMT.
The Evt class respresent a Monte Carlo (MC) event as well as an offline event.
double getSinThetaC()
Get average sine of Cherenkov angle of water corresponding to group velocity.
#define DEBUG(A)
Message macros.