18 #include "art_root_io/TFileService.h" 23 #include "canvas/Persistency/Common/FindOne.h" 24 #include "canvas/Persistency/Common/FindOneP.h" 25 #include "canvas/Persistency/Common/FindMany.h" 26 #include "canvas/Persistency/Common/FindManyP.h" 30 #include "MCCheater/BackTracker.h" 36 #include "CoreUtils/ServiceUtil.h" 40 #include "nurandom/RandomUtils/NuRandomService.h" 45 #include "TDatabasePDG.h" 46 #include "TParticlePDG.h" 49 #include "CLHEP/Random/RandFlat.h" 53 #include <unordered_map> 57 typedef std::pair<float, std::string>
P;
84 static bool lessThan_byE(std::pair<float,float>
a, std::pair<float,float>
b) {
return a.first < b.first;}
233 std::vector<Float_t>
fW;
234 std::vector<Float_t>
fX;
235 std::vector<Float_t>
fY;
237 std::vector<Float_t>
fT;
281 float MCPtoVertDefault = 10.0*std::numeric_limits<Float_t>::epsilon();
286 consumesMany<std::vector<simb::MCTruth> >();
287 consumes<std::vector<simb::MCParticle> >(
fGeantLabel);
313 fGeo = gar::providerFrom<geo::GeometryGAr>();
329 fconfig = tfs->make<TTree>(
"config",
"config");
330 fconfig->Branch(
"tpccentre", &ftpccentre,
"tpccentre[3]/D");
342 fTree = tfs->make<TTree>(
"GArAnaTree",
"GArAnaTree");
426 fTruthTree = tfs->make<TTree>(
"GArTruthTree",
"GArTruthTree");
467 TFile
infile(filename.c_str(),
"READ");
471 for(
int q = 0; q < 501; ++q){
472 sprintf(str,
"%d", q);
477 m_pidinterp.insert( std::make_pair(q, (TH2F*)
infile.Get(s.c_str())->Clone(
"pidinterp")) );
623 auto TrackHandle =
event.getHandle< std::vector<rec::Track> >(
fTrackLabel);
626 <<
" Line " << __LINE__ <<
" in file " << __FILE__ <<
std::endl;
628 auto RecoClusterHandle =
event.getHandle< std::vector<rec::Cluster> >(
fClusterLabel);
629 if (!RecoClusterHandle) {
631 <<
" Line " << __LINE__ <<
" in file " << __FILE__ <<
std::endl;
634 auto TrackIonHandle =
event.getHandle< std::vector<rec::TrackIoniz> >(
fTrackLabel);
635 if (!TrackIonHandle) {
636 throw cet::exception(
"HNLAnalysis") <<
" No rec::TrackIoniz branch." 637 <<
" Line " << __LINE__ <<
" in file " << __FILE__ <<
std::endl;
640 art::FindOneP<rec::TrackIoniz>* findIonization = NULL;
641 findIonization =
new art::FindOneP<rec::TrackIoniz>(TrackHandle,
event,
fTrackLabel);
643 art::FindManyP<rec::Track, rec::TrackEnd>* findManyCALTrackEnd = NULL;
644 findManyCALTrackEnd =
new art::FindManyP<rec::Track, rec::TrackEnd>(RecoClusterHandle,
event,
fECALAssnLabel);
648 auto mctruthHandles =
event.getMany<std::vector<simb::MCTruth> >();
649 if (mctruthHandles.size()!=1) {
650 throw cet::exception(
"HNLAnalysis") <<
" Need just 1 simb::MCTruth" 651 <<
" Line " << __LINE__ <<
" in file " << __FILE__ <<
std::endl;
654 auto MCPHandle =
event.getHandle< std::vector<simb::MCParticle> >(
fGeantLabel);
657 <<
" Line " << __LINE__ <<
" in file " << __FILE__ <<
std::endl;
663 fEvent =
event.id().event();
668 for (
size_t imchl = 0; imchl < mctruthHandles.size(); ++imchl) {
669 for (
auto const& mct : (*mctruthHandles.at(imchl)) ) {
670 if(mct.NeutrinoSet()){
677 fW.push_back(nuw.
W());
678 fX.push_back(nuw.
X());
679 fY.push_back(nuw.
Y());
715 int nparticles = mct.NParticles();
716 for(
int i = 0; i < nparticles; i++){
726 fMCP_X.push_back(position.X());
727 fMCP_Y.push_back(position.Y());
728 fMCP_Z.push_back(position.Z());
730 fMCP_PX.push_back(momentum.Px());
731 fMCP_PY.push_back(momentum.Py());
732 fMCP_PZ.push_back(momentum.Pz());
734 TVector3 nupos(position.X(), position.Y(), position.Z());
746 std::unordered_map<TrkId, Int_t> TrackIdToIndex;
748 for (
auto const& mcp : (*MCPHandle) ) {
749 int TrackId = mcp.TrackId();
750 TrackIdToIndex[TrackId] = index++;
755 for (
auto const& track : (*TrackHandle) ) {
757 std::vector<std::pair<simb::MCParticle*,float>> MCsfromTrack;
760 int nMCsfromTrack = MCsfromTrack.size();
761 if(nMCsfromTrack==0){
766 for (
int iMCfromTrack =0; iMCfromTrack<nMCsfromTrack; ++iMCfromTrack) {
768 theMCPart = *(MCsfromTrack[iMCfromTrack].first);
770 if ( particle->Charge() == 0.0 )
continue;
771 if ( particle->Stable() == 0 )
continue;
779 bool whackThatECAL =
false;
780 for (
int iTraj=0; iTraj<nTraj; ++iTraj) {
781 doink.SetXYZ(theMCPart.
Vx(iTraj),theMCPart.
Vy(iTraj),theMCPart.
Vz(iTraj));
783 whackThatECAL =
true;
791 const TLorentzVector& positionMCP = theMCPart.
Position(0);
792 float distStart =
std::hypot(track.Vertex()[0] -positionMCP[0],
793 track.Vertex()[1] -positionMCP[1],
794 track.Vertex()[2] -positionMCP[2]);
795 float distEnd =
std::hypot(track.End()[0] -positionMCP[0],
796 track.End()[1] -positionMCP[1],
797 track.End()[2] -positionMCP[2]);
801 std::vector< std::pair<int, float> >
pid;
806 fTrackX.push_back (track.Vertex()[0]);
807 fTrackY.push_back (track.Vertex()[1]);
808 fTrackZ.push_back (track.Vertex()[2]);
809 fTrackPX.push_back (track.Momentum_beg()*track.VtxDir()[0]);
810 fTrackPY.push_back (track.Momentum_beg()*track.VtxDir()[1]);
811 fTrackPZ.push_back (track.Momentum_beg()*track.VtxDir()[2]);
812 fTrackP.push_back (track.Momentum_beg());
813 fTrackQ.push_back (track.ChargeBeg());
814 fTrackLen.push_back (track.LengthForward());
820 fTrackEndPX.push_back (track.Momentum_end()*track.EndDir()[0]);
821 fTrackEndPY.push_back (track.Momentum_end()*track.EndDir()[1]);
822 fTrackEndPZ.push_back (track.Momentum_end()*track.EndDir()[2]);
830 fTrackX.push_back (track.End()[0]);
831 fTrackY.push_back (track.End()[1]);
832 fTrackZ.push_back (track.End()[2]);
833 fTrackPX.push_back (track.Momentum_end()*track.EndDir()[0]);
834 fTrackPY.push_back (track.Momentum_end()*track.EndDir()[1]);
835 fTrackPZ.push_back (track.Momentum_end()*track.EndDir()[2]);
836 fTrackP.push_back (track.Momentum_end());
837 fTrackQ.push_back (track.ChargeEnd());
838 fTrackLen.push_back (track.LengthBackward());
844 fTrackEndPX.push_back (track.Momentum_beg()*track.VtxDir()[0]);
845 fTrackEndPY.push_back (track.Momentum_beg()*track.VtxDir()[1]);
846 fTrackEndPZ.push_back (track.Momentum_beg()*track.VtxDir()[2]);
857 float pidhypo[5] = {5.0, 5.0, 5.0, 5.0, 5.0};
858 for(
size_t ipid = 0; ipid < pid.size(); ipid++){
859 if(pid.at(ipid).first == 1000010020)
continue;
860 if (pid.at(ipid).first == 13 && pid.at(ipid).second < pidhypo[0]) pidhypo[0] = pid.at(ipid).second;
861 else if(pid.at(ipid).first == 211 && pid.at(ipid).second < pidhypo[1]) pidhypo[1] = pid.at(ipid).second;
862 else if(pid.at(ipid).first == 321 && pid.at(ipid).second < pidhypo[2]) pidhypo[2] = pid.at(ipid).second;
863 else if(pid.at(ipid).first == 2212 && pid.at(ipid).second < pidhypo[3]) pidhypo[3] = pid.at(ipid).second;
864 else if(pid.at(ipid).first == 11 && pid.at(ipid).second < pidhypo[4]) pidhypo[4] = pid.at(ipid).second;
867 for(
int ihypo = 0; ihypo < 5; ihypo++){
868 if(pidhypo[ihypo] == 5.0) pidhypo[ihypo] = 0.0;
873 if(trpdg == 22) trpdg = 11;
874 else if(trpdg == 2112) trpdg = 2212;
876 CLHEP::RandFlat FlatRand(
fEngine);
877 if( (trpdg == 11 and pidhypo[4] == 1) ||
878 (trpdg == 13 and pidhypo[0] == 1) ||
879 (trpdg == 211 and pidhypo[1] == 1) ||
880 (trpdg == 321 and pidhypo[2] == 1) ||
881 (trpdg == 2212 and pidhypo[3] == 1) ) {
886 for(
int ihypo = 0; ihypo < 5; ihypo++){
887 if(pidhypo[ihypo] == 1 || pidhypo[ihypo] == 0)
continue;
889 float random_number = FlatRand.fire();
890 if(random_number < pidhypo[ihypo]){
896 if (pidpdg == 0)
fTrackPID.push_back(13);
897 else if(pidpdg == 1)
fTrackPID.push_back(211);
898 else if(pidpdg == 2)
fTrackPID.push_back(321);
899 else if(pidpdg == 3)
fTrackPID.push_back(2212);
900 else if(pidpdg == 4)
fTrackPID.push_back(11);
905 std::vector<ULong64_t> clusterID;
907 for (
auto const&
cluster : (*RecoClusterHandle) ) {
909 if ( findManyCALTrackEnd->isValid() ) {
910 nCALedTracks = findManyCALTrackEnd->at(iCluster).size();
913 for (
int iCALedTrack=0; iCALedTrack<nCALedTracks; ++iCALedTrack) {
914 rec::Track temptrack = *(findManyCALTrackEnd->at(iCluster).at(iCALedTrack));
915 if(temptrack.
getIDNumber() == track.getIDNumber()){
916 clusterID.push_back(
cluster.getIDNumber());
927 if(clusterID.size() > 0){
929 for (
auto const&
cluster : (*RecoClusterHandle) ) {
930 for(
long unsigned int i = 0; i < clusterID.size(); i++){
931 if(clusterID.at(i) ==
cluster.getIDNumber()){
953 if (findIonization->isValid()) {
956 float avgIonF, avgIonB;
972 TrkId momTrkId = theMCPart.
Mother();
975 int momIndex = TrackIdToIndex[momTrkId];
976 momPDG = (*MCPHandle).at(momIndex).PdgCode();
998 for (
size_t imchl = 0; imchl < mctruthHandles.size(); ++imchl) {
999 for (
auto const& mct : (*mctruthHandles.at(imchl)) ) {
1000 if (mct.NeutrinoSet()) {
1002 Float_t vertX = nuw.
Nu().
EndX();
1003 Float_t vertY = nuw.
Nu().
EndY();
1004 Float_t vertZ = nuw.
Nu().
EndZ();
1005 Float_t
dist =
std::hypot(position.X()-vertX,position.Y()-vertY,position.Z()-vertZ);
1013 f_W.push_back(nuw.
W());
1014 f_X.push_back(nuw.
X());
1015 f_Y.push_back(nuw.
Y());
1090 if(iTrack > 0)
fTree->Fill();
1102 std::vector<std::pair<float,float>> SigData = ion.
getFWD_dSigdXs();
1116 std::vector<std::pair<float,float>> dEvsX;
1125 if (SigData.size()==0)
return 0.0;
1126 float distAlongTrack = 0;
1127 std::vector<std::pair<float,float>>
::iterator littlebit = SigData.begin();
1128 for (; littlebit<(SigData.end()-1); ++littlebit) {
1129 float dE = std::get<0>(*littlebit);
1132 float dX = std::get<1>(*littlebit);
1133 distAlongTrack += dX;
1135 dX += std::get<1>(*(littlebit+1));
1136 float dEdX = dE/(0.5*dX);
1138 std::pair pushme = std::make_pair(dEdX,distAlongTrack);
1139 dEvsX.push_back( pushme );
1146 int goUpTo = ionizeTruncate * dEvsX.size() +0.5;
1147 if (goUpTo > (
int)dEvsX.size()) goUpTo = dEvsX.size();
1148 int i = 1;
float returnvalue = 0;
1149 littlebit = dEvsX.begin();
1150 for (; littlebit<dEvsX.end(); ++littlebit) {
1151 returnvalue += std::get<0>(*littlebit);
1153 if (i>goUpTo)
break;
1155 returnvalue /= goUpTo;
1165 std::vector<std::string> recopnamelist = {
"#pi",
"#mu",
"p",
"K",
"d",
"e"};
1166 std::vector<int> pdg_charged = {211, 13, 2212, 321, 1000010020, 11};
1167 std::vector< std::pair<int, float> >
pid;
1171 float dist = 100000000.;
1172 CLHEP::RandFlat FlatRand(
fEngine);
1174 for(
int q = 0; q < 501; ++q){
1177 unsigned first = fulltitle.find(
"=");
1178 unsigned last = fulltitle.find(
"GeV");
1179 std::string substr = fulltitle.substr(first+1, last - first-1);
1180 float pidinterp_mom = std::atof(substr.c_str());
1182 float disttemp =
std::abs(pidinterp_mom - p);
1184 if( disttemp < dist ){
1192 for(
int pidm = 0; pidm < 6; ++pidm){
1194 std::vector< std::pair<float, std::string> > v_prob;
1197 for(
int pidr = 0; pidr < 6; ++pidr){
1199 float prob =
m_pidinterp[qclosest]->GetBinContent(pidm+1, pidr+1);
1201 v_prob.push_back( std::make_pair(prob, recoparticlename) );
1205 if(v_prob.size() > 1){
1207 std::sort(v_prob.begin(), v_prob.end());
1209 float random_number = FlatRand.fire();
1211 std::partial_sum(v_prob.begin(), v_prob.end(), v_prob.begin(), [](
const P& _x,
const P& _y){
return P(_x.first + _y.first, _y.second);});
1213 for(
size_t ivec = 0; ivec < v_prob.size()-1; ivec++){
1214 if( random_number < v_prob.at(ivec+1).first && random_number >= v_prob.at(ivec).first ){
1215 pid.push_back( std::make_pair(pdg_charged.at(
std::distance( recopnamelist.begin(), std::find(recopnamelist.begin(), recopnamelist.end(), v_prob.at(ivec+1).second) ) ), v_prob.at(ivec+1).first) );
1220 pid.push_back( std::make_pair(pdg_charged.at(
std::distance( recopnamelist.begin(), std::find(recopnamelist.begin(), recopnamelist.end(), v_prob.at(0).second) ) ), v_prob.at(0).first) );
1233 CLHEP::RandFlat FlatRand(
fEngine);
1234 float ranNum = FlatRand.fire();
1236 if(
abs(pdg) == 11 || pdg == 22)
return pdg;
1237 else if(
abs(pdg) == 2212)
return pdg;
1238 else if(
abs(pdg) == 13 ||
abs(pdg) == 211){
1240 if(
abs(pdg) == 13) pdg2 = 211;
1242 if(ptrue < 0.48)
return pdg;
1243 if(ptrue >= 0.48 && ptrue < 0.75 && ranNum < 0.8)
return pdg;
1244 if(ptrue >= 0.75 && ptrue < 0.90 && ranNum < 0.9)
return pdg;
1245 if(ptrue >= 0.90 && ranNum < 0.95)
return pdg;
1247 if(ptrue >= 0.48 && ptrue < 0.75 && ranNum >= 0.8)
return pdg2;
1248 if(ptrue >= 0.75 && ptrue < 0.90 && ranNum >= 0.9)
return pdg2;
1249 if(ptrue >= 0.90 && ranNum >= 0.95)
return pdg2;
1252 if(ranNum < 0.25)
return 11;
1253 else if(ranNum >= 0.25 && ranNum < 0.5)
return 13;
1254 else if(ranNum >= 0.5 && ranNum < 0.75)
return 211;
double E(const int i=0) const
std::vector< Float_t > fMCPStartPX
std::vector< Float_t > fY
base_engine_t & createEngine(seed_t seed)
std::unordered_map< int, TH2F * > m_pidinterp
std::vector< Float_t > fTrackEndPX
unsigned int NumberTrajectoryPoints() const
std::vector< Int_t > fClusterNhits
std::vector< Float_t > fTrackPZ
const TLorentzVector & Position(const int i=0) const
std::vector< Float_t > fMCVertexZ
double Theta() const
angle between incoming and outgoing leptons, in radians
double Py(const int i=0) const
std::vector< Float_t > fTheta
std::vector< std::pair< int, float > > processPIDInfo(float p)
std::vector< Int_t > f_Mode
std::vector< Float_t > fQ2
double fECALEndcapOuterRadius
std::vector< Float_t > fMCnuPz
void analyze(art::Event const &e) override
std::vector< Float_t > fMCPStartPY
std::vector< Float_t > fMCP_PZ
std::vector< Float_t > fMCPStartZ
HNLAnalysis & operator=(HNLAnalysis const &)=delete
std::vector< Float_t > fTrackPX
bool PointInECALEndcap(TVector3 const &point) const
std::vector< Float_t > fW
cheat::BackTrackerCore * fBack
std::vector< Int_t > f_NeutrinoType
const simb::MCParticle & Nu() const
std::vector< Int_t > fMCP_PDG
HNLAnalysis(fhicl::ParameterSet const &p)
bool PointInGArTPC(TVector3 const &point) const
std::vector< Double_t > fTrackTime
double Px(const int i=0) const
double fECALBarrelInnerRadius
std::vector< Float_t > fMCP_PY
std::vector< Float_t > fX
std::vector< Float_t > fT
std::vector< Float_t > fClusterTheta
std::vector< Int_t > fMCVertexInGasTPC
float TPCXCent() const
Returns the X location of the center of the TPC in cm.
std::pair< float, std::string > P
std::vector< Float_t > fMCnuPx
Description of geometry of one entire detector.
double fECALBarrelOuterRadius
TDatabasePDG * pdgInstance
float processOneDirection(std::vector< std::pair< float, float >> SigData, float ionizeTruncate)
float GetECALOuterEndcapRadius() const
Cluster finding and building.
std::vector< Float_t > f_MCnuE
TrackEnd const TrackEndEnd
std::vector< Float_t > fMCnuE
EDAnalyzer(fhicl::ParameterSet const &pset)
std::string Process() const
std::vector< Float_t > fMCP_X
std::vector< Int_t > fMCP_InGasTPC
std::vector< Int_t > fCCNC
std::vector< Int_t > fMCPDG
std::vector< Float_t > fClusterZ
std::vector< Float_t > fTrackEndP
std::vector< Float_t > f_Q2
std::vector< Float_t > fMCVertexX
std::vector< Int_t > fMCP_TrackID
double dEdX(double KE, const simb::MCParticle *part)
std::vector< Int_t > fTrackEndQ
std::enable_if_t< std::is_arithmetic_v< T >, T > hypot(T x, T y)
std::vector< Float_t > f_W
std::vector< Float_t > fTrackEndX
std::vector< Float_t > f_Theta
std::vector< Float_t > fTrackEndZ
std::vector< std::string > fMCPEndProc
std::vector< Int_t > fMode
std::vector< Float_t > fClusterX
std::vector< Float_t > fTrackZ
int InteractionType() const
std::vector< Float_t > fMCPStartEndP
std::vector< Float_t > fMCPStartPZ
CLHEP::HepRandomEngine & fEngine
random engine
#define DEFINE_ART_MODULE(klass)
std::vector< Float_t > fClusterTimeDiffFirstLast
void processIonizationInfo(rec::TrackIoniz &ion, float ionizeTruncate, float &forwardIonVal, float &backwardIonVal)
std::string EndProcess() const
virtual void beginJob() override
float TPCRadius() const
Returns the radius of the TPC (y or z direction)
std::vector< Float_t > fTrackEndY
float GetECALInnerEndcapRadius() const
double fECALEndcapInnerRadius
std::vector< Int_t > fMCPDGMother
double P(const int i=0) const
T get(std::string const &key) const
double T(const int i=0) const
std::vector< Float_t > fMCPStartY
std::vector< Float_t > fClusterPhi
std::vector< Int_t > fMCPTrackID
std::vector< Float_t > fTrackLen
float TPCZCent() const
Returns the Z location of the center of the TPC in cm.
std::vector< Int_t > fClusterPID
float fIonizTruncate
Default=1.00;.
bool PointInECALBarrel(TVector3 const &point) const
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
std::vector< Float_t > fTrackPY
float fMatchMCPtoVertDist
Default=roundoff.
std::vector< Float_t > f_MCVertexZ
std::vector< Float_t > fClusterMainAxisX
std::vector< Float_t > fClusterTime
std::vector< Int_t > f_TgtPDG
std::vector< Float_t > fMCP_PX
std::vector< Float_t > fTrackY
float GetECALEndcapStartX() const
std::vector< Int_t > fTrackQ
std::vector< Float_t > fTrackEndPY
std::vector< Int_t > fMCPInECal
std::vector< Float_t > f_X
float GetECALOuterBarrelRadius() const
std::string fECALAssnLabel
General GArSoft Utilities.
double Vx(const int i=0) const
std::vector< Float_t > fMCPStartP
std::vector< Float_t > fTrackEndPZ
TrackEnd const TrackEndBeg
std::vector< Float_t > fTrackChi2
std::vector< Int_t > fNECalClustersForTrack
std::vector< Int_t > f_MCVertexInGasTPC
std::vector< Float_t > f_T
std::vector< ULong64_t > fTrackIDNumber
std::vector< Int_t > f_CCNC
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
float TPCYCent() const
Returns the Y location of the center of the TPC in cm.
std::vector< std::pair< simb::MCParticle *, float > > TrackToMCParticles(rec::Track *const t)
std::vector< Float_t > fTrackAvgIon
std::vector< Float_t > f_MCVertexX
std::vector< Float_t > f_MCVertexY
std::vector< Int_t > fNeutrinoType
const TLorentzVector & Momentum(const int i=0) const
std::vector< Int_t > f_InteractionType
double Pz(const int i=0) const
std::vector< Float_t > fMCnuPy
std::vector< Float_t > fClusterMainAxisZ
std::vector< Int_t > fNTPCClustersOnTrack
std::vector< Float_t > fMCVertexY
std::vector< Int_t > fInteractionType
double Vz(const int i=0) const
static bool lessThan_byE(std::pair< float, float > a, std::pair< float, float > b)
float GetECALInnerBarrelRadius() const
std::vector< Float_t > fTrackX
std::vector< Float_t > f_Y
void FillVectors(art::Event const &e)
float TPCLength() const
Returns the length of the TPC (x direction)
gar::rec::IDNumber getIDNumber() const
std::vector< Float_t > fMCP_E
int GetECalPIDParameterized(int pdg, float ptrue)
std::vector< Float_t > fMCPStartX
std::vector< Int_t > fTgtPDG
std::vector< std::string > fMCPProc
std::vector< Float_t > fMCPTime
const std::vector< std::pair< float, float > > getBAK_dSigdXs() const
def momentum(x1, x2, x3, scale=1.)
std::vector< Float_t > fMCP_Z
const gar::geo::GeometryCore * fGeo
const std::vector< std::pair< float, float > > getFWD_dSigdXs() const
Event generator information.
art framework interface to geometry description
std::vector< Float_t > fMCP_T
std::string fClusterLabel
std::vector< Float_t > fMCP_Y
std::vector< Int_t > fTrackPID
std::vector< Int_t > fClusterTrackIDMatched
double Vy(const int i=0) const
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)
QCString & append(const char *s)
Event finding and building.
float GetECALEndcapOuterX() const
std::vector< Float_t > fClusterEnergy
std::vector< Float_t > fClusterY
std::vector< Float_t > fClusterMainAxisY
std::vector< Float_t > fTrackP