145 typedef struct locVtx
155 typedef struct trkiend
163 float xtpccent = geo->TPCXCent();
167 auto detProp = gar::providerFrom<detinfo::DetectorPropertiesService>();
168 double DriftVelocity = detProp->DriftVelocity(detProp->Efield(),detProp->Temperature());
174 std::unique_ptr< std::vector<rec::Track> > trkCol(
new std::vector<rec::Track>);
175 std::unique_ptr<std::vector<gar::rec::TPCCluster> > TPCClusterCol (
new std::vector<gar::rec::TPCCluster> );
177 std::unique_ptr< std::vector<rec::TrackIoniz> > ionCol(
new std::vector<rec::TrackIoniz>);
179 std::unique_ptr< std::vector<rec::Vertex> > vtxCol(
new std::vector<rec::Vertex>);
186 auto const& inputTracks = *inputTrackHandle;
188 auto const& inputTPCClusters = *inputTPCClusterHandle;
190 const art::FindManyP<rec::TPCCluster> TPCClustersFromInputTracks(inputTrackHandle,e,
fInputTrackLabel);
191 const art::FindManyP<rec::TrackIoniz> TrackIonizFromInputTracks(inputTrackHandle,e,
fInputTrackLabel);
192 const art::FindManyP<rec::Vertex, rec::TrackEnd> VerticesFromInputTracks(inputTrackHandle,e,
fInputVertexLabel);
193 const art::FindManyP<rec::Hit> HitsFromInputTPCClusters(inputTPCClusterHandle,e,
fInputTPCClusterLabel);
209 std::map<rec::IDNumber,size_t> hcim;
210 for (
size_t iclus = 0; iclus<inputTPCClusters.size(); ++iclus)
212 rec::IDNumber clusid = inputTPCClusters.at(iclus).getIDNumber();
213 hcim[clusid] = iclus;
219 std::vector<int> trackside;
220 float chanpos[3] = {0,0,0};
221 for (
size_t itrack = 0; itrack < inputTracks.size(); ++itrack)
225 for (
size_t iTPCCluster=0; iTPCCluster<TPCClustersFromInputTracks.at(itrack).size(); ++iTPCCluster)
227 size_t icindex = hcim[TPCClustersFromInputTracks.at(itrack).at(iTPCCluster)->getIDNumber()];
228 for (
size_t ihit=0; ihit < HitsFromInputTPCClusters.at(icindex).size(); ++ihit)
230 auto hitchan = HitsFromInputTPCClusters.at(icindex).at(ihit)->Channel();
231 geo->ChannelToPosition(hitchan, chanpos);
232 if (chanpos[0] > xtpccent)
244 trackside.push_back(1);
248 trackside.push_back(-1);
256 size_t nti = inputTracks.size();
257 std::vector<int> mergedflag(nti,-1);
258 std::vector<int> fwdflag(nti,0);
259 std::vector<float> dx(nti,0);
261 for (
size_t itrack = 0; itrack < inputTracks.size(); ++itrack)
263 if (mergedflag.at(itrack) >= 0)
continue;
264 for (
size_t jtrack = itrack+1; jtrack < inputTracks.size(); ++jtrack)
266 if (mergedflag.at(jtrack)>=0)
continue;
267 if (trackside.at(itrack) == trackside.at(jtrack))
continue;
268 if (
cathodematch(inputTracks.at(itrack),inputTracks.at(jtrack),fwdflag.at(itrack),fwdflag.at(jtrack),dx.at(itrack)))
272 std::cout <<
"found a merge. dx= " <<
274 " flip flags: " << fwdflag.at(itrack) <<
" " << fwdflag.at(jtrack) <<
std::endl;
276 mergedflag.at(itrack) = jtrack;
277 mergedflag.at(jtrack) = itrack;
278 dx.at(jtrack) = -dx.at(itrack);
289 std::map<rec::IDNumber,locVtx_t> vtxmap;
292 std::map<rec::IDNumber,std::vector<trkiend_t>> vttrackmap;
295 std::map<rec::IDNumber,bool> vtxshifted;
300 for (
size_t itrack = 0; itrack < inputTracks.size(); ++itrack)
303 tmpti.trkindex = itrack;
304 tmpti.dx = dx.at(itrack);
306 for (
size_t ivtx = 0; ivtx < VerticesFromInputTracks.at(itrack).size(); ++ivtx)
308 auto vtxp = VerticesFromInputTracks.at(itrack).at(ivtx);
310 auto vtxiter = vtxmap.find(vtxid);
311 if (vtxiter == vtxmap.end())
314 tmpvtxdat.fTime = vtxp->Time();
315 for (
int i=0; i<3; ++i)
317 tmpvtxdat.fPosition[i] = vtxp->Position()[i];
319 for (
int i=0; i<9; ++i)
321 tmpvtxdat.fCovMat[i] = vtxp->CovMat()[i];
323 vtxmap[vtxid] = tmpvtxdat;
324 vtxshifted[vtxid] =
false;
326 std::vector<trkiend_t> trkindexvector;
327 tmpti.trkend = *(VerticesFromInputTracks.data(itrack).at(ivtx));
328 trkindexvector.push_back(tmpti);
329 vttrackmap[vtxid] = trkindexvector;
333 tmpti.trkend = *(VerticesFromInputTracks.data(itrack).at(ivtx));
334 vttrackmap[vtxid].push_back(tmpti);
343 bool moretodo =
true;
347 for (
const auto &vtxi : vttrackmap)
349 if (vtxshifted[vtxi.first])
continue;
353 for (
size_t i=0; i< vtxi.second.size(); ++i)
355 size_t itrack = vtxi.second.at(i).trkindex;
356 if (mergedflag.at(itrack) >= 0 || dx.at(itrack) != 0)
358 avgdx += dx.at(itrack);
364 avgdx /= (
float) numdx;
365 vtxshifted[vtxi.first] =
true;
368 vtxmap[vtxi.first].fPosition[0] += avgdx;
370 double ts = vtxmap[vtxi.first].fTime;
371 double deltat = avgdx/DriftVelocity;
373 vtxmap[vtxi.first].fTime = ts;
376 for (
size_t i=0; i< vtxi.second.size(); ++i)
378 size_t itrack = vtxi.second.at(i).trkindex;
379 if (mergedflag.at(itrack) < 0 && dx.at(itrack) == 0)
381 dx.at(itrack) = avgdx;
390 std::map<rec::IDNumber,size_t> vtxoutmap;
391 for (
const auto &vtxr : vtxmap)
393 vtxCol->emplace_back(vtxr.second.fPosition,vtxr.second.fCovMat,vtxr.second.fTime);
394 vtxoutmap[vtxr.first] = vtxCol->size() - 1;
402 for (
size_t itrack = 0; itrack < inputTracks.size(); ++itrack)
404 if (mergedflag.at(itrack) < 0)
406 TrackPar tpi(inputTracks.at(itrack));
407 double ts = tpi.getTime();
408 double deltat = dx.at(itrack)/DriftVelocity;
410 TrackPar tpm(tpi.getLengthForwards(),
411 tpi.getLengthBackwards(),
412 tpi.getNTPCClusters(),
413 tpi.getXBeg() + dx.at(itrack),
414 tpi.getTrackParametersBegin(),
416 tpi.getChisqForwards(),
417 tpi.getXEnd() + dx.at(itrack),
418 tpi.getTrackParametersEnd(),
420 tpi.getChisqBackwards(),
422 trkCol->push_back(tpm.CreateTrack());
426 auto const trackpointer = trackPtrMaker(trkCol->size()-1);
427 float cpos[3] = {0,0,0};
428 for (
size_t iTPCCluster=0; iTPCCluster<TPCClustersFromInputTracks.at(itrack).size(); ++iTPCCluster)
430 auto const &tc = TPCClustersFromInputTracks.at(itrack).at(iTPCCluster);
431 for (
size_t i=0; i<3; ++i)
433 cpos[i] = tc->Position()[i];
435 cpos[0] += dx.at(itrack);
436 TPCClusterCol->emplace_back(tc->Signal(),
443 auto const TPCClusterPointer = TPCClusterPtrMaker(TPCClusterCol->size()-1);
444 TPCClusterTrkAssns->addSingle(TPCClusterPointer,trackpointer);
446 size_t icindex = hcim[oldclusid];
447 for (
size_t ihit=0; ihit < HitsFromInputTPCClusters.at(icindex).size(); ++ihit)
449 HitTPCClusterAssns->addSingle(HitsFromInputTPCClusters.at(icindex).at(ihit),TPCClusterPointer);
456 for (
size_t iTrkIoniz=0; iTrkIoniz<TrackIonizFromInputTracks.at(itrack).size(); ++iTrkIoniz)
458 ionCol->push_back(*TrackIonizFromInputTracks.at(itrack).at(iTrkIoniz));
459 auto const ionizpointer = ionizPtrMaker(ionCol->size()-1);
460 ionTrkAssns->addSingle(ionizpointer, trackpointer);
466 for (
size_t ivtx = 0; ivtx < VerticesFromInputTracks.at(itrack).size(); ++ivtx)
468 auto vtxp = VerticesFromInputTracks.at(itrack).at(ivtx);
469 auto trkend = *(VerticesFromInputTracks.data(itrack).at(ivtx));
471 size_t ivout = vtxoutmap[vtxid];
472 auto const vtxptr = vtxPtrMaker(ivout);
473 trkVtxAssns->addSingle(trackpointer,vtxptr,trkend);
479 if (mergedflag.at(itrack) < 0)
481 MF_LOG_WARNING(
"tpccathodestitch: inconsistent merge flags ") << itrack <<
" " << mergedflag.at(itrack);
484 size_t jtrack = mergedflag.at(itrack);
485 if (jtrack < itrack)
continue;
490 TrackPar tpi(inputTracks.at(itrack), fwdflag.at(itrack) != 1);
491 TrackPar tpj(inputTracks.at(jtrack), fwdflag.at(jtrack) != 1);
493 tpi.setXBeg( tpi.getXBeg() + dx.at(itrack) );
494 tpi.setXEnd( tpi.getXEnd() + dx.at(itrack) );
495 tpj.setXBeg( tpj.getXBeg() + dx.at(jtrack) );
496 tpj.setXEnd( tpj.getXEnd() + dx.at(jtrack) );
499 double ts = tpi.getTime();
500 int deltat = dx.at(itrack)/DriftVelocity;
501 if ( (
int) ts + deltat >= 0)
506 TrackPar tpm(tpi.getLengthForwards() + tpj.getLengthForwards(),
507 tpi.getLengthBackwards() + tpj.getLengthBackwards(),
508 tpi.getNTPCClusters() + tpj.getNTPCClusters(),
510 tpi.getTrackParametersBegin(),
512 tpi.getChisqForwards() + tpj.getChisqForwards(),
514 tpj.getTrackParametersEnd(),
516 tpi.getChisqBackwards() + tpj.getChisqBackwards(),
518 trkCol->push_back(tpm.CreateTrack());
519 auto const trackpointer = trackPtrMaker(trkCol->size()-1);
523 float cpos[3] = {0,0,0};
524 for (
size_t iTPCCluster=0; iTPCCluster<TPCClustersFromInputTracks.at(itrack).size(); ++iTPCCluster)
526 auto const &tc = TPCClustersFromInputTracks.at(itrack).at(iTPCCluster);
527 for (
size_t i=0; i<3; ++i)
529 cpos[i] = tc->Position()[i];
531 cpos[0] += dx.at(itrack);
532 TPCClusterCol->emplace_back(tc->Signal(),
539 auto const TPCClusterPointer = TPCClusterPtrMaker(TPCClusterCol->size()-1);
540 TPCClusterTrkAssns->addSingle(TPCClusterPointer,trackpointer);
542 size_t icindex = hcim[oldclusid];
543 for (
size_t ihit=0; ihit < HitsFromInputTPCClusters.at(icindex).size(); ++ihit)
545 HitTPCClusterAssns->addSingle(HitsFromInputTPCClusters.at(icindex).at(ihit),TPCClusterPointer);
548 for (
size_t iTPCCluster=0; iTPCCluster<TPCClustersFromInputTracks.at(jtrack).size(); ++iTPCCluster)
550 auto const &tc = TPCClustersFromInputTracks.at(jtrack).at(iTPCCluster);
551 for (
size_t i=0; i<3; ++i)
553 cpos[i] = tc->Position()[i];
555 cpos[0] += dx.at(jtrack);
556 TPCClusterCol->emplace_back(tc->Signal(),
563 auto const TPCClusterPointer = TPCClusterPtrMaker(TPCClusterCol->size()-1);
564 TPCClusterTrkAssns->addSingle(TPCClusterPointer,trackpointer);
566 size_t icindex = hcim[oldclusid];
567 for (
size_t ihit=0; ihit < HitsFromInputTPCClusters.at(icindex).size(); ++ihit)
569 HitTPCClusterAssns->addSingle(HitsFromInputTPCClusters.at(icindex).at(ihit),TPCClusterPointer);
576 const auto itif = TrackIonizFromInputTracks.at(itrack).at(0)->getFWD_dSigdXs();
577 const auto itib = TrackIonizFromInputTracks.at(itrack).at(0)->getBAK_dSigdXs();
578 const auto jtif = TrackIonizFromInputTracks.at(jtrack).at(0)->getFWD_dSigdXs();
579 const auto jtib = TrackIonizFromInputTracks.at(jtrack).at(0)->getBAK_dSigdXs();
583 if (fwdflag.at(itrack) != 1)
590 if (fwdflag.at(jtrack) != 1)
596 for (
size_t i=0; i<jmtif.size(); ++i)
598 mtif.push_back(jmtif.at(i));
600 for (
size_t i=0; i<jmtib.size(); ++i)
602 mtib.push_back(jmtib.at(i));
605 tim.setData(mtif,mtib);
606 ionCol->push_back(tim);
607 auto const ionizpointer = ionizPtrMaker(ionCol->size()-1);
608 ionTrkAssns->addSingle(ionizpointer, trackpointer);
610 for (
size_t ivtx = 0; ivtx < VerticesFromInputTracks.at(itrack).size(); ++ivtx)
612 auto vtxp = VerticesFromInputTracks.at(itrack).at(ivtx);
613 auto trkend = *(VerticesFromInputTracks.data(itrack).at(ivtx));
614 if (fwdflag.at(itrack) != 1)
619 size_t ivout = vtxoutmap[vtxid];
620 auto const vtxptr = vtxPtrMaker(ivout);
621 trkVtxAssns->addSingle(trackpointer,vtxptr,trkend);
std::string fInputTrackLabel
input tracks and associations with TPCClusters. Get vertices associated with these tracks from the as...
int fPrintLevel
debug printout: 0: none, 1: just track parameters and residuals, 2: all
std::string fInputTPCClusterLabel
input TPC Clusters
std::string fInputVertexLabel
input vertices and associations with tracks
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
#define MF_LOG_WARNING(category)
bool cathodematch(const gar::rec::Track &trackA, const gar::rec::Track &trackB, int &fwdflagA, int &fwdflagB, float &deltaX)
LArSoft geometry interface.
QTextStream & endl(QTextStream &s)