13 #include "art/Framework/Core/EDProducer.h"
14 #include "art/Framework/Core/ModuleMacros.h"
15 #include "art/Framework/Principal/Event.h"
16 #include "art/Framework/Principal/Handle.h"
17 #include "art/Framework/Principal/Run.h"
18 #include "art/Framework/Principal/SubRun.h"
19 #include "art/Framework/Services/Registry/ServiceHandle.h"
20 #include "canvas/Persistency/Common/FindManyP.h"
21 #include "canvas/Utilities/InputTag.h"
22 #include "fhiclcpp/ParameterSet.h"
23 #include "messagefacility/MessageLogger/MessageLogger.h"
46 class ShowerCalorimetry;
54 void produce(art::Event&
e)
override;
64 , fShowerTag(
p.get<art::InputTag>(
"ShowerTag"))
65 , fSpacePointTag(
p.get<art::InputTag>(
"SpacePointTag"))
66 , fSCE(
p.get<
bool>(
"CorrectSCE"))
67 , caloAlg(
p.get<fhicl::ParameterSet>(
"CalorimetryAlg"))
69 produces<std::vector<anab::Calorimetry>>();
70 produces<art::Assns<recob::Shower, anab::Calorimetry>>();
77 art::ServiceHandle<geo::Geometry> geom;
79 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
81 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(e, clockData);
82 auto const* sce = lar::providerFrom<spacecharge::SpaceChargeService>();
85 auto caloPtr = std::make_unique<std::vector<anab::Calorimetry>>();
86 auto& caloVector = *caloPtr;
90 std::vector<size_t> assnShowerCaloVector;
91 auto associationPtr = std::make_unique<art::Assns<recob::Shower, anab::Calorimetry>>();
93 auto showerHandle = e.getValidHandle<std::vector<recob::Shower>>(fShowerTag);
96 std::vector<art::Ptr<recob::Shower>> recoShowers;
97 art::fill_ptr_vector(recoShowers, showerHandle);
100 art::FindManyP<recob::Hit> findHitsFromShowers(showerHandle, e, fShowerTag);
103 for (
size_t i = 0; i < recoShowers.size(); ++i) {
104 auto&
shower = recoShowers[i];
106 int shower_index =
shower.key();
107 MF_LOG_INFO(
"ShowerCalorimetry") <<
"Getting Calorimetry info for " << shower_index <<
"\n";
110 float shower_length =
shower->Length();
112 auto const& hits = findHitsFromShowers.at(shower_index);
114 art::FindManyP<recob::SpacePoint> spFromShowerHits(hits, e, fSpacePointTag);
118 std::vector<std::vector<size_t>> hit_indices_per_plane(geom->Nplanes());
119 for (
size_t j = 0; j < hits.size(); ++j) {
120 hit_indices_per_plane[hits[j]->WireID().Plane].push_back(j);
124 for (
size_t j = 0; j < geom->Nplanes(); ++j) {
126 size_t hits_in_plane = hit_indices_per_plane[j].size();
129 std::vector<float>
dEdx(hits_in_plane);
130 std::vector<float> dQdx(hits_in_plane);
131 std::vector<float> pitch(hits_in_plane);
134 std::vector<float> resRange(hits_in_plane, 0.);
135 std::vector<TVector3> xyz(hits_in_plane, TVector3(0., 0., 0.));
136 std::vector<float> deadwires(hits_in_plane, 0.);
137 std::vector<size_t> hitIndex(hits_in_plane);
141 float kineticEnergy = 0.;
143 for (
size_t k = 0;
k < hits_in_plane; ++
k) {
145 size_t hit_index = hit_indices_per_plane[j][
k];
146 auto& theHit = hits[hit_index];
147 if (!planeID.
isValid) { planeID = theHit->WireID(); }
148 hitIndex[
k] = theHit.key();
149 float wire_pitch = geom->WirePitch(theHit->View());
151 float theHit_Xpos = -999.;
152 float theHit_Ypos = -999.;
153 float theHit_Zpos = -999.;
155 auto const& sp = spFromShowerHits.at(hit_index);
158 theHit_Xpos = sp[0]->XYZ()[0];
159 theHit_Ypos = sp[0]->XYZ()[1];
160 theHit_Zpos = sp[0]->XYZ()[2];
163 MF_LOG_INFO(
"ShowerCalorimetry")
164 <<
"no sp associated w/this hit ... we will skip this hit";
168 TVector3 pos(theHit_Xpos, theHit_Ypos, theHit_Zpos);
170 float this_pitch = wire_pitch;
171 float angleToVert = geom->WireAngleToVertical(theHit->View(), theHit->WireID());
172 angleToVert -= 0.5 * ::util::pi<>();
174 float cosgamma =
std::abs(sin(angleToVert) *
shower->Direction().Y() +
175 cos(angleToVert) *
shower->Direction().Z());
176 if (cosgamma > 0) this_pitch /= cosgamma;
177 if (this_pitch < wire_pitch) this_pitch = wire_pitch;
178 pitch[
k] = this_pitch;
181 if (fSCE && sce->EnableCalSpatialSCE()) {
186 posOffsets = sce->GetCalPosOffsets(
geo::Point_t(pos), theHit->WireID().TPC);
191 pos.Y() + this_pitch *
shower->Direction().Y(),
192 pos.Z() + this_pitch *
shower->Direction().Z()},
193 theHit->WireID().TPC);
195 TVector3 dir_corr = {
196 this_pitch *
shower->Direction().X() - dirOffsets.X() + posOffsets.X(),
197 this_pitch *
shower->Direction().Y() + dirOffsets.Y() - posOffsets.Y(),
198 this_pitch *
shower->Direction().Z() + dirOffsets.Z() - posOffsets.Z()};
200 pitch[
k] = dir_corr.Mag();
202 theHit_Xpos -= posOffsets.X();
203 theHit_Ypos += posOffsets.Y();
204 theHit_Zpos += posOffsets.Z();
206 xyz[
k].SetXYZ(theHit_Xpos, theHit_Ypos, theHit_Zpos);
207 resRange[
k] = std::hypot(theHit_Xpos -
shower->ShowerStart().X(),
208 theHit_Ypos -
shower->ShowerStart().Y(),
209 theHit_Zpos -
shower->ShowerStart().Z());
211 dQdx[
k] = theHit->Integral() / pitch[
k];
215 dEdx[
k] = caloAlg.dEdx_AREA(clockData,
detProp, *theHit, pitch[
k]),
217 kineticEnergy += dEdx[
k];
221 caloVector.emplace_back(kineticEnergy,
233 assnShowerCaloVector.emplace_back(shower_index);
238 for (
size_t i = 0; i < assnShowerCaloVector.size(); i++) {
239 if (assnShowerCaloVector[i] == std::numeric_limits<size_t>::max())
continue;
241 art::Ptr<recob::Shower> shower_ptr(showerHandle, assnShowerCaloVector[i]);
246 e.put(std::move(caloPtr));
247 e.put(std::move(associationPtr));
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Utilities related to art service access.
Declaration of signal hit object.
The data type to uniquely identify a Plane.
bool isValid
Whether this ID points to a valid element.
ShowerCalorimetry(fhicl::ParameterSet const &p)
void produce(art::Event &e) override
process_name can override from command line with o or output calo
std::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
float dEdx(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, TP3D &tp3d)
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.
art::InputTag fSpacePointTag
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
art framework interface to geometry description