28 #include "art_root_io/TFileService.h" 33 #include "canvas/Persistency/Common/FindOne.h" 34 #include "canvas/Persistency/Common/FindOneP.h" 35 #include "canvas/Persistency/Common/FindMany.h" 36 #include "canvas/Persistency/Common/FindManyP.h" 43 #include "MCCheater/BackTracker.h" 45 #include "MCCheater/BackTracker.h" 54 #include "TDatabasePDG.h" 55 #include "TParticlePDG.h" 56 #include "Math/ProbFuncMathCore.h" 60 #include <unordered_map> 209 consumesMany<std::vector<simb::MCTruth> >();
210 consumes<std::vector<simb::MCParticle> >(
fGeantLabel);
227 fGeo = gar::providerFrom<geo::GeometryGAr>();
235 fTree = tfs->make<TTree>(
"GArPerfTree",
"GArPerfTree");
238 chargeFrac = tfs->make<TH1F>(
"chargeFrac",
"Fraction of MCPart's ionization in track",
305 fDetProp = gar::providerFrom<detinfo::DetectorPropertiesService>();
306 fClocks = gar::providerFrom<detinfo::DetectorClocksServiceGAr>();
309 *fClocks->SpillLength();
315 if ( !fBack->HasTracks() || !fBack->HasClusters() ) {
316 throw cet::exception(
"MatchingPerformance") <<
" Not enough backtracker info" 317 <<
" Line " << __LINE__ <<
" in file " << __FILE__ <<
std::endl;
397 auto TrackHandle =
event.getHandle< std::vector<rec::Track> >(
fTrackLabel);
400 <<
" Line " << __LINE__ <<
" in file " << __FILE__ <<
std::endl;
404 auto ClusterHandle =
event.getHandle< std::vector<rec::Cluster> >(ecalclustertag);
405 if (!ClusterHandle) {
406 throw cet::exception(
"MatchingPerformance") <<
" No rec::Cluster branch." 407 <<
" Line " << __LINE__ <<
" in file " << __FILE__ <<
std::endl;
410 art::FindMany<rec::Cluster, rec::TrackEnd>* findManyTrackEndCAL = NULL;
412 findManyTrackEndCAL =
new art::FindMany<rec::Cluster, rec::TrackEnd>
413 (TrackHandle,
event,ecalassntag);
414 if ( !findManyTrackEndCAL->isValid() ) {
415 throw cet::exception(
"MatchingPerformance") <<
" Bad TrackEnd-ECAL Assn." 416 <<
" Line " << __LINE__ <<
" in file " << __FILE__ <<
std::endl;
422 auto mctruthHandles =
event.getMany<std::vector<simb::MCTruth> >();
424 if (mctruthHandles.size()!=1) {
425 throw cet::exception(
"MatchingPerformance") <<
" Need just 1 simb::MCTruth" 426 <<
" Line " << __LINE__ <<
" in file " << __FILE__ <<
std::endl;
429 auto MCPHandle =
event.getHandle< std::vector<simb::MCParticle> >(
fGeantLabel);
431 throw cet::exception(
"MatchingPerformance") <<
" No simb::MCParticle" 432 <<
" Line " << __LINE__ <<
" in file " << __FILE__ <<
std::endl;
438 if ( TrackHandle->size()==0 || ClusterHandle->size()==0 )
return false;
442 std::unordered_map<TrkId, Int_t> TrackIdToIndex;
444 for (
auto const& mcp : (*MCPHandle) ) {
445 int TrackId = mcp.TrackId();
446 TrackIdToIndex[TrackId] = index++;
451 std::vector<art::Ptr<rec::Cluster>> ClusterGrabber;
453 for (
size_t iCluster=0; iCluster<ClusterHandle->size(); ++iCluster) {
455 ClusterGrabber.push_back(aPtr);
458 std::vector<art::Ptr<rec::Track>> TrackGrabber;
460 for (
size_t iTrack=0; iTrack<TrackHandle->size(); ++iTrack) {
462 TrackGrabber.push_back(aPtr);
472 fEvent =
event.id().event();
478 std::vector<niceNice> niceTracks;
479 for (
auto const& track : (*TrackHandle) ) {
482 std::vector<std::pair<simb::MCParticle*,float>> MCsfromTrack;
485 int nMCsfromTrack = MCsfromTrack.size();
486 if (nMCsfromTrack!=1)
continue;
490 if (particle==NULL )
continue;
491 if (particle->Charge()==0.0)
continue;
492 if (particle->Stable()==0 )
continue;
496 TVector3 doink;
bool whackThatECAL =
false;
497 for (
int iTraj=0; iTraj<nTraj; ++iTraj) {
498 doink.SetXYZ(theMCPart.
Vx(iTraj),theMCPart.
Vy(iTraj),theMCPart.
Vz(iTraj));
500 whackThatECAL =
true;
504 if (!whackThatECAL)
continue;
507 niceNice
tmp = {track, theMCPart};
508 niceTracks.push_back(tmp);
515 for (; iNiceTrk!=niceTracks.end(); ++iNiceTrk) {
517 std::vector<art::Ptr<rec::Track>> tracksFromSameMCP =
521 std::vector<float> ionzFromSameMCP; ionzFromSameMCP.resize(tracksFromSameMCP.size());
522 for (
size_t iTrkFromSame=0; iTrkFromSame<tracksFromSameMCP.size(); ++iTrkFromSame) {
523 rec::Track tmpTrk = *(tracksFromSameMCP[iTrkFromSame]);
525 float thisTracksI = 0;
526 for (
auto& ptrHit : hitList) thisTracksI += ptrHit->Signal();
527 ionzFromSameMCP[iTrkFromSame] = thisTracksI;
529 float ionzTotSameMCP = 0;
530 for (
size_t iIonSame=0; iIonSame<ionzFromSameMCP.size(); ++iIonSame)
531 ionzTotSameMCP += ionzFromSameMCP[iIonSame];
532 for (
size_t iIonSame=0; iIonSame<ionzFromSameMCP.size(); ++iIonSame) {
533 ionzFromSameMCP[iIonSame] /= ionzTotSameMCP;
538 for (
size_t iTrkFromSame=0; iTrkFromSame<tracksFromSameMCP.size(); ++iTrkFromSame) {
539 if ( *(tracksFromSameMCP[iTrkFromSame])==iNiceTrk->recoTrk
541 niceTracks.erase(iNiceTrk);
549 iNiceTrk = niceTracks.begin();
551 for (; iNiceTrk!=niceTracks.end(); ++iNiceTrk) {
552 for (; jNiceTrk!=niceTracks.end(); ++jNiceTrk) {
553 if ( iNiceTrk->simiTrk.TrackId() == jNiceTrk->simiTrk.TrackId() ){
554 niceTracks.erase(jNiceTrk);
562 for (
size_t iNiceTrk_local=0; iNiceTrk_local<niceTracks.size(); ++iNiceTrk_local) {
563 rec::Track track = niceTracks[iNiceTrk_local].recoTrk;
573 TVector3 positionMCP = theMCPart.
Position(0).Vect();
578 track.
Vertex()[2] -positionMCP[2]);
580 track.
End()[2] -positionMCP[2]);
581 if ( distStart < distEnd ) {
594 float trackPar[5];
float trackEnd[3];
597 for (
size_t i=0; i<5; ++i) trackPar[i] = track.
TrackParBeg()[i];
598 for (
size_t i=0; i<3; ++i) trackEnd[i] = track.
Vertex()[i];
611 for (
size_t i=0; i<5; ++i) trackPar[i] = track.
TrackParEnd()[i];
612 for (
size_t i=0; i<3; ++i) trackEnd[i] = track.
End()[i];
628 Int_t nHits = track.
NHits();
630 Float_t pVal = ROOT::Math::chisquared_cdf_c(saveChi2,nHits-5);
636 for (
int i=0; i<3; ++i) trackEnd[i] -=
ItsInTulsa[i];
640 TrkId momTrkId = theMCPart.
Mother();
643 int momIndex = TrackIdToIndex[momTrkId];
644 momPDG = (*MCPHandle).at(momIndex).PdgCode();
651 const TLorentzVector& momentumMCP = theMCPart.
Momentum(0);
660 std::vector<rec::Cluster> clustersOnMCP;
663 clustersOnMCP.push_back(
cluster);
666 clustersOnMCP.push_back(
cluster);
675 std::sort(clustersOnMCP.begin(),clustersOnMCP.end(),
678 std::unique(clustersOnMCP.begin(),clustersOnMCP.end());
679 clustersOnMCP.resize(
std::distance(clustersOnMCP.begin(),itr));
684 float eAssocNoInTruth = 0.0;
int nAssocNoInTruth = 0;
685 float eUnassocInTruth = 0.0;
int nUnassocInTruth = 0;
686 float eIsassocInTruth = 0.0;
int nIsassocInTruth = 0;
687 size_t nCALedClusts = 0;
688 std::vector<rec::Cluster const*> clustersFromAssn;
689 std::vector<rec::TrackEnd const*> trackEndsFromAssn;
694 for (; iTrack<TrackHandle->size(); ++iTrack) {
695 if ( (*TrackHandle)[iTrack] == track )
break;
701 findManyTrackEndCAL->get(iTrack, clustersFromAssn,trackEndsFromAssn);
702 nCALedClusts = clustersFromAssn.size();
704 for (
auto const&
cluster : (*ClusterHandle) ) {
709 float radius = 1.0/trackPar[2];
710 float zCent = trackPar[1] - radius*sin(trackPar[3]);
711 float yCent = trackPar[0] + radius*cos(trackPar[3]);
718 float distRadially =
std::hypot(zClus-zCent,yClus-yCent) -
abs(radius);
719 distRadially =
abs(distRadially);
721 float retXYZ1[3];
float retXYZ2[3]; TVector3 trackXYZ;
722 float cutQuantity = -1.0;
bool over25 =
false;
726 trackPar,trackEnd,rClus, 0.0, 0.0, retXYZ1,retXYZ2);
729 float transDist1 =
std::hypot(retXYZ1[2]-zClus,retXYZ1[1]-yClus);
730 float transDist2 =
std::hypot(retXYZ2[2]-zClus,retXYZ2[1]-yClus);
732 if (transDist1<transDist2) {
733 trackXYZ.SetXYZ(retXYZ1[0],retXYZ1[1],retXYZ1[2]);
735 trackXYZ.SetXYZ(retXYZ2[0],retXYZ2[1],retXYZ2[2]);
742 extrapXerr = trackXYZ.X() -xClus;
743 float expected_mean = 0;
744 if (trackEnd[0]<-25) {
748 if (trackEnd[0]>+25) {
752 cutQuantity =
abs(extrapXerr -expected_mean);
759 if (
abs(radiansInDrift) >= 2.0*
M_PI )
goto angleCut;
761 trackPar,trackEnd, xClus, retXYZ1);
763 trackXYZ.SetXYZ(retXYZ1[0],retXYZ1[1],retXYZ1[2]);
770 float angClus = std::atan2(yClus-yCent,zClus-zCent);
771 float angXtrap = std::atan2(retXYZ1[1] -yCent,retXYZ1[2] -zCent) -angClus;
773 if (angXtrap > +
M_PI) angXtrap -= 2.0*
M_PI;
774 if (angXtrap < -
M_PI) angXtrap += 2.0*
M_PI;
775 cutQuantity =
abs(radius*angXtrap);
783 int nCells =
cluster.CalorimeterHits().size();
785 float xEval = trackXYZ.x();
787 trackPar,trackEnd, xEval,trackDir);
790 clusterDir.SetXYZ(
cluster.EigenVectors()[0],
792 dotSee = clusterDir.Dot(trackDir);
798 trackXYZ.x()-xClus, trackXYZ.y()-yClus, trackXYZ.z()-zClus);
802 bool clusterOnTrack =
false;
803 for (
size_t iCALedClust=0; iCALedClust<nCALedClusts; ++iCALedClust) {
804 if (*trackEndsFromAssn[iCALedClust] != (*iEnd) )
continue;
805 if (*clustersFromAssn[iCALedClust] ==
cluster) {
806 clusterOnTrack =
true;
811 bool clusterOnMCP =
false;
812 for (
size_t iClusOnMCP = 0; iClusOnMCP<clustersOnMCP.size(); ++iClusOnMCP) {
813 if ( clustersOnMCP[iClusOnMCP] ==
cluster ) {
822 if (!clusterOnMCP ) {
836 if ( clusterOnTrack ) {
837 eAssocNoInTruth +=
cluster.Energy();
838 nAssocNoInTruth +=
cluster.CalorimeterHits().size();
854 if (!clusterOnTrack && clusterOnMCP ) {
855 eUnassocInTruth +=
cluster.Energy();
856 nUnassocInTruth +=
cluster.CalorimeterHits().size();
858 eIsassocInTruth +=
cluster.Energy();
859 nIsassocInTruth +=
cluster.CalorimeterHits().size();
float const & Momentum_beg() const
unsigned int NumberTrajectoryPoints() const
const TLorentzVector & Position(const int i=0) const
std::vector< art::Ptr< rec::Track > > MCParticleToTracks(simb::MCParticle *const p, std::vector< art::Ptr< rec::Track >> const &tracks)
std::vector< art::Ptr< rec::Hit > > const TrackToHits(rec::Track *const t)
const float * TrackParBeg() const
bool PointInECALEndcap(TVector3 const &point) const
bool PointInGArTPC(TVector3 const &point) const
bool MCParticleCreatedCluster(simb::MCParticle *const p, rec::Cluster *const c)
float TPCXCent() const
Returns the X location of the center of the TPC in cm.
Description of geometry of one entire detector.
float const & LengthBackward() const
Cluster finding and building.
TrackEnd const TrackEndEnd
EDAnalyzer(fhicl::ParameterSet const &pset)
float const & ChisqBackward() const
std::enable_if_t< std::is_arithmetic_v< T >, T > hypot(T x, T y)
const float * VtxDir() const
double const & Time() const
virtual double Efield(unsigned int planegap=0) const =0
Returns the nominal electric field in the specified volume.
float const & LengthForward() const
const float * Vertex() const
#define DEFINE_ART_MODULE(klass)
T get(std::string const &key) const
static int PropagateToX(const float *trackpar, const float *Xpoint, const float x, float *retXYZ, const float Rmax=0.0)
double T(const int i=0) const
gar::rec::IDNumber getIDNumber() const
const float * TrackParEnd() const
float TPCZCent() const
Returns the Z location of the center of the TPC in cm.
static int PropagateToCylinder(const float *trackpar, const float *Xpoint, const float rCyl, const float yCyl, const float zCyl, float *retXYZ1, float *retXYZ2, const float Xmax=0.0, const float epsilon=2.0e-5)
bool PointInECALBarrel(TVector3 const &point) const
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
virtual double Temperature() const =0
float const & ChisqForward() const
const float * End() const
bool ClusterCreatedMCParticle(simb::MCParticle *const p, rec::Cluster *const c)
Interface to propagate a Track to the specific point.
General GArSoft Utilities.
double Vx(const int i=0) const
TrackEnd const TrackEndBeg
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)
static int DirectionX(const float *trackpar, const float *Xpoint, float &xEval, float *retXYZ)
const TLorentzVector & Momentum(const int i=0) const
double Vz(const int i=0) const
float const & Momentum_end() const
size_t const & NHits() const
gar::rec::IDNumber getIDNumber() const
virtual double DriftVelocity(double efield=0., double temperature=0., bool cmPerns=true) const =0
art framework interface to geometry description
double Vy(const int i=0) const
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)
Event finding and building.
const float * EndDir() const