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();
181 double trackCosStart[3]={0.,0.,0.};
182 double trackCosEnd[3]={0.,0.,0.};
183 tracklist[trkIter]->Direction(trackCosStart,trackCosEnd);
189 uint32_t channel = 0;
190 unsigned int cstat = 0;
191 unsigned int tpc = 0;
192 unsigned int wire = 0;
193 unsigned int plane = 0;
195 std::vector< art::Ptr<recob::Hit> > allHits = fmht.at(trkIter);
198 if ( fmt0.isValid() ) {
199 std::vector< art::Ptr<anab::T0> > allT0 = fmt0.at(trkIter);
200 if ( allT0.size() ) T0 = allT0[0]->Time();
201 TickT0 = T0 / detprop->SamplingRate();
204 std::vector< std::vector<unsigned int> >
hits(nplanes);
207 for (
size_t ah = 0; ah< allHits.size(); ++ah){
208 hits[allHits[ah]->WireID().Plane].push_back(ah);
211 for (
size_t ipl = 0; ipl < nplanes; ++ipl){
227 double Trk_Length = 0.;
228 std::vector<double> vdEdx;
229 std::vector<double> vresRange;
230 std::vector<double> vdQdx;
231 std::vector<double> deadwire;
232 std::vector<TVector3> vXYZ;
235 unsigned int wire0 = 100000;
236 unsigned int wire1 = 0;
246 std::vector<double> spdelta;
249 std::vector<double> ChargeBeg;
250 std::stack<double> ChargeEnd;
253 double fTrkPitch = 0;
254 for (
size_t itp = 0; itp < tracklist[trkIter]->NumberTrajectoryPoints(); ++itp){
255 const TVector3& pos = tracklist[trkIter]->LocationAtPoint(itp);
256 const double Position[3] = { pos.X(), pos.Y(), pos.Z() };
264 << e <<
"\n setting pitch (C) to " 273 double xx = 0.,yy = 0.,
zz = 0.;
276 std::vector<double> trkx;
277 std::vector<double> trky;
278 std::vector<double> trkz;
279 std::vector<double> trkw;
280 std::vector<double> trkx0;
281 for (
size_t i = 0; i<hits[ipl].size(); ++i){
283 std::vector< art::Ptr<recob::SpacePoint> > sptv = fmspts.at(hits[ipl][i]);
284 for (
size_t j = 0; j < sptv.size(); ++j){
286 double t = allHits[hits[ipl][i]]->PeakTime() - TickT0;
287 double x = detprop->ConvertTicksToX(t, allHits[hits[ipl][i]]->WireID().
Plane, allHits[hits[ipl][i]]->WireID().TPC, allHits[hits[ipl][i]]->WireID().Cryostat);
288 double w = allHits[hits[ipl][i]]->WireID().Wire;
290 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));
293 trkx.push_back(sptv[j]->XYZ()[0]);
295 trky.push_back(sptv[j]->XYZ()[1]);
296 trkz.push_back(sptv[j]->XYZ()[2]);
301 for (
size_t ihit = 0; ihit < hits[ipl].size(); ++ihit){
306 plane = allHits[hits[ipl][ihit]]->WireID().Plane;
307 tpc = allHits[hits[ipl][ihit]]->WireID().TPC;
308 cstat = allHits[hits[ipl][ihit]]->WireID().Cryostat;
311 planeID.
Plane = plane;
315 wire = allHits[hits[ipl][ihit]]->WireID().Wire;
316 time = allHits[hits[ipl][ihit]]->PeakTime();
317 stime = allHits[hits[ipl][ihit]]->PeakTimeMinusRMS();
318 etime = allHits[hits[ipl][ihit]]->PeakTimePlusRMS();
320 double charge = allHits[hits[ipl][ihit]]->PeakAmplitude();
321 if (
fUseArea) charge = allHits[hits[ipl][ihit]]->Integral();
326 bool fBadhit =
false;
327 if (fmthm.isValid()){
328 auto vhit = fmthm.at(trkIter);
329 auto vmeta = fmthm.
data(trkIter);
330 for (
size_t ii = 0; ii<vhit.size(); ++ii){
331 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 TVector3&
dir = tracklist[trkIter]->DirectionAtPoint(vmeta[ii]->Index());
341 double cosgamma = std::abs(std::sin(angleToVert)*dir.Y() + std::cos(angleToVert)*dir.Z());
348 TVector3 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.
std::vector< double > fpitch
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)
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.
The data type to uniquely identify a TPC.
PlaneID_t Plane
Index of the plane within its TPC.
Provides recob::Track data product.
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.
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