20 #include "art/Framework/Core/EDProducer.h" 
   21 #include "art/Framework/Core/ModuleMacros.h" 
   22 #include "art/Framework/Principal/Event.h" 
   23 #include "art/Framework/Services/Registry/ServiceHandle.h" 
   46   class CosmicPCAxisTagger;
 
   54   void produce(art::Event& 
e) 
override;
 
   70   : EDProducer{p}, fPcaAlg(
p.get<fhicl::ParameterSet>(
"PrincipalComponentsAlg"))
 
   72   art::ServiceHandle<geo::Geometry const> geo;
 
   74   fDetHalfHeight = geo->DetHalfHeight();
 
   75   fDetWidth = 2. * geo->DetHalfWidth();
 
   76   fDetLength = geo->DetLength();
 
   78   auto const clock_data = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
 
   81   fPFParticleModuleLabel = 
p.get<std::string>(
"PFParticleModuleLabel");
 
   82   fPCAxisModuleLabel = 
p.get<std::string>(
"PCAxisModuleLabel");
 
   84   fTPCXBoundary = 
p.get<
float>(
"TPCXBoundary", 5);
 
   85   fTPCYBoundary = 
p.get<
float>(
"TPCYBoundary", 5);
 
   86   fTPCZBoundary = 
p.get<
float>(
"TPCZBoundary", 5);
 
   89     art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob(clock_data);
 
   90   const double driftVelocity =
 
   91     detector.DriftVelocity(detector.Efield(), detector.Temperature()); 
 
   94     2 * geo->DetHalfWidth() / (driftVelocity * fSamplingRate / 1000); 
 
   96   produces<std::vector<anab::CosmicTag>>();
 
   97   produces<art::Assns<recob::PFParticle, anab::CosmicTag>>();
 
   98   produces<art::Assns<recob::PCAxis, anab::CosmicTag>>();
 
  105   std::unique_ptr<std::vector<anab::CosmicTag>> cosmicTagPFParticleVector(
 
  106     new std::vector<anab::CosmicTag>);
 
  107   std::unique_ptr<art::Assns<recob::PCAxis, anab::CosmicTag>> assnOutCosmicTagPCAxis(
 
  108     new art::Assns<recob::PCAxis, anab::CosmicTag>);
 
  109   std::unique_ptr<art::Assns<recob::PFParticle, anab::CosmicTag>> assnOutCosmicTagPFParticle(
 
  110     new art::Assns<recob::PFParticle, anab::CosmicTag>);
 
  113   art::Handle<std::vector<recob::PFParticle>> pfParticleHandle;
 
  114   evt.getByLabel(fPFParticleModuleLabel, pfParticleHandle);
 
  116   if (!pfParticleHandle.isValid()) {
 
  117     evt.put(std::move(cosmicTagPFParticleVector));
 
  118     evt.put(std::move(assnOutCosmicTagPFParticle));
 
  119     evt.put(std::move(assnOutCosmicTagPCAxis));
 
  125   art::Handle<std::vector<recob::Cluster>> clusterHandle;
 
  126   evt.getByLabel(fPFParticleModuleLabel, clusterHandle);
 
  129   art::Handle<std::vector<recob::PCAxis>> pcaxisHandle;
 
  130   evt.getByLabel(fPCAxisModuleLabel, pcaxisHandle);
 
  132   if (!pcaxisHandle.isValid() || !clusterHandle.isValid()) {
 
  133     evt.put(std::move(cosmicTagPFParticleVector));
 
  134     evt.put(std::move(assnOutCosmicTagPFParticle));
 
  135     evt.put(std::move(assnOutCosmicTagPCAxis));
 
  140   art::FindManyP<recob::PCAxis> pfPartToPCAxisAssns(pfParticleHandle, evt, fPCAxisModuleLabel);
 
  143   art::FindManyP<recob::SpacePoint> spacePointAssnVec(
 
  144     pfParticleHandle, evt, fPFParticleModuleLabel);
 
  148   art::FindManyP<recob::Cluster> clusterAssns(pfParticleHandle, evt, fPFParticleModuleLabel);
 
  151   art::FindManyP<recob::Hit> clusterHitAssns(clusterHandle, evt, fPFParticleModuleLabel);
 
  154   for (
size_t pfPartIdx = 0; pfPartIdx != pfParticleHandle->size(); pfPartIdx++) {
 
  155     art::Ptr<recob::PFParticle> pfParticle(pfParticleHandle, pfPartIdx);
 
  158     std::vector<art::Ptr<recob::PCAxis>> pcAxisVec = pfPartToPCAxisAssns.at(pfPartIdx);
 
  161     if (pcAxisVec.empty()) 
continue;
 
  168     if (pcAxisVec.size() > 1 && pcAxisVec.front()->getID() > pcAxisVec.back()->getID())
 
  169       std::reverse(pcAxisVec.begin(), pcAxisVec.end());
 
  174     const art::Ptr<recob::PCAxis>& pcAxis = pcAxisVec.front();
 
  185     double eigenVal0 = sqrt(pcAxis->getEigenValues()[0]);
 
  186     double maxArcLen = 3. * eigenVal0;
 
  189     TVector3 vertexPosition(
 
  190       pcAxis->getAvePosition()[0], pcAxis->getAvePosition()[1], pcAxis->getAvePosition()[2]);
 
  191     TVector3 vertexDirection(pcAxis->getEigenVectors()[0][0],
 
  192                              pcAxis->getEigenVectors()[0][1],
 
  193                              pcAxis->getEigenVectors()[0][2]);
 
  195     TVector3 pcAxisStart = vertexPosition - maxArcLen * vertexDirection;
 
  196     TVector3 pcAxisEnd = vertexPosition + maxArcLen * vertexDirection;
 
  199     float trackEndPt1_X = pcAxisStart[0];
 
  200     float trackEndPt1_Y = pcAxisStart[1];
 
  201     float trackEndPt1_Z = pcAxisStart[2];
 
  202     float trackEndPt2_X = pcAxisEnd[0];
 
  203     float trackEndPt2_Y = pcAxisEnd[1];
 
  204     float trackEndPt2_Z = pcAxisEnd[2];
 
  207     std::vector<art::Ptr<recob::Cluster>> clusterVec = clusterAssns.at(pfParticle.key());
 
  212     for (
const auto& 
cluster : clusterVec) {
 
  214       std::vector<art::Ptr<recob::Hit>> hitVec = clusterHitAssns.at(
cluster->ID());
 
  222       for (
const auto& 
hit : hitVec) {
 
  224           std::cout << 
"***>> Hit key: " << 
hit.key() << 
", peak - RMS: " << 
hit->PeakTimeMinusRMS()
 
  225                     << 
", peak + RMS: " << 
hit->PeakTimePlusRMS()
 
  226                     << 
", det width: " << fDetectorWidthTicks << std::endl;
 
  228         if (
hit->PeakTimeMinusRMS() < fDetectorWidthTicks ||
 
  229             hit->PeakTimePlusRMS() > 2. * fDetectorWidthTicks) {
 
  238     std::vector<art::Ptr<recob::SpacePoint>> spacePointVec = spacePointAssnVec.at(pfParticle.key());
 
  243     if (isCosmic == 0 && !spacePointVec.empty()) {
 
  247         sqrt(std::pow(pcAxis->getEigenValues()[1], 2) + std::pow(pcAxis->getEigenValues()[1], 2));
 
  249       if (eigenVal0 > 0. && transRMS > 0.) {
 
  256         double arcLengthToFirstHit(9999.);
 
  257         double arcLengthToLastHit(-9999.);
 
  259         for (
const auto spacePoint : spacePointVec) {
 
  260           TVector3 spacePointPos(spacePoint->XYZ()[0], spacePoint->XYZ()[1], spacePoint->XYZ()[2]);
 
  261           TVector3 deltaPos = spacePointPos - vertexPosition;
 
  262           double arcLenToHit = deltaPos.Dot(vertexDirection);
 
  264           if (arcLenToHit < arcLengthToFirstHit) {
 
  265             arcLengthToFirstHit = arcLenToHit;
 
  266             pcAxisStart = spacePointPos;
 
  269           if (arcLenToHit > arcLengthToLastHit) {
 
  270             arcLengthToLastHit = arcLenToHit;
 
  271             pcAxisEnd = spacePointPos;
 
  276         trackEndPt1_X = pcAxisStart[0];
 
  277         trackEndPt1_Y = pcAxisStart[1];
 
  278         trackEndPt1_Z = pcAxisStart[2];
 
  279         trackEndPt2_X = pcAxisEnd[0];
 
  280         trackEndPt2_Y = pcAxisEnd[1];
 
  281         trackEndPt2_Z = pcAxisEnd[2];
 
  288         bool nBdX[] = {
false, 
false};
 
  289         bool nBdY[] = {
false, 
false};
 
  290         bool nBdZ[] = {
false, 
false};
 
  297         if (fDetWidth - trackEndPt1_X < fTPCXBoundary || trackEndPt1_X < fTPCXBoundary)
 
  299         if (fDetWidth - trackEndPt2_X < fTPCXBoundary || trackEndPt2_X < fTPCXBoundary)
 
  304         if (fDetHalfHeight - trackEndPt1_Y < fTPCYBoundary ||
 
  305             fDetHalfHeight + trackEndPt1_Y < fTPCYBoundary)
 
  307         if (fDetHalfHeight - trackEndPt2_Y < fTPCYBoundary ||
 
  308             fDetHalfHeight + trackEndPt2_Y < fTPCYBoundary)
 
  313         if (fDetLength - trackEndPt1_Z < fTPCZBoundary || trackEndPt1_Z < fTPCZBoundary)
 
  315         if (fDetLength - trackEndPt2_Z < fTPCZBoundary || trackEndPt2_Z < fTPCZBoundary)
 
  319         bool exitEnd1 = nBdX[0] || nBdY[0]; 
 
  320         bool exitEnd2 = nBdX[1] || nBdY[1]; 
 
  328         if ((exitEnd1 && exitEnd2) || exitEndZ1 || exitEndZ2) {
 
  330           if (nBdX[0] && nBdX[1])
 
  332           else if (nBdY[0] && nBdY[1])
 
  334           else if ((nBdX[0] || nBdX[1]) && (nBdY[0] || nBdY[1]))
 
  336           else if ((nBdX[0] || nBdX[1]) && (nBdZ[0] || nBdZ[1]))
 
  342         else if (nBdZ[0] && nBdZ[1]) {
 
  347         else if ((nBdX[0] || nBdY[0] || nBdZ[0]) != (nBdX[1] || nBdY[1] || nBdZ[1])) {
 
  349           if (nBdX[0] || nBdX[1])
 
  351           else if (nBdY[0] || nBdY[1])
 
  353           else if (nBdZ[0] || nBdZ[1])
 
  359     std::vector<float> endPt1;
 
  360     std::vector<float> endPt2;
 
  361     endPt1.push_back(trackEndPt1_X);
 
  362     endPt1.push_back(trackEndPt1_Y);
 
  363     endPt1.push_back(trackEndPt1_Z);
 
  364     endPt2.push_back(trackEndPt2_X);
 
  365     endPt2.push_back(trackEndPt2_Y);
 
  366     endPt2.push_back(trackEndPt2_Z);
 
  368     float cosmicScore = isCosmic > 0 ? 1. : 0.;
 
  373     else if (isCosmic == 4)
 
  377     cosmicTagPFParticleVector->emplace_back(endPt1, endPt2, cosmicScore, tag_id);
 
  380       *
this, evt, *cosmicTagPFParticleVector, pfParticle, *assnOutCosmicTagPFParticle);
 
  383     for (
const auto& axis : pcAxisVec) {
 
  384       util::CreateAssn(*
this, evt, *cosmicTagPFParticleVector, axis, *assnOutCosmicTagPCAxis);
 
  388   evt.put(std::move(cosmicTagPFParticleVector));
 
  389   evt.put(std::move(assnOutCosmicTagPFParticle));
 
  390   evt.put(std::move(assnOutCosmicTagPCAxis));
 
enum anab::cosmic_tag_id CosmicTagID_t
Declaration of signal hit object. 
std::string fPFParticleModuleLabel
std::vector< reco::ClusterHit2D > Hit2DVector
CosmicPCAxisTagger(fhicl::ParameterSet const &p)
Declaration of cluster object. 
void produce(art::Event &e) override
This header file defines the interface to a principal components analysis designed to be used within ...
bool CreateAssn(art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t index=UINT_MAX)
Creates a single one-to-one association. 
lar_cluster3d::PrincipalComponentsAlg fPcaAlg
Principal Components algorithm. 
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock. 
art framework interface to geometry description 
BEGIN_PROLOG could also be cout
std::string fPCAxisModuleLabel