33 inline T
sqr(T v) {
return v*v; }
46 this->reconfigure(pset);
51 fSPTAlg = pset.
get<
int >(
"SPTAlg", 0 );
52 fTrajOnly = pset.
get<
bool >(
"TrajOnly",
false);
53 ftmatch = pset.
get<
double >(
"TMatch");
54 fsmatch = pset.
get<
double >(
"SMatch");
68 TrackTrajectory(fHits);
74 throw cet::exception(
"CosmicTrackerAlg")<<
"Unknown SPTAlg "<<fSPTAlg<<
", needs to be 0 or 1";
77 if (!fTrajOnly&&trajPos.size()) MakeSPT(fHits);
87 detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
100 std::array<std::vector<geo::WireID>,3> trkWID;
101 std::array<std::vector<double>,3> trkX;
102 std::array<std::vector<double>,3> trkXErr;
104 std::array< std::vector<art::Ptr<recob::Hit>>,3> trajHits;
106 for (
size_t i = 0; i<fHits.size(); ++i){
107 trajHits[fHits[i]->WireID().Plane].push_back(fHits[i]);
110 std::vector<PlnLen> spl;
112 for(
unsigned int ipl = 0; ipl < 3; ++ipl) {
114 plnlen.
length = trajHits[ipl].size();
116 spl.push_back(plnlen);
121 for (
size_t ipl = 0; ipl <3; ++ipl){
122 if (!trajHits[ipl].size())
continue;
124 double xbeg0 = detprop->ConvertTicksToX(trajHits[spl[0].
index][0]->PeakTime(),
126 trajHits[spl[0].
index][0]->WireID().TPC,
127 trajHits[spl[0].
index][0]->WireID().Cryostat);
128 double xend0 = detprop->ConvertTicksToX(trajHits[spl[0].
index].back()->PeakTime(),
129 trajHits[spl[0].
index].back()->WireID().
Plane,
130 trajHits[spl[0].
index].back()->WireID().TPC,
131 trajHits[spl[0].
index].back()->WireID().Cryostat);
132 double xbeg1 = detprop->ConvertTicksToX(trajHits[ipl][0]->PeakTime(),
133 trajHits[ipl][0]->WireID().
Plane,
134 trajHits[ipl][0]->WireID().TPC,
135 trajHits[ipl][0]->WireID().Cryostat);
136 double xend1 = detprop->ConvertTicksToX(trajHits[ipl].back()->PeakTime(),
137 trajHits[ipl].back()->WireID().
Plane,
138 trajHits[ipl].back()->WireID().TPC,
139 trajHits[ipl].back()->WireID().Cryostat);
140 double dx1 = std::abs(xbeg0-xbeg1)+std::abs(xend0-xend1);
141 double dx2 = std::abs(xbeg0-xend1)+std::abs(xend0-xbeg1);
142 if (std::abs(xbeg1-xend1)>0.2
144 std::reverse(trajHits[ipl].
begin(),trajHits[ipl].
end());
164 for(
size_t ipl = 0; ipl < 3; ++ipl) {
166 trkWID[ipl].resize(trajHits[ipl].size());
167 trkX[ipl].resize(trajHits[ipl].size());
168 trkXErr[ipl].resize(trajHits[ipl].size());
169 for(
size_t iht = 0; iht < trajHits[ipl].size(); ++iht) {
170 trkWID[ipl][iht] = trajHits[ipl][iht]->WireID();
171 trkX[ipl][iht] = detprop->ConvertTicksToX(trajHits[ipl][iht]->PeakTime(),ipl, trajHits[ipl][iht]->WireID().TPC, trajHits[ipl][iht]->WireID().Cryostat);
172 trkXErr[ipl][iht] = 0.2 * trajHits[ipl][iht]->RMS() * trajHits[ipl][iht]->Multiplicity();
175 fTrackTrajectoryAlg.TrackTrajectory(trkWID, trkX, trkXErr, trajPos, trajDir);
176 if (!trajPos.size()||!trajDir.size()){
177 mf::LogWarning(
"CosmicTrackerAlg")<<
"Failed to reconstruct trajectory points.";
181 for (
auto ipos = trajPos.begin(), idir = trajDir.begin(); ipos != trajPos.end() - 1; ){
182 auto ipos1 = ipos +1;
183 if (*ipos1 == *ipos){
184 ipos = trajPos.erase(ipos);
185 idir = trajDir.erase(idir);
195 vw.resize(geom->Ncryostats());
196 vt.resize(geom->Ncryostats());
197 vtraj.resize(geom->Ncryostats());
198 for (
size_t cstat = 0; cstat < geom->Ncryostats(); ++cstat){
199 vw[cstat].resize(geom->Cryostat(cstat).NTPC());
200 vt[cstat].resize(geom->Cryostat(cstat).NTPC());
201 vtraj[cstat].resize(geom->Cryostat(cstat).NTPC());
202 for (
size_t tpc = 0; tpc < geom->Cryostat(cstat).NTPC(); ++tpc){
203 const geo::TPCGeo& tpcgeom = geom->Cryostat(cstat).TPC(tpc);
204 vw[cstat][tpc].resize(tpcgeom.
Nplanes());
205 vt[cstat][tpc].resize(tpcgeom.
Nplanes());
206 vtraj[cstat][tpc].resize(tpcgeom.
Nplanes());
207 for (
size_t plane = 0; plane < tpcgeom.
Nplanes(); ++plane){
208 for (
size_t i = 0; i< trajPos.size(); ++i){
209 double wirecord = geom->WireCoordinate(trajPos[i].
Y(),
212 double tick = detprop->ConvertXToTicks(trajPos[i].
X(),
216 vw[cstat][tpc][plane].push_back(wirecord);
217 vt[cstat][tpc][plane].push_back(tick);
218 vtraj[cstat][tpc][plane].push_back(i);
230 larprop = lar::providerFrom<detinfo::LArPropertiesService>();
231 detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
234 std::vector<std::map<int,double> > vtimemap(3);
235 std::vector<std::map<int,art::Ptr<recob::Hit> > > vhitmap(3);
238 for (
size_t ihit = 0; ihit<fHits.size(); ++ihit){
240 unsigned int w = hitWireID.
Wire;
241 unsigned int pl = hitWireID.
Plane;
242 double time = fHits[ihit]->PeakTime();
243 time -= detprop->GetXTicksOffset(fHits[ihit]->WireID().
Plane,
244 fHits[ihit]->WireID().TPC,
245 fHits[ihit]->WireID().Cryostat);
246 vtimemap[pl][
w] = time;
247 vhitmap[pl][
w] = fHits[ihit];
254 unsigned maxnumhits0 = 0;
255 unsigned maxnumhits1 = 0;
257 std::vector<double> tmin(vtimemap.size());
258 std::vector<double> tmax(vtimemap.size());
259 for (
size_t iclu = 0; iclu<vtimemap.size(); ++iclu){
264 for (
size_t iclu = 0; iclu<vtimemap.size(); ++iclu){
265 for (
auto itime = vtimemap[iclu].
begin(); itime!=vtimemap[iclu].end(); ++itime){
266 if (itime->second>tmax[iclu]){
267 tmax[iclu] = itime->second;
269 if (itime->second<tmin[iclu]){
270 tmin[iclu] = itime->second;
273 if (vtimemap[iclu].size()>maxnumhits0){
276 maxnumhits1 = maxnumhits0;
279 maxnumhits0 = vtimemap[iclu].size();
281 else if (vtimemap[iclu].size()>maxnumhits1){
283 maxnumhits1 = vtimemap[iclu].size();
287 std::swap(iclu1,iclu2);
290 for (
int iclu = 0; iclu<(int)vtimemap.size(); ++iclu){
291 if (iclu!=iclu1&&iclu!=iclu2) iclu3 = iclu;
294 if (iclu1!=-1&&iclu2!=-1){
296 auto ihit = vhitmap[iclu1].begin();
297 auto itime = vtimemap[iclu1].begin();
298 while (itime!=vtimemap[iclu1].
end()){
299 if (itime->second<
std::max(tmin[iclu1],tmin[iclu2])-ftmatch||
300 itime->second>
std::min(tmax[iclu1],tmax[iclu2])+ftmatch){
301 vtimemap[iclu1].erase(itime++);
302 vhitmap[iclu1].erase(ihit++);
310 ihit = vhitmap[iclu2].begin();
311 itime = vtimemap[iclu2].begin();
312 while (itime!=vtimemap[iclu2].
end()){
313 if (itime->second<
std::max(tmin[iclu1],tmin[iclu2])-ftmatch||
314 itime->second>
std::min(tmax[iclu1],tmax[iclu2])+ftmatch){
315 vtimemap[iclu2].erase(itime++);
316 vhitmap[iclu2].erase(ihit++);
325 if (!vtimemap[iclu1].size()){
327 std::swap(iclu3,iclu1);
330 if (!vtimemap[iclu2].size()){
332 std::swap(iclu3,iclu2);
333 std::swap(iclu1,iclu2);
336 if ((!vtimemap[iclu1].size())||(!vtimemap[iclu2].size()))
return;
339 auto times1 = vtimemap[iclu1].begin();
340 auto timee1 = vtimemap[iclu1].end();
342 auto times2 = vtimemap[iclu2].begin();
343 auto timee2 = vtimemap[iclu2].end();
346 double ts1 = times1->second;
347 double te1 = timee1->second;
348 double ts2 = times2->second;
349 double te2 = timee2->second;
352 if (std::abs(ts1-ts2)+std::abs(te1-te2)>std::abs(ts1-te2)+std::abs(te1-ts2)){
356 double timetick = detprop->SamplingRate()*1
e-3;
357 double Efield_drift = detprop->Efield(0);
358 double Temperature = detprop->Temperature();
360 double driftvelocity = detprop->DriftVelocity(Efield_drift,Temperature);
361 double timepitch = driftvelocity*timetick;
363 double wire_pitch = geom->WirePitch(
364 vhitmap[0].
begin()->second->WireID().Plane,
365 vhitmap[0].begin()->second->WireID().TPC,
366 vhitmap[0].begin()->second->WireID().Cryostat);
369 std::vector<double> vtracklength;
370 for (
size_t iclu = 0; iclu<vtimemap.size(); ++iclu){
372 double tracklength = 0;
373 if (vtimemap[iclu].size()==1){
374 tracklength = wire_pitch;
376 else if (!vtimemap[iclu].empty()) {
378 wend = vtimemap[iclu].cend();
379 double t0 = iw->first, w0 = iw->second;
380 while (++iw != wend) {
381 tracklength += std::sqrt(
sqr((iw->first-w0)*wire_pitch)+
sqr((iw->second-t0)*timepitch));
386 vtracklength.push_back(tracklength);
389 std::map<int,int> maxhitsMatch;
391 auto ihit1 = vhitmap[iclu1].begin();
392 for (
auto itime1 = vtimemap[iclu1].
begin();
393 itime1 != vtimemap[iclu1].end();
395 std::vector<art::Ptr<recob::Hit>> sp_hits;
396 sp_hits.push_back(ihit1->second);
397 double hitcoord[3] = {0.,0.,0.};
399 if (vtimemap[iclu1].size()==1){
400 length1 = wire_pitch;
403 for (
auto iw1 = vtimemap[iclu1].
begin(); iw1!=itime1; ++iw1){
406 length1 += std::sqrt(std::pow((iw1->first-iw2->first)*wire_pitch,2)
407 +std::pow((iw1->second-iw2->second)*timepitch,2));
410 double difference = 1e10;
411 auto matchedtime = vtimemap[iclu2].end();
412 auto matchedhit = vhitmap[iclu2].end();
414 auto ihit2 = vhitmap[iclu2].begin();
415 for (
auto itime2 = vtimemap[iclu2].
begin();
416 itime2!=vtimemap[iclu2].end();
418 if (maxhitsMatch[itime2->first])
continue;
420 if (vtimemap[iclu2].size()==1){
421 length2 = wire_pitch;
424 for (
auto iw1 = vtimemap[iclu2].
begin(); iw1!=itime2; ++iw1){
427 length2 += std::sqrt(std::pow((iw1->first-iw2->first)*wire_pitch,2)+std::pow((iw1->second-iw2->second)*timepitch,2));
430 if (rev) length2 = vtracklength[iclu2] - length2;
431 length2 = vtracklength[iclu1]/vtracklength[iclu2]*length2;
432 bool timematch = std::abs(itime1->second-itime2->second)<ftmatch;
433 if (timematch &&std::abs(length2-length1)<difference){
434 difference = std::abs(length2-length1);
435 matchedtime = itime2;
439 if (difference<fsmatch){
440 hitcoord[0] = detprop->ConvertTicksToX(matchedtime->second+
441 detprop->GetXTicksOffset((matchedhit->second)->WireID().Plane,
442 (matchedhit->second)->WireID().TPC,
443 (matchedhit->second)->WireID().Cryostat),
444 (matchedhit->second)->WireID().Plane,
445 (matchedhit->second)->WireID().TPC,
446 (matchedhit->second)->WireID().Cryostat);
457 bool sameTpcOrNot=geom->WireIDsIntersect(c1,c2, tmpWIDI);
460 hitcoord[1]=tmpWIDI.
y;
461 hitcoord[2]=tmpWIDI.
z;
464 if (hitcoord[1]>-1e9&&hitcoord[2]>-1e9){
465 maxhitsMatch[matchedtime->first] = 1;
466 sp_hits.push_back(matchedhit->second);
469 if (sp_hits.size()>1){
470 trajPos.push_back(TVector3(hitcoord));
471 trajHit.push_back(sp_hits);
482 larprop = lar::providerFrom<detinfo::LArPropertiesService>();
483 detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
485 double timetick = detprop->SamplingRate()*1
e-3;
486 double Efield_drift = detprop->Efield(0);
487 double Temperature = detprop->Temperature();
488 double driftvelocity = detprop->DriftVelocity(Efield_drift,Temperature);
489 double time_pitch = driftvelocity*timetick;
491 for (
size_t i = 0; i<fHits.size(); ++i){
498 double mindis1 = 1e9;
499 double mindis2 = 1e9;
500 double mindis2p = 1e9;
502 unsigned int wire = wireid.
Wire;
503 unsigned int plane = wireid.
Plane;
504 unsigned int tpc = wireid.
TPC;
505 unsigned int cstat = wireid.
Cryostat;
506 double wire_pitch = geom->WirePitch(plane,tpc,cstat);
509 for (
size_t j = 0; j<vw[cstat][tpc][plane].size(); ++j){
510 double dis = sqrt(pow(wire_pitch*(wire-vw[cstat][tpc][plane][j]),2)+
511 pow(time_pitch*(fHits[i]->PeakTime()-vt[cstat][tpc][plane][j]),2));
514 ip1 = vtraj[cstat][tpc][plane][j];
519 for (
size_t j = 0; j<vw[cstat][tpc][plane].size(); ++j){
520 if (
int(j)==ih1)
continue;
521 double dis = sqrt(pow(wire_pitch*(wire-vw[cstat][tpc][plane][j]),2)+
522 pow(time_pitch*(fHits[i]->PeakTime()-vt[cstat][tpc][plane][j]),2));
525 ip2 = vtraj[cstat][tpc][plane][j];
528 TVector3 v1(wire_pitch*(wire-vw[cstat][tpc][plane][ih1]),
529 time_pitch*(fHits[i]->PeakTime()-vt[cstat][tpc][plane][j]),
531 TVector3 v2(wire_pitch*(wire-vw[cstat][tpc][plane][j]),
532 time_pitch*(fHits[i]->PeakTime()-vt[cstat][tpc][plane][j]),
537 ip2p = vtraj[cstat][tpc][plane][j];
547 if (ip1==-1||ip2==-1){
549 throw cet::exception(
"CosmicTrackerAlg")<<
"Cannot find two nearest trajectory points.";
551 TVector3 v1(wire_pitch*(wire-vw[cstat][tpc][plane][ih1]),
552 time_pitch*(fHits[i]->PeakTime()-vt[cstat][tpc][plane][ih1]),
554 TVector3 v2(wire_pitch*(vw[cstat][tpc][plane][ih2]-vw[cstat][tpc][plane][ih1]),
555 time_pitch*(vt[cstat][tpc][plane][ih2]-vt[cstat][tpc][plane][ih1]),
559 throw cet::exception(
"CosmicTrackerAlg")<<
"Two identical trajectory points.";
561 double ratio = v1.Dot(v2)/v2.Mag2();
562 TVector3 pos = trajPos[ip1]+ratio*(trajPos[ip2]-trajPos[ip1]);
563 trkPos.push_back(pos);
564 if (trajDir[ip1].Mag()){
565 trkDir.push_back(trajDir[ip1]);
567 else if (trajDir[ip2].Mag()){
568 trkDir.push_back(trajDir[ip2]);
571 trkDir.push_back((trajPos[ip2]-trajPos[ip1]).Unit());
code to link reconstructed objects back to the MC truth information
double z
z position of intersection
unsigned int Nplanes() const
Number of planes in this tpc.
Geometry information for a single TPC.
CryostatID_t Cryostat
Index of cryostat.
WireID_t Wire
Index of the wire within its plane.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
T get(std::string const &key) const
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
bool greaterThan1(PlnLen p1, PlnLen p2)
PlaneID_t Plane
Index of the plane within its TPC.
Class defining a plane for tracking. It provides various functionalities to convert track parameters ...
double y
y position of intersection
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
TPCID_t TPC
Index of the TPC within its cryostat.
WireID()=default
Default constructor: an invalid TPC ID.
cet::coded_exception< error, detail::translate > exception