63 if (minTrkLength < 6) minTrkLength = 6;
67 while (t < tracks.
size()) {
70 if (t1->
Nodes().size() < minTrkLength) {
82 TVector3 trk1BackDir =
89 bool isBestFront1 =
false;
90 bool isBestFront2 =
false;
91 double xBestShift = 0;
92 double frontShift1 = t1->
Nodes()[0]->Point3D().X() - offsetFront1;
93 double backShift1 = t1->
Nodes()[t1->
Nodes().size() - 1]->Point3D().X() - offsetBack1;
95 double bestMatchScore = 99999;
97 for (
unsigned int u = t + 1; u < tracks.
size(); ++u) {
100 if (t2->
Nodes().size() < minTrkLength)
continue;
106 TVector3 trk2BackDir =
121 if (tpc1 == tpc2) giveUp =
true;
124 if (tpc1 == tpc2) giveUp =
true;
128 if (tpc1 == tpc2) giveUp =
true;
131 if (tpc1 == tpc2) giveUp =
true;
134 if (giveUp)
continue;
137 double surfaceGap = 10.0;
138 bool carryOn[4] = {
true,
true,
true,
true};
139 if (fabs(offsetFront1 - offsetFront2) > surfaceGap) carryOn[0] =
false;
140 if (fabs(offsetFront1 - offsetBack2) > surfaceGap) carryOn[1] =
false;
141 if (fabs(offsetBack1 - offsetFront2) > surfaceGap) carryOn[2] =
false;
142 if (fabs(offsetBack1 - offsetBack2) > surfaceGap) carryOn[3] =
false;
145 for (
int i = 0; i < 4; ++i) {
147 if (!carryOn[i])
continue;
156 t1Dir = trk1FrontDir;
157 xShift1 = frontShift1;
162 xShift1 = backShift1;
166 t2Dir = trk2FrontDir;
174 if (t1Dir.X() * t2Dir.X() > 0) {
continue; }
185 xBestShift = xShift1;
186 bestMatchScore =
score;
187 if (i < 2) { isBestFront1 =
true; }
189 isBestFront1 =
false;
191 if (i % 2 == 0) { isBestFront2 =
true; }
193 isBestFront2 =
false;
196 <<
"Tracks " << t <<
" and " << u <<
" matching score = " << score <<
std::endl 197 <<
" - " << t1Pos.X() <<
", " << t1Pos.Y() <<
", " << t1Pos.Z() <<
" :: " << t1Dir.X()
198 <<
", " << t1Dir.Y() <<
", " << t1Dir.Z() <<
std::endl 199 <<
" - " << t2Pos.X() <<
", " << t2Pos.Y() <<
", " << t2Pos.Z() <<
" :: " << t2Dir.X()
200 <<
", " << t2Dir.Y() <<
", " << t2Dir.Z() <<
std::endl 205 <<
" - " << isBestFront1 <<
" :: " << isBestFront2 <<
std::endl;
211 if (bestTrkMatch != 0x0) {
218 if (isBestFront1 && isBestFront2) { flip1 =
true; }
220 else if (isBestFront1 && !isBestFront2) {
224 else if (!isBestFront1 && !isBestFront2) {
232 bool canMerge =
true;
233 if ((tid1 < 0) || (tid2 < 0)) {
235 <<
"Track not found in the collection." <<
std::endl;
239 std::vector<pma::Track3D*> newTracks;
240 if (t1->
Flip(detProp, newTracks)) {
241 mf::LogInfo(
"pma::PMAlgStitching") <<
"Track 1 flipped.";
244 mf::LogInfo(
"pma::PMAlgStitching") <<
"Unable to flip Track 1.";
247 for (
const auto ts : newTracks) {
249 tracks.
tracks().emplace_back(ts, -1, tid1);
254 std::vector<pma::Track3D*> newTracks;
255 if (bestTrkMatch->
Flip(detProp, newTracks)) {
256 mf::LogInfo(
"pma::PMAlgStitching") <<
"Track 2 flipped.";
259 mf::LogInfo(
"pma::PMAlgStitching") <<
"Unable to flip Track 1.";
262 for (
const auto ts : newTracks) {
264 tracks.
tracks().emplace_back(ts, -1, tid2);
272 mf::LogInfo(
"pma::PMAlgStitching") <<
"Merging tracks...";
280 tracks.
merge((
size_t)idx2, (
size_t)idx1);
290 tracks.
merge((
size_t)idx1, (
size_t)idx2);
double GetTPCOffset(unsigned int tpc, unsigned int cryo, bool isCPA)
int getCandidateTreeId(pma::Track3D const *candidate) const
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
void ApplyDriftShiftInTree(const detinfo::DetectorClocksData &clockData, detinfo::DetectorPropertiesData const &detProp, double dx, bool skipFirst=false)
::fhicl::TupleAs< Point(::geo::Length_t,::geo::Length_t,::geo::Length_t)> Point3D
Atom object for reading a 3D point or vector (centimeters).
unsigned int BackTPC() const
unsigned int fNodesFromEnd
unsigned int BackCryo() const
double GetOptimalStitchShift(TVector3 &pos1, TVector3 &pos2, TVector3 &dir1, TVector3 &dir2, double &shift) const
bool setTreeOriginAtFront(detinfo::DetectorPropertiesData const &detProp, pma::Track3D *trk)
int getCandidateIndex(pma::Track3D const *candidate) const
unsigned int FrontTPC() const
unsigned int FrontCryo() const
The data type to uniquely identify a TPC.
void merge(size_t idx1, size_t idx2)
static unsigned int reverse(QString &chars, unsigned char *level, unsigned int a, unsigned int b)
double fStitchingThreshold
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
std::vector< pma::Node3D * > const & Nodes() const noexcept
IDparameter< geo::TPCID > TPCID
Member type of validated geo::TPCID parameter.
bool Flip(const detinfo::DetectorPropertiesData &detProp, std::vector< pma::Track3D * > &allTracks)
std::vector< TrkCandidate > const & tracks() const
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)