19 #include "canvas/Persistency/Common/FindManyP.h"    41   class ShowerCalorimetry;
    61   , 
fSCE(
p.get<
bool>(
"CorrectSCE"))
    64   produces<std::vector<anab::Calorimetry>>();
    65   produces<art::Assns<recob::Shower, anab::Calorimetry>>();
    77   auto const* 
sce = lar::providerFrom<spacecharge::SpaceChargeService>();
    80   auto caloPtr = std::make_unique<std::vector<anab::Calorimetry>>();
    81   auto& caloVector = *caloPtr;
    85   std::vector<size_t> assnShowerCaloVector;
    86   auto associationPtr = std::make_unique<art::Assns<recob::Shower, anab::Calorimetry>>();
    91   std::vector<art::Ptr<recob::Shower>> recoShowers;
    95   art::FindManyP<recob::Hit> findHitsFromShowers(showerHandle, e, 
fShowerTag);
    98   for (
size_t i = 0; i < recoShowers.size(); ++i) {
    99     auto& 
shower = recoShowers[i];
   101     int shower_index = 
shower.key();
   102     MF_LOG_INFO(
"ShowerCalorimetry") << 
"Getting Calorimetry info for " << shower_index << 
"\n";
   105     float shower_length = 
shower->Length();
   107     auto const& hits = findHitsFromShowers.at(shower_index);
   109     art::FindManyP<recob::SpacePoint> spFromShowerHits(hits, e, 
fSpacePointTag);
   113     std::vector<std::vector<size_t>> hit_indices_per_plane(geom->
Nplanes());
   114     for (
size_t j = 0; j < hits.size(); ++j) {
   115       hit_indices_per_plane[hits[j]->WireID().Plane].push_back(j);
   119     for (
size_t j = 0; j < geom->
Nplanes(); ++j) {
   121       size_t hits_in_plane = hit_indices_per_plane[j].size();
   124       std::vector<float> 
dEdx(hits_in_plane);
   125       std::vector<float> dQdx(hits_in_plane);
   126       std::vector<float> pitch(hits_in_plane);
   129       std::vector<float> resRange(hits_in_plane, 0.);
   130       std::vector<TVector3> xyz(hits_in_plane, TVector3(0., 0., 0.));
   131       std::vector<float> deadwires(hits_in_plane, 0.);
   132       std::vector<size_t> hitIndex(hits_in_plane);
   136       float kineticEnergy = 0.;
   138       for (
size_t k = 0; 
k < hits_in_plane; ++
k) {
   140         size_t hit_index = hit_indices_per_plane[j][
k];
   141         auto& theHit = hits[hit_index];
   142         if (!planeID.
isValid) { planeID = theHit->WireID(); }
   143         hitIndex[
k] = theHit.key();
   144         float wire_pitch = geom->
WirePitch(theHit->View());
   146         float theHit_Xpos = -999.;
   147         float theHit_Ypos = -999.;
   148         float theHit_Zpos = -999.;
   150         auto const& sp = spFromShowerHits.at(hit_index);
   153           theHit_Xpos = sp[0]->XYZ()[0];
   154           theHit_Ypos = sp[0]->XYZ()[1];
   155           theHit_Zpos = sp[0]->XYZ()[2];
   159             << 
"no sp associated w/this hit ... we will skip this hit";
   163         TVector3 
pos(theHit_Xpos, theHit_Ypos, theHit_Zpos);
   165         float this_pitch = wire_pitch;
   167         angleToVert -= 0.5 * ::util::pi<>();
   169         float cosgamma = 
std::abs(sin(angleToVert) * 
shower->Direction().Y() +
   170                                   cos(angleToVert) * 
shower->Direction().Z());
   171         if (cosgamma > 0) this_pitch /= cosgamma;
   172         if (this_pitch < wire_pitch) this_pitch = wire_pitch;
   173         pitch[
k] = this_pitch;
   176         if (
fSCE && 
sce->EnableCalSpatialSCE()) {
   181           posOffsets = 
sce->GetCalPosOffsets(
geo::Point_t(pos), theHit->WireID().TPC);
   186                                                pos.Y() + this_pitch * 
shower->Direction().Y(),
   187                                                pos.Z() + this_pitch * 
shower->Direction().Z()},
   188                                   theHit->WireID().TPC);
   190           TVector3 dir_corr = {
   191             this_pitch * 
shower->Direction().X() - dirOffsets.X() + posOffsets.X(),
   192             this_pitch * 
shower->Direction().Y() + dirOffsets.Y() - posOffsets.Y(),
   193             this_pitch * 
shower->Direction().Z() + dirOffsets.Z() - posOffsets.Z()};
   195           pitch[
k] = dir_corr.Mag();
   197           theHit_Xpos -= posOffsets.X();
   198           theHit_Ypos += posOffsets.Y();
   199           theHit_Zpos += posOffsets.Z();
   201         xyz[
k].SetXYZ(theHit_Xpos, theHit_Ypos, theHit_Zpos);
   203                                  theHit_Ypos - 
shower->ShowerStart().Y(),
   204                                  theHit_Zpos - 
shower->ShowerStart().Z());
   206         dQdx[
k] = theHit->Integral() / pitch[
k];
   212         kineticEnergy += dEdx[
k];
   216       caloVector.emplace_back(kineticEnergy,
   228       assnShowerCaloVector.emplace_back(shower_index);
   233   for (
size_t i = 0; i < assnShowerCaloVector.size(); i++) {
 
EDProducer(fhicl::ParameterSet const &pset)
The data type to uniquely identify a Plane. 
bool isValid
Whether this ID points to a valid element. 
ShowerCalorimetry(fhicl::ParameterSet const &p)
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space. 
geo::Length_t WirePitch(geo::PlaneID const &planeid) const 
Returns the distance between two consecutive wires. 
art framework interface to geometry description 
std::enable_if_t< std::is_arithmetic_v< T >, T > hypot(T x, T y)
void produce(art::Event &e) override
double dEdx(float dqdx, float Efield)
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const 
Returns the total number of wire planes in the specified TPC. 
#define DEFINE_ART_MODULE(klass)                                                                                          
ValidHandle< PROD > getValidHandle(InputTag const &tag) const 
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association. 
std::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
static int max(int a, int b)
#define MF_LOG_INFO(category)                                                                                                
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space. 
Declaration of signal hit object. 
double dEdx_AREA(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, recob::Hit const &hit, double pitch, double T0=0) const 
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
art::InputTag fSpacePointTag
double WireAngleToVertical(geo::View_t view, geo::TPCID const &tpcid) const 
Returns the angle of the wires in the specified view from vertical.