1744 art::ServiceHandle<geo::Geometry> geom;
1745 art::ServiceHandle<cheat::BackTrackerService> backTracker;
1746 art::ServiceHandle<cheat::ParticleInventoryService> partInventory;
1751 bool isMC = !
evt.isRealData();
1754 art::Handle< std::vector<recob::Hit> > hitListHandle;
1755 std::vector<art::Ptr<recob::Hit> > hitlist;
1757 art::fill_ptr_vector(hitlist, hitListHandle);
1760 art::Handle< std::vector<recob::Vertex> > vtxListHandle;
1761 std::vector<art::Ptr<recob::Vertex> > vtxlist;
1763 art::fill_ptr_vector(vtxlist, vtxListHandle);
1767 art::Handle< std::vector<simb::MCTruth> > mctruthListHandle;
1768 std::vector<art::Ptr<simb::MCTruth> > mclist;
1770 art::fill_ptr_vector(mclist, mctruthListHandle);
1773 art::Handle< std::vector<simb::MCTruth> > mctruthcryListHandle;
1774 std::vector<art::Ptr<simb::MCTruth> > mclistcry;
1777 art::fill_ptr_vector(mclistcry, mctruthcryListHandle);
1780 art::Ptr<simb::MCTruth> mctruthcry;
1781 int nCryPrimaries = 0;
1784 mctruthcry = mclistcry[0];
1785 nCryPrimaries = mctruthcry->NParticles();
1788 int nGeniePrimaries = 0, nGEANTparticles = 0, nMCNeutrinos = 0;
1790 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(
evt);
1791 art::Ptr<simb::MCTruth> mctruth;
1798 if (!mclist.empty()){
1805 static bool isfirsttime =
true;
1807 for (
size_t i = 0; i<hitlist.size(); i++){
1809 std::vector<sim::TrackIDE> eveIDs = backTracker->HitToEveTrackIDEs(clockData, hitlist[i]);
1810 for (
size_t e = 0;
e<eveIDs.size();
e++){
1811 art::Ptr<simb::MCTruth> ev_mctruth = partInventory->TrackIdToMCTruth_P(eveIDs[
e].trackID);
1817 isfirsttime =
false;
1833 mctruth = mclist[0];
1835 if (mctruth->NeutrinoSet()) nGeniePrimaries = mctruth->NParticles();
1838 const sim::ParticleList& plist = partInventory->ParticleList();
1839 nGEANTparticles = plist.size();
1844 MF_LOG_DEBUG(
"AnalysisTree") <<
"Expected "
1845 << nGEANTparticles <<
" GEANT particles, "
1846 << nGeniePrimaries <<
" GENIE particles";
1851 nMCNeutrinos = mclist.size();
1866 const size_t NHits = hitlist.size();
1867 const size_t NVertices = vtxlist.size();
1877 std::vector< art::Handle< std::vector<recob::Track> > > trackListHandle(NTrackers);
1878 std::vector< std::vector<art::Ptr<recob::Track> > > tracklist(NTrackers);
1879 for (
unsigned int it = 0; it < NTrackers; ++it){
1881 art::fill_ptr_vector(tracklist[it], trackListHandle[it]);
1884 art::Handle< std::vector<simb::MCFlux> > mcfluxListHandle;
1885 std::vector<art::Ptr<simb::MCFlux> > fluxlist;
1887 art::fill_ptr_vector(fluxlist, mcfluxListHandle);
1889 std::vector<const sim::AuxDetSimChannel*> fAuxDetSimChannels;
1894 std::vector<const sim::SimChannel*> fSimChannels;
1903 art::Timestamp ts =
evt.time();
1904 TTimeStamp tts(ts.timeHigh(), ts.timeLow());
1908 art::Handle< raw::BeamInfo >
beam;
1909 if (
evt.getByLabel(
"beam",beam)){
1924 mf::LogError(
"AnalysisTree:limits") <<
"event has " << NHits
1925 <<
" hits, only kMaxHits=" <<
kMaxHits <<
" stored in tree";
1927 for (
size_t i = 0; i < NHits && i <
kMaxHits ; ++i){
1948 if (!
evt.isRealData()){
1949 fData -> hit_nelec[i] = 0;
1950 fData -> hit_energy[i] = 0;
1952 for(
size_t sc = 0; sc < fSimChannels.size(); ++sc){
1953 if(fSimChannels[sc]->Channel() == hitlist[i]->Channel()) chan = fSimChannels[sc];
1956 for (
auto const& tdcide: chan->
TDCIDEMap()) {
1958 std::vector<sim::IDE>
const& idevec = tdcide.second;
1959 for(
auto const& ide: idevec) {
1960 fData -> hit_nelec[i] += ide.numElectrons;
1961 fData -> hit_energy[i] += ide.energy;
1971 for (
size_t i = 0; i < NHits && i <
kMaxHits ; ++i){
1972 if (fmtk.isValid()){
1973 if (fmtk.at(i).size()!=0){
1989 mf::LogError(
"AnalysisTree:limits") <<
"event has " << NVertices
1990 <<
" vertices, only kMaxVertices=" <<
kMaxVertices <<
" stored in tree";
1992 for (
size_t i = 0; i < NVertices && i <
kMaxVertices ; ++i){
1993 Double_t xyz[3] = {};
1994 vtxlist[i]->XYZ(xyz);
1995 for (
size_t j = 0; j<3; ++j)
fData->
vtx[i][j] = xyz[j];
2001 for (
unsigned int iTracker=0; iTracker < NTrackers; ++iTracker){
2004 size_t NTracks = tracklist[iTracker].size();
2006 TrackerData.
SetMaxTracks(std::max(NTracks, (
size_t) 1));
2007 TrackerData.Clear();
2009 TrackerData.ntracks = (int) NTracks;
2014 if (NTracks > TrackerData.GetMaxTracks()) {
2017 mf::LogError(
"AnalysisTree:limits") <<
"event has " << NTracks
2019 << TrackerData.GetMaxTracks() <<
" stored in tree";
2025 for(
size_t iTrk=0; iTrk < NTracks; ++iTrk){
2030 if (fmct.isValid()){
2031 TrackerData.trkncosmictags_tagger[iTrk] = fmct.at(iTrk).size();
2032 if (fmct.at(iTrk).size()>0){
2033 if(fmct.at(iTrk).size()>1)
2035 TrackerData.trkcosmicscore_tagger[iTrk] = fmct.at(iTrk).at(0)->CosmicScore();
2036 TrackerData.trkcosmictype_tagger[iTrk] = fmct.at(iTrk).at(0)->CosmicType();
2045 if (fmbfm.isValid()){
2046 TrackerData.trkncosmictags_flashmatch[iTrk] = fmbfm.at(iTrk).size();
2047 if (fmbfm.at(iTrk).size()>0){
2048 if(fmbfm.at(iTrk).size()>1)
2049 std::cerr <<
"\n Warning : more than one cosmic tag per track in module! assigning the first tag to the track" <<
fFlashMatchAssocLabel[iTracker];
2050 TrackerData.trkcosmicscore_flashmatch[iTrk] = fmbfm.at(iTrk).at(0)->CosmicScore();
2051 TrackerData.trkcosmictype_flashmatch[iTrk] = fmbfm.at(iTrk).at(0)->CosmicType();
2057 art::Ptr<recob::Track> ptrack(trackListHandle[iTracker], iTrk);
2075 TrackID = track.
ID();
2077 double theta_xz = std::atan2(dir_start.X(), dir_start.Z());
2078 double theta_yz = std::atan2(dir_start.Y(), dir_start.Z());
2079 double dpos =
bdist(pos);
2080 double dend =
bdist(end);
2082 TrackerData.trkId[iTrk] =
TrackID;
2083 TrackerData.trkstartx[iTrk] = pos.X();
2084 TrackerData.trkstarty[iTrk] = pos.Y();
2085 TrackerData.trkstartz[iTrk] = pos.Z();
2086 TrackerData.trkstartd[iTrk] = dpos;
2087 TrackerData.trkendx[iTrk] = end.X();
2088 TrackerData.trkendy[iTrk] = end.Y();
2089 TrackerData.trkendz[iTrk] = end.Z();
2090 TrackerData.trkendd[iTrk] = dend;
2091 TrackerData.trktheta[iTrk] = dir_start.Theta();
2092 TrackerData.trkphi[iTrk] = dir_start.Phi();
2093 TrackerData.trkstartdcosx[iTrk] = dir_start.X();
2094 TrackerData.trkstartdcosy[iTrk] = dir_start.Y();
2095 TrackerData.trkstartdcosz[iTrk] = dir_start.Z();
2096 TrackerData.trkenddcosx[iTrk] = dir_end.X();
2097 TrackerData.trkenddcosy[iTrk] = dir_end.Y();
2098 TrackerData.trkenddcosz[iTrk] = dir_end.Z();
2099 TrackerData.trkthetaxz[iTrk] = theta_xz;
2100 TrackerData.trkthetayz[iTrk] = theta_yz;
2102 TrackerData.trklen[iTrk] = tlen;
2135 Float_t minsdist = 10000;
2136 Float_t minedist = 10000;
2138 Float_t sdist = sqrt(pow(TrackerData.trkstartx[iTrk]-
fData->
vtx[ivx][0],2)+
2139 pow(TrackerData.trkstarty[iTrk]-
fData->
vtx[ivx][1],2)+
2140 pow(TrackerData.trkstartz[iTrk]-
fData->
vtx[ivx][2],2));
2141 Float_t edist = sqrt(pow(TrackerData.trkendx[iTrk]-
fData->
vtx[ivx][0],2)+
2142 pow(TrackerData.trkendy[iTrk]-
fData->
vtx[ivx][1],2)+
2143 pow(TrackerData.trkendz[iTrk]-
fData->
vtx[ivx][2],2));
2144 if (sdist<minsdist){
2146 if (minsdist<10) TrackerData.trksvtxid[iTrk] = ivx;
2148 if (edist<minedist){
2150 if (minedist<10) TrackerData.trkevtxid[iTrk] = ivx;
2155 if(fmpid.isValid()) {
2156 std::vector<const anab::ParticleID*> pids = fmpid.at(iTrk);
2157 if (pids.size() == 0){
2158 mf::LogError(
"AnalysisTree:limits")
2160 <<
" track " << iTrk <<
". Not saving particleID information.";
2163 double pidpdg[3] = {0,0,0};
2164 double pidchi[3] = {0.,0.,0.};
2165 for(
size_t planenum=0; planenum<3; ++planenum) {
2166 TrackerData.trkpidchimu[iTrk][planenum] = 0.;
2167 TrackerData.trkpidchipi[iTrk][planenum] = 0.;
2168 TrackerData.trkpidchika[iTrk][planenum] = 0.;
2169 TrackerData.trkpidchipr[iTrk][planenum] = 0.;
2170 TrackerData.trkpidpida[iTrk][planenum] = 0.;
2172 for (
size_t ipid=0; ipid<pids.size(); ipid++){
2173 std::vector<anab::sParticleIDAlgScores> AlgScoresVec = pids[ipid]->ParticleIDAlgScores();
2176 for (
size_t i_algscore=0; i_algscore<AlgScoresVec.size(); i_algscore++){
2189 if (AlgScore.
fPlaneMask.test(0)) planenum = 0;
2190 if (AlgScore.
fPlaneMask.test(1)) planenum = 1;
2191 if (AlgScore.
fPlaneMask.test(2)) planenum = 2;
2192 if (planenum<0 || planenum>2)
continue;
2196 TrackerData.trkpidchimu[iTrk][planenum] = AlgScore.
fValue;
2197 if (AlgScore.
fValue<pidchi[planenum] || (pidchi[planenum] == 0. && AlgScore.
fValue>0.)){
2198 pidchi[planenum] = AlgScore.
fValue;
2199 pidpdg[planenum] = TMath::Abs(AlgScore.
fAssumedPdg);
2202 else if (TMath::Abs(AlgScore.
fAssumedPdg) == 2212){
2203 TrackerData.trkpidchipr[iTrk][planenum] = AlgScore.
fValue;
2204 if (AlgScore.
fValue<pidchi[planenum] || (pidchi[planenum] == 0. && AlgScore.
fValue>0.)){
2205 pidchi[planenum] = AlgScore.
fValue;
2206 pidpdg[planenum] = TMath::Abs(AlgScore.
fAssumedPdg);
2209 else if (TMath::Abs(AlgScore.
fAssumedPdg) == 211){
2210 TrackerData.trkpidchipi[iTrk][planenum] = AlgScore.
fValue;
2211 if (AlgScore.
fValue<pidchi[planenum] || (pidchi[planenum] == 0. && AlgScore.
fValue>0.)){
2212 pidchi[planenum] = AlgScore.
fValue;
2213 pidpdg[planenum] = TMath::Abs(AlgScore.
fAssumedPdg);
2216 else if (TMath::Abs(AlgScore.
fAssumedPdg) == 321){
2217 TrackerData.trkpidchika[iTrk][planenum] = AlgScore.
fValue;
2218 if (AlgScore.
fValue<pidchi[planenum] || (pidchi[planenum] == 0. && AlgScore.
fValue>0.)){
2219 pidchi[planenum] = AlgScore.
fValue;
2220 pidpdg[planenum] = TMath::Abs(AlgScore.
fAssumedPdg);
2226 TrackerData.trkpidpida[iTrk][planenum] = AlgScore.
fValue;
2233 for (
size_t planenum=0; planenum<3; planenum++){
2234 TrackerData.trkpidchi[iTrk][planenum] = pidchi[planenum];
2235 TrackerData.trkpidpdg[iTrk][planenum] = pidpdg[planenum];
2242 if (fmcal.isValid()){
2243 std::vector<const anab::Calorimetry*> calos = fmcal.at(iTrk);
2244 if (calos.size() > TrackerData.GetMaxPlanesPerTrack(iTrk)) {
2247 mf::LogError(
"AnalysisTree:limits")
2249 <<
" has " << calos.size() <<
" planes for calorimetry , only "
2250 << TrackerData.GetMaxPlanesPerTrack(iTrk) <<
" stored in tree";
2252 for (
size_t ical = 0; ical<calos.size(); ++ical){
2253 if (!calos[ical])
continue;
2254 if (!calos[ical]->
PlaneID().isValid)
continue;
2255 int planenum = calos[ical]->PlaneID().Plane;
2256 if (planenum<0||planenum>2)
continue;
2257 TrackerData.trkke[iTrk][planenum] = calos[ical]->KineticEnergy();
2258 TrackerData.trkrange[iTrk][planenum] = calos[ical]->Range();
2260 TrackerData.trkpitchc[iTrk][planenum]= calos[ical] -> TrkPitchC();
2261 const size_t NHits = calos[ical] ->
dEdx().size();
2262 TrackerData.ntrkhits[iTrk][planenum] = (int) NHits;
2263 if (NHits > TrackerData.GetMaxHitsPerTrack(iTrk, planenum)) {
2265 mf::LogError(
"AnalysisTree:limits")
2267 <<
" has " << NHits <<
" hits on calorimetry plane #" << planenum
2269 << TrackerData.GetMaxHitsPerTrack(iTrk, planenum) <<
" stored in tree";
2272 for(
size_t iTrkHit = 0; iTrkHit < NHits && iTrkHit < TrackerData.GetMaxHitsPerTrack(iTrk, planenum); ++iTrkHit) {
2273 TrackerData.trkdedx[iTrk][planenum][iTrkHit] = (calos[ical] ->
dEdx())[iTrkHit];
2274 TrackerData.trkdqdx[iTrk][planenum][iTrkHit] = (calos[ical] -> dQdx())[iTrkHit];
2275 TrackerData.trkresrg[iTrk][planenum][iTrkHit] = (calos[ical] -> ResidualRange())[iTrkHit];
2276 const auto& TrkPos = (calos[ical] -> XYZ())[iTrkHit];
2277 auto& TrkXYZ = TrackerData.trkxyz[iTrk][planenum][iTrkHit];
2278 TrkXYZ[0] = TrkPos.X();
2279 TrkXYZ[1] = TrkPos.Y();
2280 TrkXYZ[2] = TrkPos.Z();
2281 TrackerData.trkxp[iTrk][planenum][iTrkHit] = TrkPos.X();
2282 TrackerData.trkyp[iTrk][planenum][iTrkHit] = TrkPos.Y();
2283 TrackerData.trkzp[iTrk][planenum][iTrkHit] = TrkPos.Z();
2287 if(TrackerData.ntrkhits[iTrk][0] > TrackerData.ntrkhits[iTrk][1] && TrackerData.ntrkhits[iTrk][0] > TrackerData.ntrkhits[iTrk][2]) TrackerData.trkpidbestplane[iTrk] = 0;
2288 else if(TrackerData.ntrkhits[iTrk][1] > TrackerData.ntrkhits[iTrk][0] && TrackerData.ntrkhits[iTrk][1] > TrackerData.ntrkhits[iTrk][2]) TrackerData.trkpidbestplane[iTrk] = 1;
2289 else if(TrackerData.ntrkhits[iTrk][2] > TrackerData.ntrkhits[iTrk][0] && TrackerData.ntrkhits[iTrk][2] > TrackerData.ntrkhits[iTrk][1]) TrackerData.trkpidbestplane[iTrk] = 2;
2290 else if(TrackerData.ntrkhits[iTrk][2] == TrackerData.ntrkhits[iTrk][0] && TrackerData.ntrkhits[iTrk][2] > TrackerData.ntrkhits[iTrk][1]) TrackerData.trkpidbestplane[iTrk] = 2;
2291 else if(TrackerData.ntrkhits[iTrk][2] == TrackerData.ntrkhits[iTrk][1] && TrackerData.ntrkhits[iTrk][2] > TrackerData.ntrkhits[iTrk][0]) TrackerData.trkpidbestplane[iTrk] = 2;
2292 else if(TrackerData.ntrkhits[iTrk][1] == TrackerData.ntrkhits[iTrk][0] && TrackerData.ntrkhits[iTrk][1] > TrackerData.ntrkhits[iTrk][2]) TrackerData.trkpidbestplane[iTrk] = 0;
2293 else if(TrackerData.ntrkhits[iTrk][1] == TrackerData.ntrkhits[iTrk][0] && TrackerData.ntrkhits[iTrk][1] == TrackerData.ntrkhits[iTrk][2]) TrackerData.trkpidbestplane[iTrk] = 2;
2300 std::vector< art::Ptr<recob::Hit> > allHits = fmht.at(iTrk);
2301 std::vector< art::Ptr<recob::Hit> > hits[
kNplanes];
2303 for(
size_t ah = 0; ah < allHits.size(); ++ah){
2305 allHits[ah]->
WireID().Plane < 3){
2306 hits[allHits[ah]->WireID().Plane].push_back(allHits[ah]);
2310 for (
size_t ipl = 0; ipl < 3; ++ipl){
2315 HitsPurity(clockData, hits[ipl],TrackerData.trkidtruth[iTrk][ipl],TrackerData.trkpurtruth[iTrk][ipl],maxe);
2317 if (TrackerData.trkidtruth[iTrk][ipl]>0){
2318 const art::Ptr<simb::MCTruth> mc = partInventory->TrackIdToMCTruth_P(TrackerData.trkidtruth[iTrk][ipl]);
2319 TrackerData.trkorigin[iTrk][ipl] = mc->Origin();
2320 const simb::MCParticle *particle = partInventory->TrackIdToParticle_P(TrackerData.trkidtruth[iTrk][ipl]);
2322 const std::vector<const sim::IDE*> vide(backTracker->TrackIdToSimIDEs_Ps(TrackerData.trkidtruth[iTrk][ipl]));
2323 for (
auto ide: vide) {
2324 tote += ide->energy;
2325 TrackerData.trksimIDEenergytruth[iTrk][ipl] = ide->energy;
2326 TrackerData.trksimIDExtruth[iTrk][ipl] = ide->x;
2327 TrackerData.trksimIDEytruth[iTrk][ipl] = ide->y;
2328 TrackerData.trksimIDEztruth[iTrk][ipl] = ide->z;
2330 TrackerData.trkpdgtruth[iTrk][ipl] = particle->PdgCode();
2331 TrackerData.trkefftruth[iTrk][ipl] = maxe/(tote/
kNplanes);
2350 for(Int_t iPartc = 0; iPartc < mctruthcry->NParticles(); ++iPartc){
2351 const simb::MCParticle& partc(mctruthcry->GetParticle(iPartc));
2383 for (
unsigned int i_mctruth = 0; i_mctruth < mclist.size(); i_mctruth++){
2385 art::Ptr<simb::MCTruth> curr_mctruth = mclist[i_mctruth];
2387 if (!curr_mctruth->NeutrinoSet())
continue;
2388 fData->
nuPDG_truth[i_mctruth] = curr_mctruth->GetNeutrino().Nu().PdgCode();
2391 fData->
Q2_truth[i_mctruth] = curr_mctruth->GetNeutrino().QSqr();
2392 fData->
W_truth[i_mctruth] = curr_mctruth->GetNeutrino().W();
2394 fData->
enu_truth[i_mctruth] = curr_mctruth->GetNeutrino().Nu().E();
2398 if (curr_mctruth->GetNeutrino().Nu().P()){
2399 fData->
nu_dcosx_truth[i_mctruth] = curr_mctruth->GetNeutrino().Nu().Px()/curr_mctruth->GetNeutrino().Nu().P();
2400 fData->
nu_dcosy_truth[i_mctruth] = curr_mctruth->GetNeutrino().Nu().Py()/curr_mctruth->GetNeutrino().Nu().P();
2401 fData->
nu_dcosz_truth[i_mctruth] = curr_mctruth->GetNeutrino().Nu().Pz()/curr_mctruth->GetNeutrino().Nu().P();
2404 if (curr_mctruth->GetNeutrino().Lepton().P()){
2405 fData->
lep_dcosx_truth[i_mctruth] = curr_mctruth->GetNeutrino().Lepton().Px()/curr_mctruth->GetNeutrino().Lepton().P();
2406 fData->
lep_dcosy_truth[i_mctruth] = curr_mctruth->GetNeutrino().Lepton().Py()/curr_mctruth->GetNeutrino().Lepton().P();
2407 fData->
lep_dcosz_truth[i_mctruth] = curr_mctruth->GetNeutrino().Lepton().Pz()/curr_mctruth->GetNeutrino().Lepton().P();
2415 if (fmFluxNeutrino.isValid()){
2416 art::Ptr<simb::MCFlux> curr_mcflux = fmFluxNeutrino.at(i_mctruth);
2427 if (mctruth->NeutrinoSet()){
2468 mf::LogError(
"AnalysisTree:limits") <<
"event has "
2470 << StoreParticles <<
" stored in tree";
2472 for(
size_t iPart = 0; iPart < StoreParticles; ++iPart){
2473 const simb::MCParticle& part(mctruth->GetParticle(iPart));
2491 const sim::ParticleList& plist = partInventory->ParticleList();
2493 std::string pri(
"primary");
2496 int geant_particle=0;
2497 sim::ParticleList::const_iterator itPart = plist.begin(),
2500 for(
size_t iPart = 0; (iPart < plist.size()) && (itPart != pend); ++iPart){
2501 const simb::MCParticle* pPart = (itPart++)->
second;
2503 throw art::Exception(art::errors::LogicError)
2504 <<
"GEANT particle #" << iPart <<
" returned a null pointer";
2508 bool isPrimary = pPart->Process() == pri;
2509 if (isPrimary) ++primary;
2511 int TrackID = pPart->TrackId();
2513 TVector3 mcstart, mcend;
2514 double plen =
length(*pPart, mcstart, mcend);
2516 bool isActive = plen != 0;
2519 if (iPart < fData->GetMaxGEANTparticles()) {
2520 if (pPart->E()>
fG4minE||isPrimary){
2525 fData->
pdg[iPart]=pPart->PdgCode();
2533 fData->
P[iPart]=pPart->Momentum().Vect().Mag();
2542 fData->
theta[iPart] = pPart->Momentum().Theta();
2543 fData->
phi[iPart] = pPart->Momentum().Phi();
2544 fData->
theta_xz[iPart] = std::atan2(pPart->Px(), pPart->Pz());
2545 fData->
theta_yz[iPart] = std::atan2(pPart->Py(), pPart->Pz());
2561 const art::Ptr<simb::MCTruth>& matched_mctruth = partInventory->ParticleToMCTruth_P(pPart);
2566 unsigned short nAD = 0;
2573 const std::vector<sim::AuxDetIDE>& setOfIDEs = c->AuxDetIDEs();
2578 std::vector<sim::AuxDetIDE>::const_iterator iIDE
2580 setOfIDEs.begin(), setOfIDEs.end(),
2583 if (iIDE == setOfIDEs.end())
continue;
2591 for(
const auto& adtracks: setOfIDEs) {
2592 if( fabs(adtracks.trackID) ==
TrackID )
2593 totalE += adtracks.energyDeposited;
2618 mf::LogError(
"AnalysisTree:limits") <<
"particle #" << iPart
2619 <<
" touches " << nAD <<
" auxiliary detector cells, only "
2620 <<
kMaxAuxDets <<
" of them are saved in the tree";
2627 mf::LogError(
"AnalysisTree:limits") <<
"event has "
2628 << plist.size() <<
" MC particles, only "
2637 MF_LOG_DEBUG(
"AnalysisTree") <<
"Counted "
2646 std::map<int, size_t> TrackIDtoIndex;
2648 for (
size_t index = 0; index < nTrackIDs; ++index)
2654 int currentMergedId = 1;
2663 while(currentMotherTrackId > 0) {
2665 std::map<int, size_t>::const_iterator iMother
2666 = TrackIDtoIndex.find(currentMotherTrackId);
2667 if (iMother == TrackIDtoIndex.end())
break;
2668 size_t currentMotherIndex = iMother->second;
2676 currentMotherTrackId =
fData->
Mother[currentMotherIndex];
2687 if (mf::isDebugEnabled()) {
2690 mf::LogDebug logStream(
"AnalysisTreeStructure");
2692 <<
"Tree data structure contains:"
2701 size_t iTracker = 0;
2707 <<
" tracks (" << tracker->GetMaxTracks() <<
")"
2709 for (
int iTrk = 0; iTrk < tracker->ntracks; ++iTrk) {
2710 logStream <<
"\n [" << iTrk <<
"] "<< tracker->ntrkhits[iTrk][0];
2711 for (
size_t ipl = 1; ipl < tracker->GetMaxPlanesPerTrack(iTrk); ++ipl)
2712 logStream <<
" + " << tracker->ntrkhits[iTrk][ipl];
2713 logStream <<
" hits (" << tracker->GetMaxHitsPerTrack(iTrk, 0);
2714 for (
size_t ipl = 1; ipl < tracker->GetMaxPlanesPerTrack(iTrk); ++ipl)
2715 logStream <<
" + " << tracker->GetMaxHitsPerTrack(iTrk, ipl);
2724 MF_LOG_DEBUG(
"AnalysisTreeStructure") <<
"Freeing the tree data structure";
void ClearLocalData()
Clear all fields if this object (not the tracker algorithm data)
std::vector< Int_t > cry_trackID
std::vector< std::string > processname
std::vector< Float_t > cry_StartPointx
std::vector< Float_t > Eng
std::vector< Int_t > process_primary
std::vector< Float_t > StartPointz
std::vector< Float_t > lep_mom_truth
std::vector< Float_t > lep_dcosz_truth
std::vector< Float_t > StartPointx
std::vector< Int_t > TrackId
bool isCosmics
if it contains cosmics
Short_t hit_tpc[kMaxHits]
std::vector< UShort_t > NAuxDets
Number of AuxDets crossed by this particle.
std::vector< Float_t > StartPointy_tpcAV
Energy deposited on a readout channel by simulated tracks.
int TrueParticleIDFromTotalTrueEnergy(detinfo::DetectorClocksData const &clockData, const std::vector< art::Ptr< recob::Hit > > &hits, bool rollup_unsaved_ids=1)
double length(const recob::Track &track)
SubRunData_t SubRunData
subrun data collected at begin of subrun
std::vector< Float_t > W_truth
void ResizeGenie(int nPrimaries)
Resize the data strutcure for Genie primaries.
BEGIN_PROLOG could also be cerr
std::vector< Int_t > genie_trackID
std::vector< Float_t > EndPointy
void ResizeMCNeutrino(int nNeutrinos)
Resize the data structure for MCNeutrino particles.
Short_t hit_trkid[kMaxHits]
std::vector< Float_t > EndPointx_tpcAV
std::vector< Float_t > lep_dcosx_truth
Int_t geant_list_size_in_tpcAV
bool fSaveTrackInfo
whether to extract and save Hit information
size_t GetMaxGEANTparticles() const
Returns the number of GEANT particles for which memory is allocated.
AuxDetMCData_t< Float_t > entryY
Entry Y position of particle into AuxDet.
Float_t hit_peakT[kMaxHits]
constexpr unsigned short kMaxVertices
size_t GetMaxGeniePrimaries() const
Returns the number of GENIE primaries for which memory is allocated.
std::vector< Float_t > cry_Py
AuxDetMCData_t< Float_t > exitPz
Exit z momentum of particle out of AuxDet.
void SetMaxTracks(size_t maxTracks)
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
Vector_t VertexDirection() const
double bdist(const recob::tracking::Point_t &pos)
std::vector< Float_t > theta
std::vector< std::string > fTrackModuleLabel
std::vector< Float_t > nu_dcosy_truth
std::vector< Float_t > Py
std::vector< Float_t > genie_P
bool fSaveAuxDetInfo
whether to extract and save auxiliary detector data
std::string fGenieGenModuleLabel
std::vector< Float_t > lep_dcosy_truth
process_name use argoneut_mc_hitfinder track
TrackDataStruct & GetTrackerData(size_t iTracker)
std::vector< Float_t > nuvtxz_truth
AuxDetMCData_t< Float_t > entryX
Entry X position of particle into AuxDet.
std::vector< TrackDataStruct > TrackData
bool fUseBuffer
whether to use a permanent buffer (faster, huge memory)
float fValue
Result of Particle ID algorithm/test.
std::vector< Int_t > genie_mother
std::vector< Float_t > StartPointy
std::vector< Float_t > cry_Px
void DestroyData()
Destroy the local buffers (existing branches will point to invalid address!)
std::vector< std::string > fCosmicTaggerAssocLabel
whether to extract and save Vertex information
AuxDetMCData_t< Float_t > entryZ
Entry Z position of particle into AuxDet.
std::vector< Float_t > nuvtxy_truth
std::vector< std::string > fFlashMatchAssocLabel
std::vector< Int_t > inTPCActive
std::vector< Float_t > genie_Eng
AuxDetMCData_t< Float_t > exitPx
Exit x momentum of particle out of AuxDet.
std::bitset< 8 > fPlaneMask
Bitset for PlaneID used by algorithm, allowing for multiple planes and up to 8 total planes...
std::vector< Int_t > ccnc_truth
AuxDetMCData_t< Float_t > entryT
Entry T position of particle into AuxDet.
std::vector< Float_t > EndPointy_tpcAV
IDparameter< geo::PlaneID > PlaneID
Member type of validated geo::PlaneID parameter.
std::string fLArG4ModuleLabel
std::vector< Float_t > Q2_truth
std::vector< Float_t > EndPointx
std::string fAlgName
< determined particle ID
AnalysisTreeDataStruct::SubRunData_t SubRunData
std::vector< Float_t > cry_Eng
Collection of particles crossing one auxiliary detector cell.
void HitsPurity(detinfo::DetectorClocksData const &clockData, std::vector< art::Ptr< recob::Hit > > const &hits, Int_t &trackid, Float_t &purity, double &maxe)
std::vector< Float_t > nu_dcosx_truth
void ResizeGEANT(int nParticles)
Resize the data strutcure for GEANT particles.
std::vector< Float_t > EndE
std::vector< Float_t > StartPointx_tpcAV
std::vector< Int_t > cry_ND
kVariableType fVariableType
Variable type enum: defined in ParticleID_VariableTypeEnums.h. Set to kNotSet by default.
Short_t hit_plane[kMaxHits]
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< Coord_t >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space. See recob::tracking::Coord_t for more details on the ...
Int_t no_primaries
! how many particles there is currently room for
Int_t mcevts_truth
! The number of MCNeutrinos there is currently room for
bool fSaveHitInfo
whether to extract and save Geant information
std::vector< Float_t > phi
std::vector< Float_t > Mass
Float_t vtx[kMaxVertices][3]
std::vector< Int_t > cry_status_code
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
AuxDetMCData_t< Float_t > exitT
Exit T position of particle out of AuxDet.
std::vector< Float_t > cry_Pz
std::vector< Float_t > genie_Px
std::vector< Float_t > tpy_flux
std::vector< Float_t > pathlen
std::vector< Int_t > cry_mother
std::vector< Float_t > cry_StartPointz
std::vector< Int_t > nuID_truth
std::string fHitsModuleLabel
AuxDetMCData_t< Float_t > CombinedEnergyDep
Sum energy of all particles with this trackID (+ID or -ID) in AuxDet.
Point_t const & Vertex() const
AuxDetMCData_t< Float_t > exitX
Exit X position of particle out of AuxDet.
auto end(FixedBins< T, C > const &) noexcept
Float_t hit_endT[kMaxHits]
std::vector< Float_t > Px
std::vector< Float_t > enu_truth
std::vector< Float_t > StartPointz_tpcAV
std::vector< Int_t > MergedId
std::vector< Int_t > cry_primaries_pdg
int TrueParticleIDFromTotalRecoHits(detinfo::DetectorClocksData const &clockData, const std::vector< art::Ptr< recob::Hit > > &hits, bool rollup_unsaved_ids=1)
std::vector< Int_t > MotherNuId
Short_t hit_wire[kMaxHits]
size_t GetMaxHits() const
Returns the number of hits for which memory is allocated.
std::vector< Int_t > mode_truth
float dEdx(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, TP3D &tp3d)
std::vector< Float_t > tpx_flux
Float_t hit_charge[kMaxHits]
std::vector< Float_t > genie_mass
std::vector< std::string > fCalorimetryModuleLabel
AuxDetMCData_t< Float_t > exitZ
Exit Z position of particle out of AuxDet.
std::vector< Float_t > cry_mass
void SetTrackerAddresses(size_t iTracker)
std::vector< Int_t > genie_ND
std::vector< Float_t > cry_StartPointy
void ResizeCry(int nPrimaries)
Resize the data strutcure for Cry primaries.
std::vector< Int_t > NumberDaughters
std::vector< Float_t > EndPointz
std::vector< Int_t > genie_status_code
Float_t hit_startT[kMaxHits]
size_t GetNTrackers() const
Returns the number of trackers configured.
std::vector< Float_t > Pz
std::vector< Float_t > EndT
void CreateTree(bool bClearData=false)
Create the output tree and the data structures, if needed.
std::vector< Float_t > theta_yz
std::vector< std::string > fParticleIDModuleLabel
AuxDetMCData_t< Float_t > exitY
Exit Y position of particle out of AuxDet.
AuxDetMCData_t< Short_t > AuxDetID
Which AuxDet this particle went through.
bool fSaveCaloCosmics
save calorimetry information for cosmics
Vector_t EndDirection() const
MC truth information to make RawDigits and do back tracking.
std::vector< Int_t > tptype_flux
std::vector< Float_t > cry_P
std::vector< Int_t > status
Short_t hit_channel[kMaxHits]
std::vector< Int_t > genie_primaries_pdg
std::vector< Float_t > StartT
std::string fCryGenModuleLabel
bool fSaveGenieInfo
whether to extract and save CRY particle data
Point_t const & End() const
std::vector< Float_t > EndPointz_tpcAV
TDCIDEs_t const & TDCIDEMap() const
Returns all the deposited energy information as stored.
std::string fVertexModuleLabel
std::vector< Float_t > genie_Py
int TrueParticleIDFromTotalRecoCharge(detinfo::DetectorClocksData const &clockData, const std::vector< art::Ptr< recob::Hit > > &hits, bool rollup_unsaved_ids=1)
AnalysisTreeDataStruct * fData
bool fSaveGeantInfo
whether to extract and save Genie information
AuxDetMCData_t< Float_t > exitPy
Exit y momentum of particle out of AuxDet.
std::vector< Float_t > theta_xz
std::vector< Float_t > tpz_flux
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< Coord_t >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space. See recob::tracking::Coord_t for more detai...
std::vector< Float_t > nuvtxx_truth
std::vector< Float_t > genie_Pz
std::vector< Int_t > hitnuc_truth
void CreateData(bool bClearData=false)
Creates the structure for the tree data; optionally initializes it.
std::vector< Int_t > nuPDG_truth
std::vector< Float_t > nu_dcosz_truth
bool fSaveVertexInfo
whether to extract and save Track information
std::vector< Int_t > Mother
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
int fAssumedPdg
PDG of particle hypothesis assumed by algorithm, if applicable. Set to 0 by default.
constexpr unsigned short kMaxAuxDets
max number of auxiliary detector cells per MC particle