16 #include <sys/types.h> 38 #include "larevt/CalibrationDBI/Interface/ChannelStatusService.h" 39 #include "larevt/CalibrationDBI/Interface/ChannelStatusProvider.h" 94 void GetPitch(
art::Ptr<recob::Hit> hit, std::vector<double> trkx, std::vector<double> trky, std::vector<double> trkz, std::vector<double> trkw, std::vector<double> trkx0,
double *xyz3d,
double &pitch,
double TickT0);
129 fUseArea(pset.get< bool >(
"UseArea") ),
133 produces< std::vector<anab::Calorimetry> >();
134 produces< art::Assns<recob::Track, anab::Calorimetry> >();
152 auto const* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
155 std::vector<art::Ptr<recob::Track> > tracklist;
163 lariov::ChannelStatusProvider
const& channelStatus
166 size_t nplanes = geom->
Nplanes();
169 std::unique_ptr< std::vector<anab::Calorimetry> > calorimetrycol(
new std::vector<anab::Calorimetry>);
177 for(
size_t trkIter = 0; trkIter < tracklist.size(); ++trkIter){
179 decltype(
auto) larEnd = tracklist[trkIter]->Trajectory().End();
185 uint32_t channel = 0;
186 unsigned int cstat = 0;
187 unsigned int tpc = 0;
188 unsigned int wire = 0;
189 unsigned int plane = 0;
191 std::vector< art::Ptr<recob::Hit> > allHits = fmht.at(trkIter);
194 if ( fmt0.isValid() ) {
195 std::vector< art::Ptr<anab::T0> > allT0 = fmt0.at(trkIter);
196 if ( allT0.size() ) T0 = allT0[0]->Time();
197 TickT0 = T0 / detprop->SamplingRate();
200 std::vector< std::vector<unsigned int> >
hits(nplanes);
203 for (
size_t ah = 0; ah< allHits.size(); ++ah){
204 hits[allHits[ah]->WireID().Plane].push_back(ah);
207 for (
size_t ipl = 0; ipl < nplanes; ++ipl){
223 float Trk_Length = 0.;
224 std::vector<float> vdEdx;
225 std::vector<float> vresRange;
226 std::vector<float> vdQdx;
227 std::vector<float> deadwire;
228 std::vector<TVector3> vXYZ;
231 unsigned int wire0 = 100000;
232 unsigned int wire1 = 0;
242 std::vector<double> spdelta;
245 std::vector<double> ChargeBeg;
246 std::stack<double> ChargeEnd;
249 double fTrkPitch = 0;
250 for (
size_t itp = 0; itp < tracklist[trkIter]->NumberTrajectoryPoints(); ++itp){
251 const auto& pos = tracklist[trkIter]->LocationAtPoint(itp);
252 const double Position[3] = { pos.X(), pos.Y(), pos.Z() };
260 << e <<
"\n setting pitch (C) to " 269 double xx = 0.,yy = 0.,
zz = 0.;
272 std::vector<double> trkx;
273 std::vector<double> trky;
274 std::vector<double> trkz;
275 std::vector<double> trkw;
276 std::vector<double> trkx0;
277 for (
size_t i = 0; i<hits[ipl].size(); ++i){
279 std::vector< art::Ptr<recob::SpacePoint> > sptv = fmspts.at(hits[ipl][i]);
280 for (
size_t j = 0; j < sptv.size(); ++j){
282 double t = allHits[hits[ipl][i]]->PeakTime() - TickT0;
283 double x = detprop->ConvertTicksToX(t, allHits[hits[ipl][i]]->WireID().
Plane, allHits[hits[ipl][i]]->WireID().TPC, allHits[hits[ipl][i]]->WireID().Cryostat);
284 double w = allHits[hits[ipl][i]]->WireID().Wire;
286 trkx.push_back(sptv[j]->XYZ()[0]-detprop->ConvertTicksToX(TickT0, allHits[hits[ipl][i]]->WireID().Plane, allHits[hits[ipl][i]]->WireID().TPC, allHits[hits[ipl][i]]->WireID().Cryostat));
289 trkx.push_back(sptv[j]->XYZ()[0]);
291 trky.push_back(sptv[j]->XYZ()[1]);
292 trkz.push_back(sptv[j]->XYZ()[2]);
297 for (
size_t ihit = 0; ihit < hits[ipl].size(); ++ihit){
302 plane = allHits[hits[ipl][ihit]]->WireID().Plane;
303 tpc = allHits[hits[ipl][ihit]]->WireID().TPC;
304 cstat = allHits[hits[ipl][ihit]]->WireID().Cryostat;
307 planeID.
Plane = plane;
311 wire = allHits[hits[ipl][ihit]]->WireID().Wire;
312 time = allHits[hits[ipl][ihit]]->PeakTime();
313 stime = allHits[hits[ipl][ihit]]->PeakTimeMinusRMS();
314 etime = allHits[hits[ipl][ihit]]->PeakTimePlusRMS();
316 double charge = allHits[hits[ipl][ihit]]->PeakAmplitude();
317 if (
fUseArea) charge = allHits[hits[ipl][ihit]]->Integral();
322 bool fBadhit =
false;
323 if (fmthm.isValid()){
324 auto vhit = fmthm.at(trkIter);
325 auto vmeta = fmthm.
data(trkIter);
326 for (
size_t ii = 0; ii<vhit.size(); ++ii){
327 if (vhit[ii].key() == allHits[hits[ipl][ihit]].key()){
332 if (vmeta[ii]->Index()>=tracklist[trkIter]->NumberTrajectoryPoints()){
333 throw cet::exception(
"Calorimetry_module.cc") <<
"Requested track trajectory index "<<vmeta[ii]->Index()<<
" exceeds the total number of trajectory points "<<tracklist[trkIter]->NumberTrajectoryPoints()<<
" for track index "<<trkIter<<
". Something is wrong with the track reconstruction. Please contact tjyang@fnal.gov";
335 if (!tracklist[trkIter]->HasValidPoint(vmeta[ii]->Index())){
339 double angleToVert = geom->
WireAngleToVertical(vhit[ii]->View(), vhit[ii]->WireID().TPC, vhit[ii]->WireID().Cryostat) - 0.5*::util::pi<>();
340 const auto&
dir = tracklist[trkIter]->DirectionAtPoint(vmeta[ii]->Index());
341 double cosgamma = std::abs(std::sin(angleToVert)*dir.Y() + std::cos(angleToVert)*dir.Z());
348 auto loc = tracklist[trkIter]->LocationAtPoint(vmeta[ii]->Index());
357 GetPitch(allHits[hits[ipl][ihit]], trkx, trky, trkz, trkw, trkx0, xyz3d, pitch, TickT0);
359 if (fBadhit)
continue;
360 if (xyz3d[2]<-100)
continue;
361 if (pitch<=0) pitch = fTrkPitch;
362 if (!pitch)
continue;
368 spdelta.push_back(0);
370 double dx = xyz3d[0] -
xx;
371 double dy = xyz3d[1] - yy;
372 double dz = xyz3d[2] -
zz;
373 spdelta.push_back(sqrt(dx*dx + dy*dy + dz*dz));
374 Trk_Length += spdelta.back();
380 ChargeBeg.push_back(charge);
381 ChargeEnd.push(charge);
383 double MIPs = charge;
384 double dQdx = MIPs/pitch;
389 Kin_En = Kin_En + dEdx * pitch;
391 if (allHits[hits[ipl][ihit]]->WireID().Wire < wire0) wire0 = allHits[hits[ipl][ihit]]->WireID().Wire;
392 if (allHits[hits[ipl][ihit]]->WireID().Wire > wire1) wire1 = allHits[hits[ipl][ihit]]->WireID().Wire;
394 fMIPs.push_back(MIPs);
395 fdEdx.push_back(dEdx);
396 fdQdx.push_back(dQdx);
397 fwire.push_back(wire);
398 ftime.push_back(time);
402 TVector3 v(xyz3d[0],xyz3d[1],xyz3d[2]);
421 for (
int isp = 0; isp<
fnsps; ++isp){
423 USChg += ChargeBeg[isp];
426 while (!ChargeEnd.empty()){
427 if (countsp>3)
break;
428 DSChg += ChargeEnd.top();
437 fResRng[fnsps - 1] = spdelta[fnsps - 1] / 2;
438 for(
int isp = fnsps - 2; isp > -1; isp--) {
443 for(
int isp = 1; isp <
fnsps; isp++) {
448 LOG_DEBUG(
"CaloPrtHit") <<
" pt wire time ResRng MIPs pitch dE/dx Ai X Y Z\n";
451 for (
int i = 0; i <
fnsps; ++i){
452 vresRange.push_back(
fResRng[i]);
453 vdEdx.push_back(
fdEdx[i]);
454 vdQdx.push_back(
fdQdx[i]);
455 vXYZ.push_back(
fXYZ[i]);
456 if (i!=0 && i!= fnsps-1){
462 LOG_DEBUG(
"CaloPrtHit") <<std::setw(4)<< trkIter
466 <<std::setw(4) <<
fwire[i]
467 << std::setw(6) << (int)
ftime[i]
468 << std::setiosflags(std::ios::fixed | std::ios::showpoint)
469 << std::setprecision(2)
471 << std::setprecision(1)
472 << std::setw(8) <<
fMIPs[i]
473 << std::setprecision(2)
474 << std::setw(8) <<
fpitch[i]
475 << std::setw(8) <<
fdEdx[i]
476 << std::setw(8) << Ai
477 << std::setw(8) <<
fXYZ[i].x()
478 << std::setw(8) <<
fXYZ[i].y()
479 << std::setw(8) <<
fXYZ[i].z()
483 PIDA = PIDA / (double)nPIDA;
488 LOG_DEBUG(
"CaloPrtTrk") <<
"Plane # "<< ipl
490 << std::setprecision(2) << fTrkPitch
491 <<
" nhits= " << fnsps
493 << std::setiosflags(std::ios::fixed | std::ios::showpoint)
494 <<
"Trk Length= " << std::setprecision(1)
495 << Trk_Length <<
" cm," 496 <<
" KE calo= " << std::setprecision(1)
502 for (
unsigned int iw = wire0; iw<wire1+1; ++iw){
503 plane = allHits[hits[ipl][0]]->WireID().Plane;
504 tpc = allHits[hits[ipl][0]]->WireID().TPC;
505 cstat = allHits[hits[ipl][0]]->WireID().Cryostat;
507 if (channelStatus.IsBad(channel)){
508 LOG_DEBUG(
"Calorimetry") <<
"Found dead wire at Plane = " << plane
510 unsigned int closestwire = 0;
511 unsigned int endwire = 0;
512 unsigned int dwire = 100000;
513 double mindis = 100000;
514 double goodresrange = 0;
516 for (
size_t ihit = 0; ihit <hits[ipl].size(); ++ihit){
520 channel = allHits[hits[ipl][ihit]]->Channel();
521 if (channelStatus.IsBad(channel))
continue;
523 std::vector< art::Ptr<recob::SpacePoint> > sppv = fmspts.at(hits[ipl][ihit]);
524 if(sppv.size() < 1)
continue;
530 double dis1 = (larEnd - xyz).Mag2();
531 if (dis1) dis1 = std::sqrt(dis1);
533 endwire = allHits[hits[ipl][ihit]]->WireID().Wire;
537 closestwire = allHits[hits[ipl][ihit]]->WireID().Wire;
538 dwire =
util::absDiff(allHits[hits[ipl][ihit]]->WireID().Wire, iw);
544 deadwire.push_back(goodresrange+(
int(closestwire)-
int(iw))*fTrkPitch);
547 deadwire.push_back(goodresrange+(
int(iw)-
int(closestwire))*fTrkPitch);
567 evt.
put(std::move(calorimetrycol));
568 evt.
put(std::move(assn));
581 auto const* dp = lar::providerFrom<detinfo::DetectorPropertiesService>();
584 std::map<double,size_t> sptmap;
586 std::map<size_t, int> sptsignmap;
594 for (
size_t i = 0; i<trkx.size(); ++i){
595 double distance = pow((trkw[i]-w0)*wire_pitch,2)+pow(trkx0[i]-x0,2);
596 if (distance>0) distance = sqrt(distance);
598 sptmap.insert(std::pair<double,size_t>(distance,i));
599 if (w0-trkw[i]>0) sptsignmap.insert(std::pair<size_t,int>(i,1));
600 else sptsignmap.insert(std::pair<size_t,int>(i,-1));
604 std::vector<double> vx;
605 std::vector<double> vy;
606 std::vector<double> vz;
607 std::vector<double> vs;
609 double kx = 0, ky = 0, kz = 0;
612 for (
auto isp = sptmap.begin(); isp!=sptmap.end(); isp++){
616 xyz[0] = trkx[isp->second];
617 xyz[1] = trky[isp->second];
618 xyz[2] = trkz[isp->second];
620 double distancesign = sptsignmap[isp->second];
622 if (np==0&&isp->first>30){
631 vx.push_back(xyz[0]);
632 vy.push_back(xyz[1]);
633 vz.push_back(xyz[2]);
634 vs.push_back(isp->first*distancesign);
645 TGraph *xs =
new TGraph(np,&vs[0],&vx[0]);
655 if (np>2) pol = (TF1*) xs->GetFunction(
"pol2");
656 else pol = (TF1*) xs->GetFunction(
"pol1");
657 xyz3d[0] = pol->Eval(0);
658 kx = pol->GetParameter(1);
666 TGraph *ys =
new TGraph(np,&vs[0],&vy[0]);
675 if (np>2) pol = (TF1*) ys->GetFunction(
"pol2");
676 else pol = (TF1*) ys->GetFunction(
"pol1");
677 xyz3d[1] = pol->Eval(0);
678 ky = pol->GetParameter(1);
686 TGraph *zs =
new TGraph(np,&vs[0],&vz[0]);
695 if (np>2) pol = (TF1*) zs->GetFunction(
"pol2");
696 else pol = (TF1*) zs->GetFunction(
"pol1");
697 xyz3d[2] = pol->Eval(0);
698 kz = pol->GetParameter(1);
720 if (kx*kx+ky*ky+kz*kz){
721 double tot = sqrt(kx*kx+ky*ky+kz*kz);
728 double cosgamma = TMath::Abs(TMath::Sin(angleToVert)*ky+TMath::Cos(angleToVert)*kz);
729 if (cosgamma>0) pitch = wirePitch/cosgamma;
code to link reconstructed objects back to the MC truth information
Calorimetry(fhicl::ParameterSet const &pset)
Functions to help with numbers.
std::vector< double > fdEdx
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
void produce(art::Event &evt)
double dEdx_AREA(art::Ptr< recob::Hit > hit, double pitch, double T0=0) const
geo::WireID WireID() const
Initial tdc tick for hit.
Declaration of signal hit object.
The data type to uniquely identify a Plane.
bool isValid
Whether this ID points to a valid element.
CryostatID_t Cryostat
Index of cryostat.
WireID_t Wire
Index of the wire within its plane.
data_const_reference data(size_type i) const
std::vector< TVector3 > fXYZ
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
std::vector< double > fResRng
double ThetaZ() const
Angle of the wires from positive z axis; .
ProductID put(std::unique_ptr< PROD > &&product)
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
bool BeginsOnBoundary(art::Ptr< recob::Track > lar_track)
View_t View() const
Which coordinate does this plane measure.
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
std::string fT0ModuleLabel
#define DEFINE_ART_MODULE(klass)
Provides recob::Track data product.
std::string fSpacePointModuleLabel
std::vector< double > ftime
std::vector< double > fetime
bool EndsOnBoundary(art::Ptr< recob::Track > lar_track)
void GetPitch(art::Ptr< recob::Hit > hit, std::vector< double > trkx, std::vector< double > trky, std::vector< double > trkz, std::vector< double > trkw, std::vector< double > trkx0, double *xyz3d, double &pitch, double TickT0)
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)
The data type to uniquely identify a TPC.
PlaneID_t Plane
Index of the plane within its TPC.
std::vector< double > fMIPs
Detector simulation of raw signals on wires.
constexpr auto absDiff(A const &a, B const &b)
Returns the absolute value of the difference between two values.
Encapsulate the geometry of a wire.
raw::ChannelID_t PlaneWireToChannel(WireID const &wireid) const
Returns the ID of the TPC channel connected to the specified wire.
float PeakTime() const
Time of the signal peak, in tick units.
Utility object to perform functions of association.
Encapsulate the construction of a single detector plane.
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
std::vector< double > fdQdx
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
tracking::Point_t Point_t
std::string fTrackModuleLabel
constexpr double kBogusD
obviously bogus double value
double TrackPitchInView(recob::Track const &track, geo::View_t view, size_t trajectory_point=0)
Provides projected wire pitch for the view.
std::vector< double > fstime
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
TPCID_t TPC
Index of the TPC within its cryostat.
std::vector< float > fpitch
recob::tracking::Plane Plane
Utility functions to extract information from recob::Track.
double WireAngleToVertical(geo::View_t view, geo::TPCID const &tpcid) const
Returns the angle of the wires in the specified view from vertical.
double dEdx_AMP(art::Ptr< recob::Hit > hit, double pitch, double T0=0) const
cet::coded_exception< error, detail::translate > exception