diff --git a/dq_install.sh b/dq_install.sh new file mode 100644 index 00000000..1eba6755 --- /dev/null +++ b/dq_install.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +#sudo mount -t cvmfs seaquest.opensciencegrid.org /cvmfs/seaquest.opensciencegrid.org +#sudo yum install sqlite-devel +#source /cvmfs/seaquest.opensciencegrid.org/seaquest/software/current/setup.sh + +#git clone https://github.com/cmantill/e1039-core.git +git clone https://github.com/wpmccormack/e1039-core.git +#git clone git@github.com:wpmccormack/e1039-core.git +cd e1039-core/ +git checkout patrick_new_tracking_withEmbedding +cd script/ + +cp /home/submit/pcharris/DQ/setup-install.sh +cd .. +./script/setup-install.sh auto +source ../core-inst/this-e1039.sh +./build.sh + +#git clone https://github.com/DarkQuest-FNAL/DarkQuest.git +git clone https://github.com/wpmccormack/DarkQuest.git +#git clone git@github.com:wpmccormack/DarkQuest.git +cd DarkQuest +#git checkout add_ana_flag_withEmbedding +cd e1039-analysis/SimHits/ +sed "s@XXX@$PWD@g" /home/submit/pcharris/DQ/setup_mye1039_tmp.sh > setup_mye1039.sh +#sed "s@XXX@$PWD@g" /data/t3home000/pharris/DQ/DarkQuest/e1039-analysis/SimHits/setup_mye1039_tmp.sh > setup_mye1039.sh + +source setup_mye1039.sh +mkdir work +mkdir install +cd work +cmake ../src/ -DCMAKE_INSTALL_PREFIX=../install +make clean +make +make install +cd ../../ +pwd + +cd HitEmbedding +sed "s@XXX@$PWD@g" /work/submit/wmccorma/DQ_Embed/setup_my1039_tmpHitEmbed.sh > setup_my1039.sh +source setup_my1039.sh +cmake-this +make-this +cd .. diff --git a/framework/phool/recoConsts.cc b/framework/phool/recoConsts.cc index 1d1752ef..b429111e 100644 --- a/framework/phool/recoConsts.cc +++ b/framework/phool/recoConsts.cc @@ -52,10 +52,13 @@ void recoConsts::set_defaults() set_BoolFlag("MC_MODE", false); set_BoolFlag("COSMIC_MODE", false); + set_BoolFlag("NOT_DISPLACED", true); set_BoolFlag("TARGETONLY", false); set_BoolFlag("DUMPONLY", false); set_BoolFlag("TRACK_ELECTRONS", false); /**This flag is used to turn off hit requirements in proportional tubes and tracking layers after the DarkQuest ECal*/ set_BoolFlag("TRACK_DISPLACED", false); /**When this flag is turned on, an expected-position window is not used when connecting station2+3 tracklets to station 1 tracklets, AND both charges are checked for every station1+2+3 tracklet. The charge that yields a lower chi2 in the tracklet fit is used. This is needed for displaced tracks, where the tracklet's charge cannot be determined from x0 position alone.*/ + set_BoolFlag("OLD_TRACKING", false); /**This flag can be used to turn on the old version of tracking, where tracklets in station 2 and 3 are matched based on the minimization of the sum of the DCA^2 <- that's distance of closest approach*/ + //Following values are fed to GeomSvc set_BoolFlag("OnlineAlignment", false); diff --git a/packages/calibrator/CalibDriftDist.cc b/packages/calibrator/CalibDriftDist.cc index 4d449442..d4f4b364 100644 --- a/packages/calibrator/CalibDriftDist.cc +++ b/packages/calibrator/CalibDriftDist.cc @@ -75,9 +75,14 @@ int CalibDriftDist::process_event(PHCompositeNode* topNode) int det = hit->get_detector_id(); if (!geom->isChamber(det) && !geom->isPropTube(det)) continue; - CalibParamXT::Set* xt = m_cal_xt->GetParam(det); - if (! det) { - cerr << " WARNING: Cannot find the in-time parameter for det=" << det << " in CalibDriftDist.\n"; + int ele = hit->get_element_id(); + TGraphErrors* gr_t2x; + TGraphErrors* gr_t2dx; + double center, width; + if (! m_cal_xt ->Find(det, gr_t2x, gr_t2dx) || + ! m_cal_int->Find(det, ele, center, width) ) { + cerr << " WARNING: Cannot find the in-time parameter for det=" << det << " ele=" << ele << " in CalibDriftDist.\n"; + continue; //return Fun4AllReturnCodes::ABORTEVENT; } @@ -90,6 +95,7 @@ int CalibDriftDist::process_event(PHCompositeNode* topNode) int ele = hit->get_element_id(); hit->set_pos(geom->getMeasurement(det, ele)); + std::cout<<"still still in CalibDriftDist process_event. index = "<get_hit_id()<<", detID = "<get_detector_id()<<", elementID = "<get_element_id()<<", tdcTime = "<get_tdc_time()<<", driftDistance = "<get_drift_distance())<<", pos = "<get_pos()<<", is_in_time = "<is_in_time()<<", get_tdc_time = "<get_tdc_time()<<", t1 = "<::const_iterator iter = hits.begin(); iter != hits.end(); ++iter) { if(iter->hit.index < 0) continue; @@ -961,23 +961,285 @@ double Tracklet::calcChisq() //double p = iter->hit.pos + iter->sign*fabs(iter->hit.driftDistance); if(KMAG_ON && stationID == nStations && detectorID <= 12) { - //residual[index] = p - p_geomSvc->getInterception(detectorID, tx_st1, ty, x0_st1, y0); - residual[index] = iter->sign*fabs(iter->hit.driftDistance) - p_geomSvc->getDCA(detectorID, iter->hit.elementID, tx_st1, ty, x0_st1, y0); + //residual[index] = p - p_geomSvc->getInterception(detectorID, tx_st1, ty, x0_st1, y0); + residual[index] = iter->sign*fabs(iter->hit.driftDistance) - p_geomSvc->getDCA(detectorID, iter->hit.elementID, tx_st1, ty, x0_st1, y0); + } + else + { + //residual[index] = p - p_geomSvc->getInterception(detectorID, tx, ty, x0, y0); + residual[index] = iter->sign*fabs(iter->hit.driftDistance) - p_geomSvc->getDCA(detectorID, iter->hit.elementID, tx, ty, x0, y0); + } + + chisq += (residual[index]*residual[index]/sigma/sigma); + } + + return chisq; +} + +double Tracklet::calcChisq_noDrift() +{ + chisq = 0.; + + double tx_st1, x0_st1; + if(stationID == nStations && KMAG_ON) + { + getXZInfoInSt1(tx_st1, x0_st1); + } + for(std::list::const_iterator iter = hits.begin(); iter != hits.end(); ++iter) + { + if(iter->hit.index < 0) continue; + + int detectorID = iter->hit.detectorID; + int index = detectorID - 1; + + double sigma; + //if(iter->sign == 0 || COARSE_MODE) + sigma = p_geomSvc->getPlaneSpacing(detectorID)/sqrt(12.); + //sigma = fabs(iter->hit.driftDistance)/sqrt(12.); + //else + // sigma = p_geomSvc->getPlaneResolution(detectorID); + + //double p = iter->hit.pos + iter->sign*fabs(iter->hit.driftDistance); + if(KMAG_ON && stationID == nStations && detectorID <= 12) + { + //residual[index] = p - p_geomSvc->getInterception(detectorID, tx_st1, ty, x0_st1, y0); + //residual[index] = iter->sign*fabs(iter->hit.driftDistance) - p_geomSvc->getDCA(detectorID, iter->hit.elementID, tx_st1, ty, x0_st1, y0); + residual[index] = p_geomSvc->getDCA(detectorID, iter->hit.elementID, tx_st1, ty, x0_st1, y0); } else { - //residual[index] = p - p_geomSvc->getInterception(detectorID, tx, ty, x0, y0); - residual[index] = iter->sign*fabs(iter->hit.driftDistance) - p_geomSvc->getDCA(detectorID, iter->hit.elementID, tx, ty, x0, y0); + //residual[index] = p - p_geomSvc->getInterception(detectorID, tx, ty, x0, y0); + //residual[index] = iter->sign*fabs(iter->hit.driftDistance) - p_geomSvc->getDCA(detectorID, iter->hit.elementID, tx, ty, x0, y0); + residual[index] = p_geomSvc->getDCA(detectorID, iter->hit.elementID, tx, ty, x0, y0); } chisq += (residual[index]*residual[index]/sigma/sigma); - //std::cout << iter->hit.detectorID << " " << iter->hit.elementID << " " << iter->sign << " " << iter->hit.pos << " " << iter->hit.driftDistance << " " << residual[index] << " " << sigma << " " << chisq << std::endl; } - //std::cout << chisq << std::endl; return chisq; } + + +//getSlopesX finds the possible X-Z lines for the single-station tracklet, based on the two input hits, which must be associated with the vertical wires in the station +void Tracklet::getSlopesX(Hit hit1, Hit hit2){ + //z difference between the two hits. An important component of X-Z slope + double zDist = std::abs(p_geomSvc->getPlanePosition(hit1.detectorID) - p_geomSvc->getPlanePosition(hit2.detectorID)); + std::vector twoHits; //sort the hits by z position + if(p_geomSvc->getPlanePosition(hit1.detectorID) <= p_geomSvc->getPlanePosition(hit2.detectorID)){ + twoHits.push_back(hit1); + twoHits.push_back(hit2); + } else{ + twoHits.push_back(hit2); + twoHits.push_back(hit1); + } + //Calculate the possible lines by brute force. No y-information is provided by the vertical wires + linedef testline1; + testline1.slopeX = ( (twoHits.at(1).pos + twoHits.at(1).driftDistance) - (twoHits.at(0).pos + twoHits.at(0).driftDistance) )/zDist; + testline1.initialX = twoHits.at(0).pos + twoHits.at(0).driftDistance; + testline1.initialZ = p_geomSvc->getPlanePosition(twoHits.at(0).detectorID); + linedef testline2; + testline2.slopeX = ( (twoHits.at(1).pos + twoHits.at(1).driftDistance) - (twoHits.at(0).pos - twoHits.at(0).driftDistance) )/zDist; + testline2.initialX = twoHits.at(0).pos - twoHits.at(0).driftDistance; + testline2.initialZ = p_geomSvc->getPlanePosition(twoHits.at(0).detectorID); + linedef testline3; + testline3.slopeX = ( (twoHits.at(1).pos - twoHits.at(1).driftDistance) - (twoHits.at(0).pos + twoHits.at(0).driftDistance) )/zDist; + testline3.initialX = twoHits.at(0).pos + twoHits.at(0).driftDistance; + testline3.initialZ = p_geomSvc->getPlanePosition(twoHits.at(0).detectorID); + linedef testline4; + testline4.slopeX = ( (twoHits.at(1).pos - twoHits.at(1).driftDistance) - (twoHits.at(0).pos - twoHits.at(0).driftDistance) )/zDist; + testline4.initialX = twoHits.at(0).pos - twoHits.at(0).driftDistance; + testline4.initialZ = p_geomSvc->getPlanePosition(twoHits.at(0).detectorID); + + //Keep track of the four possible X-Z lines for the station's tracklet + possibleXLines.push_back(testline1); + possibleXLines.push_back(testline2); + possibleXLines.push_back(testline3); + possibleXLines.push_back(testline4); +} + +//Find the possible U-Z lines for a single-station's tracklet. Here a little more information is needed than in the X-Z case, which will eventually be used to extract Y information +void Tracklet::getSlopesU(Hit hit1, Hit hit2){ + double zDist = std::abs(p_geomSvc->getPlanePosition(hit1.detectorID) - p_geomSvc->getPlanePosition(hit2.detectorID)); + std::vector twoHits; + if(p_geomSvc->getPlanePosition(hit1.detectorID) <= p_geomSvc->getPlanePosition(hit2.detectorID)){ + twoHits.push_back(hit1); + twoHits.push_back(hit2); + } else{ + twoHits.push_back(hit2); + twoHits.push_back(hit1); + } + + //We need to know the slopes of the two wires in X-Y space + double w1Slope = -p_geomSvc->getCostheta(twoHits.at(0).detectorID)/p_geomSvc->getSintheta(twoHits.at(0).detectorID); + double w2Slope = -p_geomSvc->getCostheta(twoHits.at(1).detectorID)/p_geomSvc->getSintheta(twoHits.at(1).detectorID); + + //std::cout<<"in GETSLOPESU. w1 ID is: "<getPlanePosition(twoHits.at(0).detectorID); + //std::cout<<"quick check here. detID is "<getPlanePosition(twoHits.at(0).detectorID) = "<getPlanePosition(twoHits.at(0).detectorID)<getCostheta(twoHits.at(0).detectorID)*testline1.wireHit1Pos; //This is the X-value of the hit in the first wire layer + testline1.wireHit2PosX = p_geomSvc->getCostheta(twoHits.at(1).detectorID)*testline1.wireHit2Pos; //X-value of hit in second layer + testline1.wireHit1PosY = p_geomSvc->getSintheta(twoHits.at(0).detectorID)*testline1.wireHit1Pos; //This is the Y-value of (U1, 0) = (wireHit1Pos, 0) point + testline1.wireHit2PosY = p_geomSvc->getSintheta(twoHits.at(1).detectorID)*testline1.wireHit2Pos; //This is the Y-value of (U1, 0) = (wireHit2Pos, 0) point + testline1.wireHit1PosZ = p_geomSvc->getPlanePosition(twoHits.at(0).detectorID); //Z position of wire (no rotation needed) + testline1.wireHit2PosZ = p_geomSvc->getPlanePosition(twoHits.at(1).detectorID); //Z position + testline1.wireIntercept1 = testline1.wireHit1PosY - testline1.wire1Slope * testline1.wireHit1PosX; //Extract the Y-intercept of the line that defines where the first U-plane hit occured + testline1.wireIntercept2 = testline1.wireHit2PosY - testline1.wire2Slope * testline1.wireHit2PosX; //Extract the Y-intercept of the line that defines where the second U-plane hit occured + linedef testline2; + testline2.slopeU = ( (twoHits.at(1).pos + twoHits.at(1).driftDistance) - (twoHits.at(0).pos - twoHits.at(0).driftDistance) )/zDist; + testline2.initialU = twoHits.at(0).pos - twoHits.at(0).driftDistance; + testline2.initialZ = p_geomSvc->getPlanePosition(twoHits.at(0).detectorID); + testline2.wire1Slope = w1Slope; + testline2.wire2Slope = w2Slope; + testline2.wireHit1Pos = (twoHits.at(0).pos - twoHits.at(0).driftDistance); + testline2.wireHit2Pos = (twoHits.at(1).pos + twoHits.at(1).driftDistance); + testline2.wireHit1PosX = p_geomSvc->getCostheta(twoHits.at(0).detectorID)*testline2.wireHit1Pos; + testline2.wireHit2PosX = p_geomSvc->getCostheta(twoHits.at(1).detectorID)*testline2.wireHit2Pos; + testline2.wireHit1PosY = p_geomSvc->getSintheta(twoHits.at(0).detectorID)*testline2.wireHit1Pos; + testline2.wireHit2PosY = p_geomSvc->getSintheta(twoHits.at(1).detectorID)*testline2.wireHit2Pos; + testline2.wireHit1PosZ = p_geomSvc->getPlanePosition(twoHits.at(0).detectorID); + testline2.wireHit2PosZ = p_geomSvc->getPlanePosition(twoHits.at(1).detectorID); + testline2.wireIntercept1 = testline2.wireHit1PosY - testline2.wire1Slope * testline2.wireHit1PosX; + testline2.wireIntercept2 = testline2.wireHit2PosY - testline2.wire2Slope * testline2.wireHit2PosX; + linedef testline3; + testline3.slopeU = ( (twoHits.at(1).pos - twoHits.at(1).driftDistance) - (twoHits.at(0).pos + twoHits.at(0).driftDistance) )/zDist; + testline3.initialU = twoHits.at(0).pos + twoHits.at(0).driftDistance; + testline3.initialZ = p_geomSvc->getPlanePosition(twoHits.at(0).detectorID); + testline3.wire1Slope = w1Slope; + testline3.wire2Slope = w2Slope; + testline3.wireHit1Pos = (twoHits.at(0).pos + twoHits.at(0).driftDistance); + testline3.wireHit2Pos = (twoHits.at(1).pos - twoHits.at(1).driftDistance); + testline3.wireHit1PosX = p_geomSvc->getCostheta(twoHits.at(0).detectorID)*testline3.wireHit1Pos; + testline3.wireHit2PosX = p_geomSvc->getCostheta(twoHits.at(1).detectorID)*testline3.wireHit2Pos; + testline3.wireHit1PosY = p_geomSvc->getSintheta(twoHits.at(0).detectorID)*testline3.wireHit1Pos; + testline3.wireHit2PosY = p_geomSvc->getSintheta(twoHits.at(1).detectorID)*testline3.wireHit2Pos; + testline3.wireHit1PosZ = p_geomSvc->getPlanePosition(twoHits.at(0).detectorID); + testline3.wireHit2PosZ = p_geomSvc->getPlanePosition(twoHits.at(1).detectorID); + testline3.wireIntercept1 = testline3.wireHit1PosY - testline3.wire1Slope * testline3.wireHit1PosX; + testline3.wireIntercept2 = testline3.wireHit2PosY - testline3.wire2Slope * testline3.wireHit2PosX; + linedef testline4; + testline4.slopeU = ( (twoHits.at(1).pos - twoHits.at(1).driftDistance) - (twoHits.at(0).pos - twoHits.at(0).driftDistance) )/zDist; + testline4.initialU = twoHits.at(0).pos - twoHits.at(0).driftDistance; + testline4.initialZ = p_geomSvc->getPlanePosition(twoHits.at(0).detectorID); + testline4.wire1Slope = w1Slope; + testline4.wire2Slope = w2Slope; + testline4.wireHit1Pos = (twoHits.at(0).pos - twoHits.at(0).driftDistance); + testline4.wireHit2Pos = (twoHits.at(1).pos - twoHits.at(1).driftDistance); + testline4.wireHit1PosX = p_geomSvc->getCostheta(twoHits.at(0).detectorID)*testline4.wireHit1Pos; + testline4.wireHit2PosX = p_geomSvc->getCostheta(twoHits.at(1).detectorID)*testline4.wireHit2Pos; + testline4.wireHit1PosY = p_geomSvc->getSintheta(twoHits.at(0).detectorID)*testline4.wireHit1Pos; + testline4.wireHit2PosY = p_geomSvc->getSintheta(twoHits.at(1).detectorID)*testline4.wireHit2Pos; + testline4.wireHit1PosZ = p_geomSvc->getPlanePosition(twoHits.at(0).detectorID); + testline4.wireHit2PosZ = p_geomSvc->getPlanePosition(twoHits.at(1).detectorID); + testline4.wireIntercept1 = testline4.wireHit1PosY - testline4.wire1Slope * testline4.wireHit1PosX; + testline4.wireIntercept2 = testline4.wireHit2PosY - testline4.wire2Slope * testline4.wireHit2PosX; + + //Keep track of the four possible U-Z lines and the corresponding possible lines for the hit in the X-Y plane + possibleULines.push_back(testline1); + possibleULines.push_back(testline2); + possibleULines.push_back(testline3); + possibleULines.push_back(testline4); +} + +//getSlopesV is essentially a copy of getSlopesU, but it assigns the possible V lines +void Tracklet::getSlopesV(Hit hit1, Hit hit2){ + double zDist = std::abs(p_geomSvc->getPlanePosition(hit1.detectorID) - p_geomSvc->getPlanePosition(hit2.detectorID)); + std::vector twoHits; + if(p_geomSvc->getPlanePosition(hit1.detectorID) <= p_geomSvc->getPlanePosition(hit2.detectorID)){ + twoHits.push_back(hit1); + twoHits.push_back(hit2); + } else{ + twoHits.push_back(hit2); + twoHits.push_back(hit1); + } + + double w1Slope = -p_geomSvc->getCostheta(twoHits.at(0).detectorID)/p_geomSvc->getSintheta(twoHits.at(0).detectorID); + double w2Slope = -p_geomSvc->getCostheta(twoHits.at(1).detectorID)/p_geomSvc->getSintheta(twoHits.at(1).detectorID); + + //std::cout<<"in GETSLOPESV. w1 ID is: "<getPlanePosition(twoHits.at(0).detectorID); + testline1.wire1Slope = w1Slope; + testline1.wire2Slope = w2Slope; + testline1.wireHit1Pos = (twoHits.at(0).pos + twoHits.at(0).driftDistance); + testline1.wireHit2Pos = (twoHits.at(1).pos + twoHits.at(1).driftDistance); + testline1.wireHit1PosX = p_geomSvc->getCostheta(twoHits.at(0).detectorID)*testline1.wireHit1Pos; + testline1.wireHit2PosX = p_geomSvc->getCostheta(twoHits.at(1).detectorID)*testline1.wireHit2Pos; + testline1.wireHit1PosY = p_geomSvc->getSintheta(twoHits.at(0).detectorID)*testline1.wireHit1Pos; + testline1.wireHit2PosY = p_geomSvc->getSintheta(twoHits.at(1).detectorID)*testline1.wireHit2Pos; + testline1.wireHit1PosZ = p_geomSvc->getPlanePosition(twoHits.at(0).detectorID); + testline1.wireHit2PosZ = p_geomSvc->getPlanePosition(twoHits.at(1).detectorID); + testline1.wireIntercept1 = testline1.wireHit1PosY - testline1.wire1Slope * testline1.wireHit1PosX; + testline1.wireIntercept2 = testline1.wireHit2PosY - testline1.wire2Slope * testline1.wireHit2PosX; + linedef testline2; + testline2.slopeV = ( (twoHits.at(1).pos + twoHits.at(1).driftDistance) - (twoHits.at(0).pos - twoHits.at(0).driftDistance) )/zDist; + testline2.initialV = twoHits.at(0).pos - twoHits.at(0).driftDistance; + testline2.initialZ = p_geomSvc->getPlanePosition(twoHits.at(0).detectorID); + testline2.wire1Slope = w1Slope; + testline2.wire2Slope = w2Slope; + testline2.wireHit1Pos = (twoHits.at(0).pos - twoHits.at(0).driftDistance); + testline2.wireHit2Pos = (twoHits.at(1).pos + twoHits.at(1).driftDistance); + testline2.wireHit1PosX = p_geomSvc->getCostheta(twoHits.at(0).detectorID)*testline2.wireHit1Pos; + testline2.wireHit2PosX = p_geomSvc->getCostheta(twoHits.at(1).detectorID)*testline2.wireHit2Pos; + testline2.wireHit1PosY = p_geomSvc->getSintheta(twoHits.at(0).detectorID)*testline2.wireHit1Pos; + testline2.wireHit2PosY = p_geomSvc->getSintheta(twoHits.at(1).detectorID)*testline2.wireHit2Pos; + testline2.wireHit1PosZ = p_geomSvc->getPlanePosition(twoHits.at(0).detectorID); + testline2.wireHit2PosZ = p_geomSvc->getPlanePosition(twoHits.at(1).detectorID); + testline2.wireIntercept1 = testline2.wireHit1PosY - testline2.wire1Slope * testline2.wireHit1PosX; + testline2.wireIntercept2 = testline2.wireHit2PosY - testline2.wire2Slope * testline2.wireHit2PosX; + linedef testline3; + testline3.slopeV = ( (twoHits.at(1).pos - twoHits.at(1).driftDistance) - (twoHits.at(0).pos + twoHits.at(0).driftDistance) )/zDist; + testline3.initialV = twoHits.at(0).pos + twoHits.at(0).driftDistance; + testline3.initialZ = p_geomSvc->getPlanePosition(twoHits.at(0).detectorID); + testline3.wire1Slope = w1Slope; + testline3.wire2Slope = w2Slope; + testline3.wireHit1Pos = (twoHits.at(0).pos + twoHits.at(0).driftDistance); + testline3.wireHit2Pos = (twoHits.at(1).pos - twoHits.at(1).driftDistance); + testline3.wireHit1PosX = p_geomSvc->getCostheta(twoHits.at(0).detectorID)*testline3.wireHit1Pos; + testline3.wireHit2PosX = p_geomSvc->getCostheta(twoHits.at(1).detectorID)*testline3.wireHit2Pos; + testline3.wireHit1PosY = p_geomSvc->getSintheta(twoHits.at(0).detectorID)*testline3.wireHit1Pos; + testline3.wireHit2PosY = p_geomSvc->getSintheta(twoHits.at(1).detectorID)*testline3.wireHit2Pos; + testline3.wireHit1PosZ = p_geomSvc->getPlanePosition(twoHits.at(0).detectorID); + testline3.wireHit2PosZ = p_geomSvc->getPlanePosition(twoHits.at(1).detectorID); + testline3.wireIntercept1 = testline3.wireHit1PosY - testline3.wire1Slope * testline3.wireHit1PosX; + testline3.wireIntercept2 = testline3.wireHit2PosY - testline3.wire2Slope * testline3.wireHit2PosX; + linedef testline4; + testline4.slopeV = ( (twoHits.at(1).pos - twoHits.at(1).driftDistance) - (twoHits.at(0).pos - twoHits.at(0).driftDistance) )/zDist; + testline4.initialV = twoHits.at(0).pos - twoHits.at(0).driftDistance; + testline4.initialZ = p_geomSvc->getPlanePosition(twoHits.at(0).detectorID); + testline4.wire1Slope = w1Slope; + testline4.wire2Slope = w2Slope; + testline4.wireHit1Pos = (twoHits.at(0).pos - twoHits.at(0).driftDistance); + testline4.wireHit2Pos = (twoHits.at(1).pos - twoHits.at(1).driftDistance); + testline4.wireHit1PosX = p_geomSvc->getCostheta(twoHits.at(0).detectorID)*testline4.wireHit1Pos; + testline4.wireHit2PosX = p_geomSvc->getCostheta(twoHits.at(1).detectorID)*testline4.wireHit2Pos; + testline4.wireHit1PosY = p_geomSvc->getSintheta(twoHits.at(0).detectorID)*testline4.wireHit1Pos; + testline4.wireHit2PosY = p_geomSvc->getSintheta(twoHits.at(1).detectorID)*testline4.wireHit2Pos; + testline4.wireHit1PosZ = p_geomSvc->getPlanePosition(twoHits.at(0).detectorID); + testline4.wireHit2PosZ = p_geomSvc->getPlanePosition(twoHits.at(1).detectorID); + testline4.wireIntercept1 = testline4.wireHit1PosY - testline4.wire1Slope * testline4.wireHit1PosX; + testline4.wireIntercept2 = testline4.wireHit2PosY - testline4.wire2Slope * testline4.wireHit2PosX; + + possibleVLines.push_back(testline1); + possibleVLines.push_back(testline2); + possibleVLines.push_back(testline3); + possibleVLines.push_back(testline4); +} +//Eventually, getSlopesU and getSlopesV should probably be combined into one function, and the extraction of the possible line information can probably be simplified into single loop + SignedHit Tracklet::getSignedHit(int index) { int id = 0; @@ -1115,6 +1377,19 @@ void Tracklet::print(std::ostream& os) os << "KMAG projection: X = " << getExpPositionX(Z_KMAG_BEND) << " +/- " << getExpPosErrorX(Z_KMAG_BEND) << endl; os << "KMAG projection: Y = " << getExpPositionY(Z_KMAG_BEND) << " +/- " << getExpPosErrorY(Z_KMAG_BEND) << endl; os << "KMAGSTR = " << KMAGSTR << endl; + os << "and for good measure, let's print out the possible slope info" << endl; + os << "possible X lines" << endl; + for(unsigned int sl = 0; sl hits; - + SignedHit getHit(int _i){ + std::list::iterator it = hits.begin(); + for(int i=0; i<_i; i++){ + ++it; + } + return *it; + } + //Corresponding prop. tube segments PropSegment seg_x; PropSegment seg_y; @@ -238,6 +246,71 @@ class Tracklet : public PHObject double y0; double invP; + //This is an admittedly messy way of keeping track of various bits of needed information to describe the possible particle trajectories in a single-station tracklet + struct linedef { + double slopeX; + double slopeY; + double initialX; + double initialY; + double initialZ; + double slopeU; + double initialU; + double slopeV; + double initialV; + + double wireHit1Pos; + double wireHit2Pos; + double wireHit1PosX; + double wireHit2PosX; + double wireHit1PosY; + double wireHit2PosY; + double wireHit1PosZ; + double wireHit2PosZ; + double wire1Slope; + double wire2Slope; + double wireIntercept1; + double wireIntercept2; + + void print(){ + std::cout<<"slopeX: "< possibleXLines; + std::vector possibleULines; + std::vector possibleVLines; + + void getSlopesX(Hit hit1, Hit hit2); + void getSlopesU(Hit hit1, Hit hit2); + void getSlopesV(Hit hit1, Hit hit2); + double err_tx; double err_ty; double err_x0; diff --git a/packages/reco/interface/SRawEvent.cxx b/packages/reco/interface/SRawEvent.cxx index bc85eda2..09081502 100644 --- a/packages/reco/interface/SRawEvent.cxx +++ b/packages/reco/interface/SRawEvent.cxx @@ -206,7 +206,8 @@ std::list SRawEvent::getHitsIndexInDetector(Short_t detectorID, Double_t for(Int_t i = 0; i < fNHits[0]; i++) { - if(fAllHits[i].detectorID != detectorID) continue; + if(fAllHits[i].detectorID != detectorID) continue; + //std::cout<<"in getHitsIndexInDetector: index is "< win) continue; hit_list.push_back(i); @@ -275,6 +276,8 @@ std::list SRawEvent::getPartialHitPairsInSuperDetector(Shor for(std::list::iterator jter = _hitlist2.begin(); jter != _hitlist2.end(); ++jter) { index2++; + //std::cout<<"in getPartialHitPairsInSuperDetector: index 1 is "< spacing[detectorID]) continue; _hitpairs.push_back(std::make_pair(*iter, *jter)); @@ -324,6 +327,8 @@ std::list SRawEvent::getPartialHitPairsInSuperDetector(Shor for(std::list::iterator jter = _hitlist2.begin(); jter != _hitlist2.end(); ++jter) { index2++; + //std::cout<<"in getPartialHitPairsInSuperDetector: index 1 is "< spacing[detectorID]) continue; _hitpairs.push_back(std::make_pair(*iter, *jter)); diff --git a/packages/reco/ktracker/KalmanFastTracking.cxx b/packages/reco/ktracker/KalmanFastTracking.cxx index 1a8923e7..42a31c70 100644 --- a/packages/reco/ktracker/KalmanFastTracking.cxx +++ b/packages/reco/ktracker/KalmanFastTracking.cxx @@ -25,6 +25,7 @@ Created: 05-28-2013 #include "TriggerRoad.h" //#define _DEBUG_ON +#define _DEBUG_PATRICK namespace { @@ -77,8 +78,13 @@ namespace static bool COARSE_MODE; //if displaced, skip fit to the target/vertex + static bool NOT_DISPLACED; static bool TRACK_ELECTRONS; //please see comment in framework/phool/recoConsts.cc static bool TRACK_DISPLACED; //please see comment in framework/phool/recoConsts.cc + static bool OLD_TRACKING; //please see comment in framework/phool/recoConsts.cc + + static double KMAGSTR; + static double PT_KICK_KMAG; //initialize global variables void initGlobalVariables() @@ -93,8 +99,10 @@ namespace COSMIC_MODE = rc->get_BoolFlag("COSMIC_MODE"); COARSE_MODE = rc->get_BoolFlag("COARSE_MODE"); + NOT_DISPLACED = rc->get_BoolFlag("NOT_DISPLACED"); TRACK_ELECTRONS = rc->get_BoolFlag("TRACK_ELECTRONS"); TRACK_DISPLACED = rc->get_BoolFlag("TRACK_DISPLACED"); + OLD_TRACKING = rc->get_BoolFlag("OLD_TRACKING"); MaxHitsDC0 = rc->get_IntFlag("MaxHitsDC0"); MaxHitsDC1 = rc->get_IntFlag("MaxHitsDC1"); @@ -125,6 +133,9 @@ namespace MUID_EMP_P1 = rc->get_DoubleFlag("MUID_EMP_P1"); MUID_EMP_P2 = rc->get_DoubleFlag("MUID_EMP_P2"); MUID_MINHITS = rc->get_IntFlag("MUID_MINHITS"); + + KMAGSTR = rc->get_DoubleFlag("KMAGSTR"); + PT_KICK_KMAG = rc->get_DoubleFlag("PT_KICK_KMAG")*KMAGSTR; } } } @@ -159,7 +170,6 @@ KalmanFastTracking::KalmanFastTracking(const PHField* field, const TGeoManager* minimizer[0] = ROOT::Math::Factory::CreateMinimizer("Minuit2", "Simplex"); minimizer[1] = ROOT::Math::Factory::CreateMinimizer("Minuit2", "Combined"); fcn = ROOT::Math::Functor(&tracklet_curr, &Tracklet::Eval, KMAG_ON ? 5 : 4); - for(int i = 0; i < 2; ++i) { minimizer[i]->SetMaxFunctionCalls(1000000); @@ -441,7 +451,12 @@ int KalmanFastTracking::setRawEvent(SRawEvent* event_input) } //Initialize tracklet lists - for(int i = 0; i < 5; i++) trackletsInSt[i].clear(); + for(int i = 0; i < 5; i++){ + trackletsInSt[i].clear(); + trackletsInStSlimX[i].clear(); + trackletsInStSlimU[i].clear(); + trackletsInStSlimV[i].clear(); + } stracks.clear(); //pre-tracking cuts @@ -496,7 +511,28 @@ int KalmanFastTracking::setRawEvent(SRawEvent* event_input) //Build tracklets in station 2, 3+, 3- _timers["st2"]->restart(); - buildTrackletsInStation(3, 1); //3 for station-2, 1 for list position 1 + //buildTrackletsInStation(3, 1); //3 for station-2, 1 for list position 1 + buildTrackletsInStationSlim(3, 1); //3 for station-2, 1 for list position 1 + std::cout<<"Station 2 x combos = "<getCostheta(1) * pos_exp[0] + p_geomSvc->getSintheta(1) * 0<<", "<getCostheta(5) * pos_exp[0] + p_geomSvc->getSintheta(5) * 0<stop(); if(verbosity >= 2) LogInfo("NTracklets in St2: " << trackletsInSt[1].size()); @@ -505,12 +541,21 @@ int KalmanFastTracking::setRawEvent(SRawEvent* event_input) #ifdef _DEBUG_ON LogInfo("Failed in tracklet build at station 2"); #endif - return TFEXIT_FAIL_ST2_TRACKLET; + //return TFEXIT_FAIL_ST2_TRACKLET; } _timers["st3"]->restart(); - buildTrackletsInStation(4, 2); //4 for station-3+ - buildTrackletsInStation(5, 2); //5 for station-3- + //buildTrackletsInStation(4, 2); //4 for station-3+ + //buildTrackletsInStation(5, 2); //5 for station-3- + buildTrackletsInStationSlim(4, 2); //4 for station-3+ + buildTrackletsInStationSlim(5, 2); //5 for station-3- + std::cout<<"Station 3 x combos = "<stop(); if(verbosity >= 2) LogInfo("NTracklets in St3: " << trackletsInSt[2].size()); @@ -519,12 +564,47 @@ int KalmanFastTracking::setRawEvent(SRawEvent* event_input) #ifdef _DEBUG_ON LogInfo("Failed in tracklet build at station 3"); #endif - return TFEXIT_FAIL_ST3_TRACKLET; + //return TFEXIT_FAIL_ST3_TRACKLET; } //Build back partial tracks in station 2, 3+ and 3- _timers["st23"]->restart(); - buildBackPartialTracks(); + //buildBackPartialTracks(); + buildBackPartialTracksSlimX(1); + std::cout<<"Station 2+3 x combos = "< 500){ + trackletsInStSlimX[3].clear(); + buildBackPartialTracksSlimX(2); + std::cout<<"Station 2+3 x combos = "< 100){ + return TFEXIT_FAIL_BACKPARTIAL; + } + } + buildBackPartialTracksSlimU(1); + std::cout<<"Station 2+3 u combos = "< 500){ + trackletsInStSlimU[3].clear(); + buildBackPartialTracksSlimU(2); + std::cout<<"Station 2+3 u combos = "< 100){ + return TFEXIT_FAIL_BACKPARTIAL; + } + } + buildBackPartialTracksSlimV(1); + std::cout<<"Station 2+3 v combos = "< 500){ + trackletsInStSlimV[3].clear(); + buildBackPartialTracksSlimV(2); + std::cout<<"Station 2+3 v combos = "< 100){ + return TFEXIT_FAIL_BACKPARTIAL; + } + } + buildBackPartialTracksSlim_v2(); + std::cout<<"Station 2+3 all combos = "<::iterator tracklet23 = trackletsInStSlimX[3].begin(); tracklet23 != trackletsInStSlimX[3].end(); ++tracklet23){ + // buildTrackletsInStationWithUV(6, 3, *tracklet23); + //} _timers["st23"]->stop(); if(verbosity >= 2) LogInfo("NTracklets St2+St3: " << trackletsInSt[3].size()); @@ -539,7 +619,11 @@ int KalmanFastTracking::setRawEvent(SRawEvent* event_input) //Connect tracklets in station 2/3 and station 1 to form global tracks _timers["global"]->restart(); - buildGlobalTracks(); + if(!TRACK_DISPLACED){ + buildGlobalTracks(); + } else{ + buildGlobalTracksDisplaced(); + } _timers["global"]->stop(); if(verbosity >= 2) LogInfo("NTracklets Global: " << trackletsInSt[4].size()); @@ -592,8 +676,8 @@ int KalmanFastTracking::setRawEvent(SRawEvent* event_input) bool KalmanFastTracking::acceptEvent(SRawEvent* rawEvent) { - if(Verbosity() >= Fun4AllBase::VERBOSITY_A_LOT) - { + //if(Verbosity() >= Fun4AllBase::VERBOSITY_A_LOT) //WPM + //{ //WPM LogInfo("D0: " << rawEvent->getNHitsInD0()); LogInfo("D1: " << rawEvent->getNHitsInD1()); LogInfo("D2: " << rawEvent->getNHitsInD2()); @@ -606,10 +690,10 @@ bool KalmanFastTracking::acceptEvent(SRawEvent* rawEvent) LogInfo("Prop:" << rawEvent->getNPropHitsAll()); LogInfo("NRoadsPos: " << rawEvent->getNRoadsPos()); LogInfo("NRoadsNeg: " << rawEvent->getNRoadsNeg()); - } + //} //WPM if(rawEvent->getNHitsInD0() > MaxHitsDC0) return false; - if(rawEvent->getNHitsInD1() > MaxHitsDC1) return false; + //if(rawEvent->getNHitsInD1() > MaxHitsDC1) return false; if(rawEvent->getNHitsInD2() > MaxHitsDC2) return false; if(rawEvent->getNHitsInD3p() > MaxHitsDC3p) return false; if(rawEvent->getNHitsInD3m() > MaxHitsDC3m) return false; @@ -637,29 +721,32 @@ void KalmanFastTracking::buildBackPartialTracks() for(std::list::iterator tracklet3 = trackletsInSt[2].begin(); tracklet3 != trackletsInSt[2].end(); ++tracklet3) { + //tracklet3->print(); if(!COARSE_MODE) { //Extract the X hits only from station-3 tracks nHitsX3 = 0; for(std::list::iterator ptr_hit = tracklet3->hits.begin(); ptr_hit != tracklet3->hits.end(); ++ptr_hit) { - if(ptr_hit->hit.index < 0) continue; - if(p_geomSvc->getPlaneType(ptr_hit->hit.detectorID) == 1) + if(ptr_hit->hit.index < 0) continue; + if(p_geomSvc->getPlaneType(ptr_hit->hit.detectorID) == 1) { - z_fit[nHitsX3] = z_plane[ptr_hit->hit.detectorID]; - x_fit[nHitsX3] = ptr_hit->hit.pos; - ++nHitsX3; + z_fit[nHitsX3] = z_plane[ptr_hit->hit.detectorID]; + x_fit[nHitsX3] = ptr_hit->hit.pos; + ++nHitsX3; } - } + } } Tracklet tracklet_best; for(std::list::iterator tracklet2 = trackletsInSt[1].begin(); tracklet2 != trackletsInSt[1].end(); ++tracklet2) { + //tracklet2->print(); if(!COARSE_MODE) { - if(fabs(tracklet2->tx - tracklet3->tx) > 0.15 || fabs(tracklet2->ty - tracklet3->ty) > 0.1) continue; - + if(OLD_TRACKING){ + if(fabs(tracklet2->tx - tracklet3->tx) > 0.15 || fabs(tracklet2->ty - tracklet3->ty) > 0.1) continue; + } //Extract the X hits from station-2 tracke nHitsX2 = nHitsX3; for(std::list::iterator ptr_hit = tracklet2->hits.begin(); ptr_hit != tracklet2->hits.end(); ++ptr_hit) @@ -695,7 +782,29 @@ void KalmanFastTracking::buildBackPartialTracks() if(!TRACK_ELECTRONS && nPropHits == 0) continue; //Turned off by Patrick for electron tracks } - Tracklet tracklet_23 = (*tracklet2) + (*tracklet3); + Tracklet tracklet_23; + if(OLD_TRACKING){ + tracklet_23 = (*tracklet2) + (*tracklet3); + } + else{ + if(compareTracklets(*tracklet2, *tracklet3)){ + tracklet_23 = (*tracklet2) + (*tracklet3); + tracklet_23.tx = tracklet2->tx; //This is needed to "seed" the tracklet fit that happens below. This tx and ty information is assigned in compareTracklets below + tracklet_23.ty = tracklet2->ty; + + tracklet_23.st2Z = tracklet2->st2Z; + tracklet_23.st2X = tracklet2->st2X; + tracklet_23.st2Y = tracklet2->st2Y; + tracklet_23.st3Y = tracklet2->st3Y; + tracklet_23.st2U = tracklet2->st2U; + tracklet_23.st2V = tracklet2->st2V; + tracklet_23.st2Usl = tracklet2->st2Usl; + tracklet_23.st2Vsl = tracklet2->st2Vsl; + } + else{ + continue; + } + } #ifdef _DEBUG_ON LogInfo("Using following two tracklets:"); tracklet2->print(); @@ -703,7 +812,7 @@ void KalmanFastTracking::buildBackPartialTracks() LogInfo("Yield this combination:"); tracklet_23.print(); #endif - fitTracklet(tracklet_23); + fitTracklet(tracklet_23); //This is the fit that needs the seeded tx and ty information. Without the seed information, the fit occasionally finds bad slope and X0 or Y0 values, much in the same way that it does for single-station tracklets. Note from Patrick: this fit could probably be throw out, as we already know the tx and ty information from compareTracklets. I would just need to extrapolate back to z = 0 and calculate the chisq by hand if(tracklet_23.chisq > 9000.) { #ifdef _DEBUG_ON @@ -726,7 +835,7 @@ void KalmanFastTracking::buildBackPartialTracks() if(!COARSE_MODE) { - resolveLeftRight(tracklet_23, 40.); + resolveLeftRight(tracklet_23, 40.); //resolveLeftRight at this stage is, in truth, not needed. We already know which side of the wire the particle passed by from compareTracklet. However, getting rid of this would take a bit of work resolveLeftRight(tracklet_23, 150.); } @@ -764,476 +873,2673 @@ void KalmanFastTracking::buildBackPartialTracks() trackletsInSt[3].sort(); } -void KalmanFastTracking::buildGlobalTracks() + +void KalmanFastTracking::buildBackPartialTracksSlim() { - double pos_exp[3], window[3]; - for(std::list::iterator tracklet23 = trackletsInSt[3].begin(); tracklet23 != trackletsInSt[3].end(); ++tracklet23) - { - Tracklet tracklet_best[2]; - for(int i = 0; i < 2; ++i) //for two station-1 chambers - { - trackletsInSt[0].clear(); - if(!TRACK_DISPLACED){ - //Calculate the window in station 1 - if(KMAG_ON) - { - getSagittaWindowsInSt1(*tracklet23, pos_exp, window, i+1); - } - else - { - getExtrapoWindowsInSt1(*tracklet23, pos_exp, window, i+1); - } +#ifdef _DEBUG_ON + LogInfo("HELLO I'm in buildBackPartialTracksSlim"); +#endif + //std::cout<<"trackletsInStSlimV[3].size() = "<::iterator trackletV = trackletsInStSlimV[3].begin(); trackletV != trackletsInStSlimV[3].end(); ++trackletV){ + //std::cout<<"FIFTH TEST trackletV->acceptedVLine2.wireHit1PosZ = "<<(*trackletV).acceptedVLine2.wireHit1PosZ< acceptedStation2Tracklets; + std::vector acceptedStation3Tracklets; + + for(std::list::iterator trackletX = trackletsInStSlimX[3].begin(); trackletX != trackletsInStSlimX[3].end(); ++trackletX){ + Tracklet tracklet_best; + for(std::list::iterator trackletU = trackletsInStSlimU[3].begin(); trackletU != trackletsInStSlimU[3].end(); ++trackletU){ + Tracklet tracklet_best_UX; + for(std::list::iterator trackletV = trackletsInStSlimV[3].begin(); trackletV != trackletsInStSlimV[3].end(); ++trackletV){ + + double posy2U = ((*trackletU).st2U - p_geomSvc->getCostheta((*trackletX).getHit(0).hit.detectorID+2)*((*trackletX).st2X + (*trackletX).st2Xsl * ((*trackletU).st2Z - (*trackletX).st2Z) ))/p_geomSvc->getSintheta((*trackletX).getHit(0).hit.detectorID+2); + double posy2V = ((*trackletV).st2V - p_geomSvc->getCostheta((*trackletX).getHit(0).hit.detectorID-2)*((*trackletX).st2X + (*trackletX).st2Xsl * ((*trackletV).st2Z - (*trackletX).st2Z) ))/p_geomSvc->getSintheta((*trackletX).getHit(0).hit.detectorID-2); + double posy3U = ((*trackletU).st3U - p_geomSvc->getCostheta((*trackletX).getHit(2).hit.detectorID+2)*((*trackletX).st3X + (*trackletX).st3Xsl * ((*trackletU).st3Z - (*trackletX).st3Z) ))/p_geomSvc->getSintheta((*trackletX).getHit(2).hit.detectorID+2); + double posy3V = ((*trackletV).st3V - p_geomSvc->getCostheta((*trackletX).getHit(2).hit.detectorID-2)*((*trackletX).st3X + (*trackletX).st3Xsl * ((*trackletV).st3Z - (*trackletX).st3Z) ))/p_geomSvc->getSintheta((*trackletX).getHit(2).hit.detectorID-2); + +#ifdef _DEBUG_PATRICK + LogInfo("HELLO I'm in buildBackPartialTracksSlim"); +#endif + + double st2UWireSin = TMath::Sin(TMath::ATan(1./trackletU->acceptedULine2.wire1Slope)); + double st2VWireSin = TMath::Sin(TMath::ATan(1./trackletV->acceptedVLine2.wire1Slope)); + double st3UWireSin = TMath::Sin(TMath::ATan(1./trackletU->acceptedULine3.wire1Slope)); + double st3VWireSin = TMath::Sin(TMath::ATan(1./trackletV->acceptedVLine3.wire1Slope)); + + double st2UWireCos = TMath::Cos(TMath::ATan(1./trackletU->acceptedULine2.wire1Slope)); + double st2VWireCos = TMath::Cos(TMath::ATan(1./trackletV->acceptedVLine2.wire1Slope)); + double st3UWireCos = TMath::Cos(TMath::ATan(1./trackletU->acceptedULine3.wire1Slope)); + double st3VWireCos = TMath::Cos(TMath::ATan(1./trackletV->acceptedVLine3.wire1Slope)); + + double testTY2 = ( trackletV->st2Vsl - (st2VWireCos/st2UWireCos)*trackletU->st2Usl )/( (st2VWireCos * st2UWireSin)/(st2UWireCos) - st2VWireSin ); + double testTY3 = ( trackletV->st3Vsl - (st3VWireCos/st3UWireCos)*trackletU->st3Usl )/( (st3VWireCos * st3UWireSin)/(st3UWireCos) - st3VWireSin ); + double testTX2 = ( trackletU->st2Usl - (st2UWireSin/st2VWireSin)*trackletV->st2Vsl )/( st2UWireCos - ( st2UWireSin * st2VWireCos )/st2VWireSin ); + double testTX3 = ( trackletU->st3Usl - (st3UWireSin/st3VWireSin)*trackletV->st3Vsl )/( st3UWireCos - ( st3UWireSin * st3VWireCos )/st3VWireSin ); + +#ifdef _DEBUG_PATRICK + std::cout<<"testTY2 = "<st2Xsl - testTX2) > 0.005 || std::abs(trackletX->st2Xsl - testTX3) > 0.005) continue; +#ifdef _DEBUG_PATRICK + LogInfo("past cont 2"); +#endif + //double posy = tracklet23->ty * ( z_plane[3] - tracklet23->st2Z ) + tracklet23->st2Y; //WPM + + double tracklet2Ys_D = 0.; //This is the sum of the Y-values of the hits in the U and V planes of the two tracklets. The sum is taken to be used in an average. The _D here stands for driftDistance. I originally did this part of the code without taking the drift distance in the slanted layers into account + double tracklet3Ys_D = 0.; + + for(unsigned int h = 0; h < trackletU->hits.size(); h++){ + double posx = trackletX->st2Xsl * (z_plane[(*trackletU).getHit(h).hit.detectorID] - trackletX->st2Z) + trackletX->st2X; + if((*trackletU).getHit(h).hit.detectorID == 17){ + tracklet2Ys_D += trackletU->acceptedULine2.wire1Slope * posx + trackletU->acceptedULine2.wireIntercept1; + } + if((*trackletU).getHit(h).hit.detectorID == 18){ + tracklet2Ys_D += trackletU->acceptedULine2.wire2Slope * posx + trackletU->acceptedULine2.wireIntercept2; + } + if((*trackletU).getHit(h).hit.detectorID == 19 || (*trackletU).getHit(h).hit.detectorID == 25){ + tracklet3Ys_D += trackletU->acceptedULine3.wire1Slope * posx + trackletU->acceptedULine3.wireIntercept1; + } + if((*trackletU).getHit(h).hit.detectorID == 20 || (*trackletU).getHit(h).hit.detectorID == 26){ + tracklet3Ys_D += trackletU->acceptedULine3.wire2Slope * posx + trackletU->acceptedULine3.wireIntercept2; + } + } + + for(unsigned int h = 0; h < trackletV->hits.size(); h++){ + double posx = trackletX->st2Xsl * (z_plane[(*trackletV).getHit(h).hit.detectorID] - trackletX->st2Z) + trackletX->st2X; + if((*trackletV).getHit(h).hit.detectorID == 13){ + tracklet2Ys_D += trackletV->acceptedVLine2.wire1Slope * posx + trackletV->acceptedVLine2.wireIntercept1; + } + if((*trackletV).getHit(h).hit.detectorID == 14){ + tracklet2Ys_D += trackletV->acceptedVLine2.wire2Slope * posx + trackletV->acceptedVLine2.wireIntercept2; + } + if((*trackletV).getHit(h).hit.detectorID == 23 || (*trackletV).getHit(h).hit.detectorID == 29){ + tracklet3Ys_D += trackletV->acceptedVLine3.wire1Slope * posx + trackletV->acceptedVLine3.wireIntercept1; + } + if((*trackletV).getHit(h).hit.detectorID == 24 || (*trackletV).getHit(h).hit.detectorID == 30){ + tracklet3Ys_D += trackletV->acceptedVLine3.wire2Slope * posx + trackletV->acceptedVLine3.wireIntercept2; + } + } + + double differentYSlope = (tracklet3Ys_D/4. - tracklet2Ys_D/4.)/(trackletX->st3Z - trackletX->st2Z); +#ifdef _DEBUG_PATRICK + std::cout<<"differentYSlope = "<st2Xsl; + tracklet_TEST_23.ty = (differentYSlope + testTY2 + testTY3)/3.; + tracklet_TEST_23.invP = 1./50.; + tracklet_TEST_23.x0 = trackletX->st2Xsl * (0. - trackletX->st2Z) + trackletX->st2X; + tracklet_TEST_23.y0 = (differentYSlope + testTY2 + testTY3)/3. * (0. - trackletX->st2Z) + tracklet2Ys_D/4.; + tracklet_TEST_23.calcChisq(); +#ifdef _DEBUG_PATRICK + tracklet_TEST_23.print(); +#endif + if(tracklet_TEST_23.chisq > 300) continue; +#ifdef _DEBUG_PATRICK + LogInfo("past cont 4"); +#endif + + + //std::cout<<"testTY st2 = "<print(); - for(int j = 0; j < 3; j++) LogInfo("Extrapo: " << pos_exp[j] << " " << window[j]); + tracklet_st2.print(); #endif - - _timers["global_st1"]->restart(); - if(!TRACK_DISPLACED){ - buildTrackletsInStation(i+1, 0, pos_exp, window); + if(acceptTracklet(tracklet_st2)) + { + trackletsInSt[1].push_back(tracklet_st2); } - if(TRACK_DISPLACED){ - buildTrackletsInStation(i+1, 0); +#ifdef _DEBUG_ON + else + { + LogInfo("Rejected!!!"); } - _timers["global_st1"]->stop(); - - _timers["global_link"]->restart(); - //Tracklet tracklet_best_prob, tracklet_best_vtx; - Tracklet tracklet_best_prob; - for(std::list::iterator tracklet1 = trackletsInSt[0].begin(); tracklet1 != trackletsInSt[0].end(); ++tracklet1) - { +#endif +*/ + } + + if(acceptedStation2Tracklets.size() == 0 || newSt2Tracklet){ + acceptedStation2Tracklets.push_back(tracklet_st2); + } + + //std::cout<<"trying station 3"< 18 && (*trackletX).getHit(2).hit.detectorID < 25){ + tracklet_st3.stationID = 4; + } + + if((*trackletX).getHit(2).hit.detectorID > 24 && (*trackletX).getHit(2).hit.detectorID < 31){ + tracklet_st3.stationID = 5; + } + + //resolveLeftRight(*xiter, LR1, LR2); + tracklet_st3.hits.push_back(SignedHit((*trackletX).getHit(2).hit, (*trackletX).getHit(2).sign)); + tracklet_st3.nXHits++; + tracklet_st3.hits.push_back(SignedHit((*trackletX).getHit(3).hit, (*trackletX).getHit(3).sign)); + tracklet_st3.nXHits++; + tracklet_st3.getSlopesX((*trackletX).getHit(2).hit, (*trackletX).getHit(3).hit); + + tracklet_st3.hits.push_back(SignedHit((*trackletU).getHit(2).hit, (*trackletU).getHit(2).sign)); + tracklet_st3.nUHits++; + tracklet_st3.hits.push_back(SignedHit((*trackletU).getHit(3).hit, (*trackletU).getHit(3).sign)); + tracklet_st3.nUHits++; + tracklet_st3.getSlopesU((*trackletU).getHit(2).hit, (*trackletU).getHit(3).hit); + + tracklet_st3.hits.push_back(SignedHit((*trackletV).getHit(2).hit, (*trackletV).getHit(2).sign)); + tracklet_st3.nVHits++; + tracklet_st3.hits.push_back(SignedHit((*trackletV).getHit(3).hit, (*trackletV).getHit(3).sign)); + tracklet_st3.nVHits++; + tracklet_st3.getSlopesV((*trackletV).getHit(2).hit, (*trackletV).getHit(3).hit); + + tracklet_st3.sortHits(); + + for(unsigned int tr3 = 0; tr3print(); + tracklet_st3.print(); #endif + if(acceptTracklet(tracklet_st3)) + { + trackletsInSt[2].push_back(tracklet_st3); + } +#ifdef _DEBUG_ON + else + { + LogInfo("Rejected!!!"); + } +#endif +*/ + } + + if(acceptedStation3Tracklets.size() == 0 || newSt3Tracklet){ + acceptedStation3Tracklets.push_back(tracklet_st3); + } + + //if(!(newSt2Tracklet) && !(newSt3Tracklet)) continue; //WPM changed + + Tracklet tracklet_23; + //Tracklet tracklet_23_reverse; + //if(compareTracklets(tracklet_st2, tracklet_st3)){ + if(compareTracklets(tracklet_st2, tracklet_st3)){ + /* + std::cout<<"about to COMBINE two tracklets"<::iterator iter = tracklet_st2.hits.begin(); iter != tracklet_st2.hits.end(); ++iter) + { + if(iter->sign > 0) std::cout << "L: "; + if(iter->sign < 0) std::cout << "R: "; + if(iter->sign == 0) std::cout << "U: "; + + std::cout << iter->hit.index << " " << p_geomSvc->getDetectorName(iter->hit.detectorID) << "(" << iter->hit.detectorID << ") " << iter->hit.elementID << " = "; + } + std::cout<::iterator iter = tracklet_st3.hits.begin(); iter != tracklet_st3.hits.end(); ++iter) + { + if(iter->sign > 0) std::cout << "L: "; + if(iter->sign < 0) std::cout << "R: "; + if(iter->sign == 0) std::cout << "U: "; + + std::cout << iter->hit.index << " " << p_geomSvc->getDetectorName(iter->hit.detectorID) << "(" << iter->hit.detectorID << ") " << iter->hit.elementID << " = "; + } + std::cout< 9000.) + { +#ifdef _DEBUG_ON + tracklet_23.print(); + LogInfo("Impossible combination!"); +#endif + continue; + } + /* + if(!COARSE_MODE && !hodoMask(tracklet_23)) + { - //Get the tracklets that has the best prob - if(tracklet_global < tracklet_best_prob) tracklet_best_prob = tracklet_global; +#ifdef _DEBUG_ON + LogInfo("Hodomasking failed!"); +#endif + continue; + } - ///Set vertex information - only applied when KF is enabled - ///TODO: maybe in the future add a Genfit-based equivalent here, for now leave as is +#ifdef _DEBUG_ON + LogInfo("Hodomasking Scucess!"); +#endif + */ + if(!COARSE_MODE) + { + resolveLeftRight(tracklet_23, 40.); //resolveLeftRight at this stage is, in truth, not needed. We already know which side of the wire the particle passed by from compareTracklet. However, getting rid of this would take a bit of work + resolveLeftRight(tracklet_23, 150.); + } - if(enable_KF && !TRACK_DISPLACED) - { - _timers["global_kalman"]->restart(); - SRecTrack recTrack = processOneTracklet(tracklet_global); - _timers["global_kalman"]->stop(); - tracklet_global.chisq_vtx = recTrack.getChisqVertex(); + ///Remove bad hits if needed + removeBadHits(tracklet_23); - if(recTrack.isValid() && tracklet_global.chisq_vtx < tracklet_best_vtx.chisq_vtx) tracklet_best_vtx = tracklet_global; - } #ifdef _DEBUG_ON - LogInfo("New tracklet: "); - tracklet_global.print(); + LogInfo("New tracklet: "); + tracklet_23.print(); - LogInfo("Current best by prob:"); - tracklet_best_prob.print(); + LogInfo("Current best:"); + tracklet_best_UX.print(); - LogInfo("Comparison I: " << (tracklet_global < tracklet_best_prob)); - LogInfo("Quality I : " << acceptTracklet(tracklet_global)); + LogInfo("Comparison: " << (tracklet_23 < tracklet_best_UX)); + LogInfo("Candidate chisq: " << tracklet_23.chisq); + LogInfo("Quality: " << acceptTracklet(tracklet_23)); - if(enable_KF && !TRACK_DISPLACED) - { - LogInfo("Current best by vtx:"); - tracklet_best_vtx.print(); - LogInfo("Comparison II: " << (tracklet_global.chisq_vtx < tracklet_best_vtx.chisq_vtx)); - LogInfo("Quality II : " << recTrack.isValid()); - } #endif - } - _timers["global_link"]->stop(); - //The selection logic is, prefer the tracks with best p-value, as long as it's not low-pz - if(enable_KF && !TRACK_DISPLACED && tracklet_best_prob.isValid() > 0 && 1./tracklet_best_prob.invP > 18.) - { - tracklet_best[i] = tracklet_best_prob; - } - else if(enable_KF && !TRACK_DISPLACED && tracklet_best_vtx.isValid() > 0) //otherwise select the one with best vertex chisq, TODO: maybe add a z-vtx constraint + //If current tracklet is better than the best tracklet up-to-now + if(acceptTracklet(tracklet_23) && tracklet_23 < tracklet_best_UX) + { - tracklet_best[i] = tracklet_best_vtx; + tracklet_best_UX = tracklet_23; } - else if(tracklet_best_prob.isValid() > 0) //then fall back to the default only choice +#ifdef _DEBUG_ON + else { - tracklet_best[i] = tracklet_best_prob; + LogInfo("Rejected!!"); } - } - - //Merge the tracklets from two stations if necessary - Tracklet tracklet_merge; - if(fabs(tracklet_best[0].getMomentum() - tracklet_best[1].getMomentum())/tracklet_best[0].getMomentum() < MERGE_THRES) - { - //Merge the track and re-fit - tracklet_merge = tracklet_best[0].merge(tracklet_best[1]); - fitTracklet(tracklet_merge); +#endif -#ifdef _DEBUG_ON - LogInfo("Merging two track candidates with momentum: " << tracklet_best[0].getMomentum() << " " << tracklet_best[1].getMomentum()); - LogInfo("tracklet_best_1:"); tracklet_best[0].print(); - LogInfo("tracklet_best_2:"); tracklet_best[1].print(); - LogInfo("tracklet_merge:"); tracklet_merge.print(); + } + if(tracklet_best_UX < tracklet_best){ + tracklet_best = tracklet_best_UX; + } + } + if(acceptTracklet(tracklet_best)){ + if(tracklet_best.isValid() > 0){ + //std::cout<<"pushing back 2+3 tracklets with candidate with the following chisq: "< 0 && tracklet_merge < tracklet_best[0] && tracklet_merge < tracklet_best[1]) - { + } + } + } + } + +} + + + +void KalmanFastTracking::buildBackPartialTracksSlim_v2() +{ #ifdef _DEBUG_ON - LogInfo("Choose merged tracklet"); + LogInfo("HELLO I'm in buildBackPartialTracksSlim"); #endif - trackletsInSt[4].push_back(tracklet_merge); - } - else if(tracklet_best[0].isValid() > 0 && tracklet_best[0] < tracklet_best[1]) - { + + std::vector acceptedStation2Tracklets; + std::vector acceptedStation3Tracklets; + + for(std::list::iterator trackletX = trackletsInStSlimX[3].begin(); trackletX != trackletsInStSlimX[3].end(); ++trackletX){ + Tracklet tracklet_best; + for(std::list::iterator trackletU = trackletsInStSlimU[3].begin(); trackletU != trackletsInStSlimU[3].end(); ++trackletU){ + Tracklet tracklet_best_UX; + for(std::list::iterator trackletV = trackletsInStSlimV[3].begin(); trackletV != trackletsInStSlimV[3].end(); ++trackletV){ + + double posy2U = ((*trackletU).st2U - p_geomSvc->getCostheta((*trackletX).getHit(0).hit.detectorID+2)*((*trackletX).st2X + (*trackletX).st2Xsl * ((*trackletU).st2Z - (*trackletX).st2Z) ))/p_geomSvc->getSintheta((*trackletX).getHit(0).hit.detectorID+2); + double posy2V = ((*trackletV).st2V - p_geomSvc->getCostheta((*trackletX).getHit(0).hit.detectorID-2)*((*trackletX).st2X + (*trackletX).st2Xsl * ((*trackletV).st2Z - (*trackletX).st2Z) ))/p_geomSvc->getSintheta((*trackletX).getHit(0).hit.detectorID-2); + double posy3U = ((*trackletU).st3U - p_geomSvc->getCostheta((*trackletX).getHit(2).hit.detectorID+2)*((*trackletX).st3X + (*trackletX).st3Xsl * ((*trackletU).st3Z - (*trackletX).st3Z) ))/p_geomSvc->getSintheta((*trackletX).getHit(2).hit.detectorID+2); + double posy3V = ((*trackletV).st3V - p_geomSvc->getCostheta((*trackletX).getHit(2).hit.detectorID-2)*((*trackletX).st3X + (*trackletX).st3Xsl * ((*trackletV).st3Z - (*trackletX).st3Z) ))/p_geomSvc->getSintheta((*trackletX).getHit(2).hit.detectorID-2); + +#ifdef _DEBUG_PATRICK + LogInfo("HELLO I'm in buildBackPartialTracksSlim"); +#endif + + double st2UWireSin = TMath::Sin(TMath::ATan(1./trackletU->acceptedULine2.wire1Slope)); + double st2VWireSin = TMath::Sin(TMath::ATan(1./trackletV->acceptedVLine2.wire1Slope)); + double st3UWireSin = TMath::Sin(TMath::ATan(1./trackletU->acceptedULine3.wire1Slope)); + double st3VWireSin = TMath::Sin(TMath::ATan(1./trackletV->acceptedVLine3.wire1Slope)); + + double st2UWireCos = TMath::Cos(TMath::ATan(1./trackletU->acceptedULine2.wire1Slope)); + double st2VWireCos = TMath::Cos(TMath::ATan(1./trackletV->acceptedVLine2.wire1Slope)); + double st3UWireCos = TMath::Cos(TMath::ATan(1./trackletU->acceptedULine3.wire1Slope)); + double st3VWireCos = TMath::Cos(TMath::ATan(1./trackletV->acceptedVLine3.wire1Slope)); + + double testTY2 = ( trackletV->st2Vsl - (st2VWireCos/st2UWireCos)*trackletU->st2Usl )/( (st2VWireCos * st2UWireSin)/(st2UWireCos) - st2VWireSin ); + double testTY3 = ( trackletV->st3Vsl - (st3VWireCos/st3UWireCos)*trackletU->st3Usl )/( (st3VWireCos * st3UWireSin)/(st3UWireCos) - st3VWireSin ); + double testTX2 = ( trackletU->st2Usl - (st2UWireSin/st2VWireSin)*trackletV->st2Vsl )/( st2UWireCos - ( st2UWireSin * st2VWireCos )/st2VWireSin ); + double testTX3 = ( trackletU->st3Usl - (st3UWireSin/st3VWireSin)*trackletV->st3Vsl )/( st3UWireCos - ( st3UWireSin * st3VWireCos )/st3VWireSin ); + +#ifdef _DEBUG_PATRICK + std::cout<<"testTY2 = "<st2Xsl - testTX2) > 0.005 || std::abs(trackletX->st2Xsl - testTX3) > 0.005) continue; +#ifdef _DEBUG_PATRICK + LogInfo("past cont 2"); +#endif + //double posy = tracklet23->ty * ( z_plane[3] - tracklet23->st2Z ) + tracklet23->st2Y; //WPM + + double tracklet2Ys_D = 0.; //This is the sum of the Y-values of the hits in the U and V planes of the two tracklets. The sum is taken to be used in an average. The _D here stands for driftDistance. I originally did this part of the code without taking the drift distance in the slanted layers into account + double tracklet3Ys_D = 0.; + + for(unsigned int h = 0; h < trackletU->hits.size(); h++){ + double posx = trackletX->st2Xsl * (z_plane[(*trackletU).getHit(h).hit.detectorID] - trackletX->st2Z) + trackletX->st2X; + if((*trackletU).getHit(h).hit.detectorID == 17){ + tracklet2Ys_D += trackletU->acceptedULine2.wire1Slope * posx + trackletU->acceptedULine2.wireIntercept1; + } + if((*trackletU).getHit(h).hit.detectorID == 18){ + tracklet2Ys_D += trackletU->acceptedULine2.wire2Slope * posx + trackletU->acceptedULine2.wireIntercept2; + } + if((*trackletU).getHit(h).hit.detectorID == 19 || (*trackletU).getHit(h).hit.detectorID == 25){ + tracklet3Ys_D += trackletU->acceptedULine3.wire1Slope * posx + trackletU->acceptedULine3.wireIntercept1; + } + if((*trackletU).getHit(h).hit.detectorID == 20 || (*trackletU).getHit(h).hit.detectorID == 26){ + tracklet3Ys_D += trackletU->acceptedULine3.wire2Slope * posx + trackletU->acceptedULine3.wireIntercept2; + } + } + + for(unsigned int h = 0; h < trackletV->hits.size(); h++){ + double posx = trackletX->st2Xsl * (z_plane[(*trackletV).getHit(h).hit.detectorID] - trackletX->st2Z) + trackletX->st2X; + if((*trackletV).getHit(h).hit.detectorID == 13){ + tracklet2Ys_D += trackletV->acceptedVLine2.wire1Slope * posx + trackletV->acceptedVLine2.wireIntercept1; + } + if((*trackletV).getHit(h).hit.detectorID == 14){ + tracklet2Ys_D += trackletV->acceptedVLine2.wire2Slope * posx + trackletV->acceptedVLine2.wireIntercept2; + } + if((*trackletV).getHit(h).hit.detectorID == 23 || (*trackletV).getHit(h).hit.detectorID == 29){ + tracklet3Ys_D += trackletV->acceptedVLine3.wire1Slope * posx + trackletV->acceptedVLine3.wireIntercept1; + } + if((*trackletV).getHit(h).hit.detectorID == 24 || (*trackletV).getHit(h).hit.detectorID == 30){ + tracklet3Ys_D += trackletV->acceptedVLine3.wire2Slope * posx + trackletV->acceptedVLine3.wireIntercept2; + } + } + + double differentYSlope = (tracklet3Ys_D/4. - tracklet2Ys_D/4.)/(trackletX->st3Z - trackletX->st2Z); +#ifdef _DEBUG_PATRICK + std::cout<<"differentYSlope = "<st2Xsl; + tracklet_TEST_23.ty = (differentYSlope + testTY2 + testTY3)/3.; + tracklet_TEST_23.invP = 1./50.; + tracklet_TEST_23.x0 = trackletX->st2Xsl * (0. - trackletX->st2Z) + trackletX->st2X; + tracklet_TEST_23.y0 = (differentYSlope + testTY2 + testTY3)/3. * (0. - trackletX->st2Z) + tracklet2Ys_D/4.; + tracklet_TEST_23.calcChisq(); +#ifdef _DEBUG_PATRICK + tracklet_TEST_23.print(); +#endif + if(tracklet_TEST_23.chisq > 300) continue; +#ifdef _DEBUG_PATRICK + LogInfo("past cont 4"); +#endif + + tracklet_TEST_23.st2Z = trackletX->st2Z; + tracklet_TEST_23.st2X = trackletX->st2X; + tracklet_TEST_23.st2Y = tracklet2Ys_D/4.; + tracklet_TEST_23.st3Y = tracklet3Ys_D/4.; + tracklet_TEST_23.st2U = trackletU->st2U; + tracklet_TEST_23.st2V = trackletV->st2V; + tracklet_TEST_23.st2Usl = trackletU->st2Usl; + tracklet_TEST_23.st2Vsl = trackletV->st2Vsl; + + + if(!COARSE_MODE) + { + resolveLeftRight(tracklet_TEST_23, 40.); //resolveLeftRight at this stage is, in truth, not needed. We already know which side of the wire the particle passed by from compareTracklet. However, getting rid of this would take a bit of work + resolveLeftRight(tracklet_TEST_23, 150.); + } + + ///Remove bad hits if needed + removeBadHits(tracklet_TEST_23); + + fitTracklet(tracklet_TEST_23); //This is the fit that needs the seeded tx and ty information. Without the seed information, the fit occasionally finds bad slope and X0 or Y0 values, much in the same way that it does for single-station tracklets. Note from Patrick: this fit could probably be throw out, as we already know the tx and ty information from compareTracklets. I would just need to extrapolate back to z = 0 and calculate the chisq by hand + if(tracklet_TEST_23.chisq > 9000.) + { #ifdef _DEBUG_ON - LogInfo("Choose tracklet with station-0"); + tracklet_TEST_23.print(); + LogInfo("Impossible combination!"); #endif - trackletsInSt[4].push_back(tracklet_best[0]); - } - else if(tracklet_best[1].isValid() > 0) - { + continue; + } + +#ifdef _DEBUG_PATRICK + LogInfo("New tracklet: "); + tracklet_TEST_23.print(); + + LogInfo("Current best:"); + tracklet_best_UX.print(); + + LogInfo("Comparison: " << (tracklet_TEST_23 < tracklet_best_UX)); + LogInfo("Candidate chisq: " << tracklet_TEST_23.chisq); + LogInfo("Quality: " << acceptTracklet(tracklet_TEST_23)); +#endif + + //If current tracklet is better than the best tracklet up-to-now + if(acceptTracklet(tracklet_TEST_23) && tracklet_TEST_23 < tracklet_best_UX) + { + tracklet_best_UX = tracklet_TEST_23; + } #ifdef _DEBUG_ON - LogInfo("Choose tracklet with station-1"); + else + { + LogInfo("Rejected!!"); + } #endif - trackletsInSt[4].push_back(tracklet_best[1]); - } + + } + if(tracklet_best_UX < tracklet_best){ + tracklet_best = tracklet_best_UX; + } } + if(acceptTracklet(tracklet_best)){ + if(tracklet_best.isValid() > 0){ + //std::cout<<"pushing back 2+3 tracklets with candidate with the following chisq: "<::iterator hit1 = tracklet.hits.begin(); - std::list::iterator hit2 = tracklet.hits.begin(); - ++hit2; - while(true) + for(std::list::iterator tracklet3 = trackletsInStSlimX[2].begin(); tracklet3 != trackletsInStSlimX[2].end(); ++tracklet3) { -#ifdef _DEBUG_ON - LogInfo(hit1->hit.index << " " << hit2->sign << " === " << hit2->hit.index << " " << hit2->sign); - int detectorID1 = hit1->hit.detectorID; - int detectorID2 = hit2->hit.detectorID; - LogInfo("Hit1: " << tracklet.getExpPositionX(z_plane[detectorID1])*costheta_plane[detectorID1] + tracklet.getExpPositionY(z_plane[detectorID1])*sintheta_plane[detectorID1] << " " << hit1->hit.pos + hit1->hit.driftDistance << " " << hit1->hit.pos - hit1->hit.driftDistance); - LogInfo("Hit2: " << tracklet.getExpPositionX(z_plane[detectorID2])*costheta_plane[detectorID2] + tracklet.getExpPositionY(z_plane[detectorID2])*sintheta_plane[detectorID2] << " " << hit2->hit.pos + hit2->hit.driftDistance << " " << hit2->hit.pos - hit2->hit.driftDistance); -#endif - - if(hit1->hit.index > 0 && hit2->hit.index > 0 && hit1->sign*hit2->sign == 0) + //tracklet3->print(); + /*if(!COARSE_MODE) { - int index_min = -1; - double pull_min = 1E6; - for(int i = 0; i < 4; i++) + //Extract the X hits only from station-3 tracks + nHitsX3 = 0; + for(std::list::iterator ptr_hit = tracklet3->hits.begin(); ptr_hit != tracklet3->hits.end(); ++ptr_hit) + { + if(ptr_hit->hit.index < 0) continue; + if(p_geomSvc->getPlaneType(ptr_hit->hit.detectorID) == 1) + { + z_fit[nHitsX3] = z_plane[ptr_hit->hit.detectorID]; + x_fit[nHitsX3] = ptr_hit->hit.pos; + ++nHitsX3; + } + } + }*/ + + Tracklet tracklet_best; + for(std::list::iterator tracklet2 = trackletsInStSlimX[1].begin(); tracklet2 != trackletsInStSlimX[1].end(); ++tracklet2) + { + //tracklet2->print(); + /*if(!COARSE_MODE) + { + if(OLD_TRACKING){ + if(fabs(tracklet2->tx - tracklet3->tx) > 0.15 || fabs(tracklet2->ty - tracklet3->ty) > 0.1) continue; + } + //Extract the X hits from station-2 tracke + nHitsX2 = nHitsX3; + for(std::list::iterator ptr_hit = tracklet2->hits.begin(); ptr_hit != tracklet2->hits.end(); ++ptr_hit) + { + if(ptr_hit->hit.index < 0) continue; + if(p_geomSvc->getPlaneType(ptr_hit->hit.detectorID) == 1) + { + z_fit[nHitsX2] = z_plane[ptr_hit->hit.detectorID]; + x_fit[nHitsX2] = ptr_hit->hit.pos; + ++nHitsX2; + } + } + + //Apply a simple linear fit to get rough estimation of X-Z slope and intersection + chi2fit(nHitsX2, z_fit, x_fit, a, b); + if(fabs(a) > 2.*TX_MAX || fabs(b) > 2.*X0_MAX) continue; + + //Project to proportional tubes to see if there is enough + int nPropHits = 0; + for(int i = 0; i < 4; ++i) + { + double x_exp = a*z_mask[detectorIDs_muid[0][i] - nChamberPlanes - 1] + b; + for(std::list::iterator iter = hitIDs_muid[0][i].begin(); iter != hitIDs_muid[0][i].end(); ++iter) + { + if(fabs(hitAll[*iter].pos - x_exp) < 5.08) + { + ++nPropHits; + break; + } + } + if(nPropHits > 0) break; + } + if(!TRACK_ELECTRONS && nPropHits == 0) continue; //Turned off by Patrick for electron tracks + }*/ + + Tracklet tracklet_23; + if(OLD_TRACKING){ + tracklet_23 = (*tracklet2) + (*tracklet3); + } + else{ + if(compareTrackletsSlim(*tracklet2, *tracklet3, pass)){ + tracklet_23 = (*tracklet2) + (*tracklet3); + tracklet_23.tx = tracklet2->tx; //This is needed to "seed" the tracklet fit that happens below. This tx and ty information is assigned in compareTracklets below + tracklet_23.st2X = tracklet2->st2X; + tracklet_23.st2Z = tracklet2->st2Z; + tracklet_23.st3X = tracklet3->st2X; + tracklet_23.st3Z = tracklet3->st2Z; + tracklet_23.st2Xsl = tracklet2->st2Xsl; + tracklet_23.st3Xsl = tracklet3->st2Xsl; + tracklet_23.acceptedXLine2 = tracklet2->acceptedXLine2; + tracklet_23.acceptedXLine3 = tracklet3->acceptedXLine3; + //std::cout<<"tracklet 2 tx is "<tx<<" and tracklet 3 tx is "<tx<st2X<<" and tracklet 3 st2X is "<st2X<print(); + tracklet3->print(); + LogInfo("Yield this combination:"); + tracklet_23.print(); +#endif + + trackletsInStSlimX[3].push_back(tracklet_23); + /*tracklet_23.ty = tracklet2->ty; + + tracklet_23.st2Z = tracklet2->st2Z; + tracklet_23.st2X = tracklet2->st2X; + tracklet_23.st2Y = tracklet2->st2Y; + tracklet_23.st3Y = tracklet2->st3Y; + tracklet_23.st2U = tracklet2->st2U; + tracklet_23.st2V = tracklet2->st2V; + tracklet_23.st2Usl = tracklet2->st2Usl; + tracklet_23.st2Vsl = tracklet2->st2Vsl;*/ + } + else{ + continue; + } + } + } + } + + //std::cout<<"Number of x pairs for 2+3 tracklets is "< 9000.) + { +#ifdef _DEBUG_ON + tracklet_23.print(); + LogInfo("Impossible combination!"); +#endif + continue; + } + + if(!COARSE_MODE && !hodoMask(tracklet_23)) + { +#ifdef _DEBUG_ON + LogInfo("Hodomasking failed!"); +#endif + continue; + } +#ifdef _DEBUG_ON + LogInfo("Hodomasking Scucess!"); +#endif + + if(!COARSE_MODE) + { + resolveLeftRight(tracklet_23, 40.); //resolveLeftRight at this stage is, in truth, not needed. We already know which side of the wire the particle passed by from compareTracklet. However, getting rid of this would take a bit of work + resolveLeftRight(tracklet_23, 150.); + } + + ///Remove bad hits if needed + removeBadHits(tracklet_23); + +#ifdef _DEBUG_ON + LogInfo("New tracklet: "); + tracklet_23.print(); + + LogInfo("Current best:"); + tracklet_best.print(); + + LogInfo("Comparison: " << (tracklet_23 < tracklet_best)); + LogInfo("Quality: " << acceptTracklet(tracklet_23)); +#endif + + //If current tracklet is better than the best tracklet up-to-now + if(acceptTracklet(tracklet_23) && tracklet_23 < tracklet_best) + { + tracklet_best = tracklet_23; + } +#ifdef _DEBUG_ON + else + { + LogInfo("Rejected!!"); + } +#endif + } + + if(tracklet_best.isValid() > 0) trackletsInSt[3].push_back(tracklet_best); + } + + reduceTrackletList(trackletsInSt[3]); + trackletsInSt[3].sort();*/ +} + +void KalmanFastTracking::buildBackPartialTracksSlimU(int pass) +{ + //Temporary container for a simple chisq fit + int nHitsX2, nHitsX3; + double z_fit[4], x_fit[4]; + double a, b; + + for(std::list::iterator tracklet3 = trackletsInStSlimU[2].begin(); tracklet3 != trackletsInStSlimU[2].end(); ++tracklet3) + { + Tracklet tracklet_best; + for(std::list::iterator tracklet2 = trackletsInStSlimU[1].begin(); tracklet2 != trackletsInStSlimU[1].end(); ++tracklet2) + { + Tracklet tracklet_23; + if(OLD_TRACKING){ + tracklet_23 = (*tracklet2) + (*tracklet3); + } + else{ + if(compareTrackletsSlimU(*tracklet2, *tracklet3, pass)){ + tracklet_23 = (*tracklet2) + (*tracklet3); + tracklet_23.tx = tracklet2->tx; //This is needed to "seed" the tracklet fit that happens below. This tx and ty information is assigned in compareTracklets below + tracklet_23.st2U = tracklet2->st2U; + tracklet_23.st2Z = tracklet2->st2Z; + tracklet_23.st3U = tracklet3->st2U; + tracklet_23.st3Z = tracklet3->st2Z; + tracklet_23.st2Usl = tracklet2->st2Usl; + tracklet_23.st3Usl = tracklet3->st2Usl; + tracklet_23.acceptedULine2 = tracklet2->acceptedULine2; + tracklet_23.acceptedULine3 = tracklet3->acceptedULine3; + //std::cout<<"tracklet 2 tx is "<tx<<" and tracklet 3 tx is "<tx<st2U<<" and tracklet 3 st2U is "<st2U<print(); + tracklet3->print(); + LogInfo("Yield this combination:"); + tracklet_23.print(); +#endif + + trackletsInStSlimU[3].push_back(tracklet_23); + /*tracklet_23.ty = tracklet2->ty; + + tracklet_23.st2Z = tracklet2->st2Z; + tracklet_23.st2X = tracklet2->st2X; + tracklet_23.st2Y = tracklet2->st2Y; + tracklet_23.st3Y = tracklet2->st3Y; + tracklet_23.st2U = tracklet2->st2U; + tracklet_23.st2V = tracklet2->st2V; + tracklet_23.st2Usl = tracklet2->st2Usl; + tracklet_23.st2Vsl = tracklet2->st2Vsl;*/ + } + else{ + continue; + } + } + } + } + + //std::cout<<"Number of U pairs for 2+3 tracklets is "<::iterator tracklet3 = trackletsInStSlimV[2].begin(); tracklet3 != trackletsInStSlimV[2].end(); ++tracklet3) + { + Tracklet tracklet_best; + for(std::list::iterator tracklet2 = trackletsInStSlimV[1].begin(); tracklet2 != trackletsInStSlimV[1].end(); ++tracklet2) + { + Tracklet tracklet_23; + if(OLD_TRACKING){ + tracklet_23 = (*tracklet2) + (*tracklet3); + } + else{ + if(compareTrackletsSlimV(*tracklet2, *tracklet3, pass)){ + tracklet_23 = (*tracklet2) + (*tracklet3); + tracklet_23.tx = tracklet2->tx; //This is needed to "seed" the tracklet fit that happens below. This tx and ty information is assigned in compareTracklets below + tracklet_23.st2V = tracklet2->st2V; + tracklet_23.st2Z = tracklet2->st2Z; + tracklet_23.st3V = tracklet3->st2V; + tracklet_23.st3Z = tracklet3->st2Z; + tracklet_23.st2Vsl = tracklet2->st2Vsl; + tracklet_23.st3Vsl = tracklet3->st2Vsl; + //std::cout<<"SECOND TEST OF LINE2 "<acceptedVLine2.wireHit1PosZ<acceptedVLine2; + //std::cout<<"THIRD TEST OF LINE2 "<acceptedVLine3; + //std::cout<<"tracklet 2 tx is "<tx<<" and tracklet 3 tx is "<tx<st2V<<" and tracklet 3 st2V is "<st2V<print(); + tracklet3->print(); + LogInfo("Yield this combination:"); + tracklet_23.print(); +#endif + + trackletsInStSlimV[3].push_back(tracklet_23); + /*tracklet_23.ty = tracklet2->ty; + + tracklet_23.st2Z = tracklet2->st2Z; + tracklet_23.st2X = tracklet2->st2X; + tracklet_23.st2Y = tracklet2->st2Y; + tracklet_23.st3Y = tracklet2->st3Y; + tracklet_23.st2U = tracklet2->st2U; + tracklet_23.st2V = tracklet2->st2V; + tracklet_23.st2Usl = tracklet2->st2Usl; + tracklet_23.st2Vsl = tracklet2->st2Vsl;*/ + } + else{ + continue; + } + } + } + } + + //std::cout<<"Number of V pairs for 2+3 tracklets is "<::iterator tracklet23 = trackletsInSt[3].begin(); tracklet23 != trackletsInSt[3].end(); ++tracklet23) + { + Tracklet tracklet_best[2]; + for(int i = 0; i < 2; ++i) //for two station-1 chambers + { + trackletsInSt[0].clear(); + if(!TRACK_DISPLACED){ + //Calculate the window in station 1 + if(KMAG_ON) + { + getSagittaWindowsInSt1(*tracklet23, pos_exp, window, i+1); + } + else + { + getExtrapoWindowsInSt1(*tracklet23, pos_exp, window, i+1); + } + } +#ifdef _DEBUG_ON + LogInfo("Using this back partial: "); + tracklet23->print(); + for(int j = 0; j < 3; j++) LogInfo("Extrapo: " << pos_exp[j] << " " << window[j]); +#endif + + _timers["global_st1"]->restart(); + if(!TRACK_DISPLACED){ + buildTrackletsInStation(i+1, 0, pos_exp, window); + } + if(TRACK_DISPLACED){ + buildTrackletsInStation(i+1, 0); + } + + _timers["global_st1"]->stop(); + + _timers["global_link"]->restart(); + Tracklet tracklet_best_prob, tracklet_best_vtx; + for(std::list::iterator tracklet1 = trackletsInSt[0].begin(); tracklet1 != trackletsInSt[0].end(); ++tracklet1) + { +#ifdef _DEBUG_ON + LogInfo("With this station 1 track:"); + tracklet1->print(); +#endif + + Tracklet tracklet_global = (*tracklet23) * (*tracklet1); + fitTracklet(tracklet_global); + if(!hodoMask(tracklet_global)) continue; + + ///Resolve the left-right with a tight pull cut, then a loose one, then resolve by single projections + if(!COARSE_MODE) + { + resolveLeftRight(tracklet_global, 75.); + resolveLeftRight(tracklet_global, 150.); + resolveSingleLeftRight(tracklet_global); + } + if(TRACK_DISPLACED){ + double firstChiSq = tracklet_global.calcChisq(); + Tracklet tracklet_global2 = (*tracklet23) * (*tracklet1); + tracklet_global2.setCharge(-1*tracklet_global2.getCharge()); /**By default, the value returned by getCharge is based on the x0 of the tracklet. For a particle produced at the target, this is a valid way to extract charge. However, for a displaced particle, the x0 does not tell you anything useful about the charge of the particle, which is why we need to check both possible charge values. getCharge is used later on when extracting certain track quality values, so using the wrong charge leads to tracks getting rejected due to poor quality values*/ + if(!COARSE_MODE) + { + resolveLeftRight(tracklet_global2, 75.); + resolveLeftRight(tracklet_global2, 150.); + resolveSingleLeftRight(tracklet_global2); + } + double secondChiSq = tracklet_global2.calcChisq(); + if(secondChiSq < firstChiSq){ + tracklet_global = tracklet_global2; + } + } + + ///Remove bad hits if needed + removeBadHits(tracklet_global); + + //Most basic cuts + if(!acceptTracklet(tracklet_global)) continue; + + //Get the tracklets that has the best prob + if(tracklet_global < tracklet_best_prob) tracklet_best_prob = tracklet_global; + + ///Set vertex information - only applied when KF is enabled + ///TODO: maybe in the future add a Genfit-based equivalent here, for now leave as is + if(enable_KF && NOT_DISPLACED) + { + _timers["global_kalman"]->restart(); + SRecTrack recTrack = processOneTracklet(tracklet_global); + _timers["global_kalman"]->stop(); + tracklet_global.chisq_vtx = recTrack.getChisqVertex(); + + if(recTrack.isValid() && tracklet_global.chisq_vtx < tracklet_best_vtx.chisq_vtx) tracklet_best_vtx = tracklet_global; + } + +#ifdef _DEBUG_ON + LogInfo("New tracklet: "); + tracklet_global.print(); + + LogInfo("Current best by prob:"); + tracklet_best_prob.print(); + + LogInfo("Comparison I: " << (tracklet_global < tracklet_best_prob)); + LogInfo("Quality I : " << acceptTracklet(tracklet_global)); + + if(enable_KF && NOT_DISPLACED) + { + LogInfo("Current best by vtx:"); + tracklet_best_vtx.print(); + + LogInfo("Comparison II: " << (tracklet_global.chisq_vtx < tracklet_best_vtx.chisq_vtx)); + //LogInfo("Quality II : " << recTrack.isValid()); + } +#endif + } + _timers["global_link"]->stop(); + + //The selection logic is, prefer the tracks with best p-value, as long as it's not low-pz + if(enable_KF && NOT_DISPLACED && tracklet_best_prob.isValid() > 0 && 1./tracklet_best_prob.invP > 18.) + { + tracklet_best[i] = tracklet_best_prob; + } + else if(enable_KF && NOT_DISPLACED && tracklet_best_vtx.isValid() > 0) //otherwise select the one with best vertex chisq, TODO: maybe add a z-vtx constraint + { + tracklet_best[i] = tracklet_best_vtx; + } + else if(tracklet_best_prob.isValid() > 0) //then fall back to the default only choice + { + tracklet_best[i] = tracklet_best_prob; + } + } + + //Merge the tracklets from two stations if necessary + Tracklet tracklet_merge; + if(fabs(tracklet_best[0].getMomentum() - tracklet_best[1].getMomentum())/tracklet_best[0].getMomentum() < MERGE_THRES) + { + //Merge the track and re-fit + tracklet_merge = tracklet_best[0].merge(tracklet_best[1]); + fitTracklet(tracklet_merge); + +#ifdef _DEBUG_ON + LogInfo("Merging two track candidates with momentum: " << tracklet_best[0].getMomentum() << " " << tracklet_best[1].getMomentum()); + LogInfo("tracklet_best_1:"); tracklet_best[0].print(); + LogInfo("tracklet_best_2:"); tracklet_best[1].print(); + LogInfo("tracklet_merge:"); tracklet_merge.print(); +#endif + } + + if(tracklet_merge.isValid() > 0 && tracklet_merge < tracklet_best[0] && tracklet_merge < tracklet_best[1]) + { +#ifdef _DEBUG_ON + LogInfo("Choose merged tracklet"); +#endif + trackletsInSt[4].push_back(tracklet_merge); + } + else if(tracklet_best[0].isValid() > 0 && tracklet_best[0] < tracklet_best[1]) + { +#ifdef _DEBUG_ON + LogInfo("Choose tracklet with station-0"); +#endif + trackletsInSt[4].push_back(tracklet_best[0]); + } + else if(tracklet_best[1].isValid() > 0) + { +#ifdef _DEBUG_ON + LogInfo("Choose tracklet with station-1"); +#endif + trackletsInSt[4].push_back(tracklet_best[1]); + } + } + + trackletsInSt[4].sort(); +} + + +void KalmanFastTracking::buildGlobalTracksDisplaced() +{ + double pos_exp[3], window[3]; + for(std::list::iterator tracklet23 = trackletsInSt[3].begin(); tracklet23 != trackletsInSt[3].end(); ++tracklet23) + { + + Tracklet tracklet_best_prob, tracklet_best_vtx; + + //std::cout<<"I'm testing backwards extrapolation... z_plane thing is "<tx * ( z_plane[3] - tracklet23->st2Z ) + tracklet23->st2X; //WPM pick up here. do u and v extrapolations + //std::cout<<"test of u extrapo. st2Usl = "<st2Usl<<" ( z_plane[(i)*6 + 0] - tracklet23->st2UZ ) = "<<( z_plane[3] - tracklet23->st2UZ )<<" tracklet23->st2U = "<st2U<st2Usl * ( z_plane[1] - tracklet23->st2Z ) + tracklet23->st2U; //WPM + double posv = tracklet23->st2Vsl * ( z_plane[5] - tracklet23->st2Z ) + tracklet23->st2V; //WPM + double posy = tracklet23->ty * ( z_plane[3] - tracklet23->st2Z ) + tracklet23->st2Y; //WPM + //std::cout<<"checking V extrapolation. tracklet23->st2Vsl: "<st2Vsl<<", ( z_plane[5] - tracklet23->st2Z ): "<<( z_plane[5] - tracklet23->st2Z )<<", tracklet23->st2V: "<st2V<ty * ( z_plane[3] - tracklet23->st2Z ) + tracklet23->st2Y<getCostheta(1)<<", "<getCostheta(2)<<", "<getCostheta(3)<<", "<getCostheta(4)<<", "<getCostheta(5)<<", "<getCostheta(6)<getSintheta(1)<<", "<getSintheta(2)<<", "<getSintheta(3)<<", "<getSintheta(4)<<", "<getSintheta(5)<<", "<getSintheta(6)<print(); + for(int j = 0; j < 3; j++) LogInfo("Extrapo: " << pos_exp[j] << " " << window[j]); +#endif + + (*tracklet23).setCharge(charges[ch]); //WPM + double expXZSlope = ((*tracklet23).tx - 0.002 * charges[ch]*pxSlices[pxs]); + + _timers["global_st1"]->restart(); + if(!TRACK_DISPLACED){ + buildTrackletsInStation(i+1, 0, pos_exp, window); + } + if(TRACK_DISPLACED){ + //(*tracklet23).setCharge(charges[ch]); //WPM + //tracklet23->print(); + pos_exp[0] = posx+charges[ch]*pxSlices[pxs]; + pos_exp[1] = p_geomSvc->getCostheta(1) * pos_exp[0] + p_geomSvc->getSintheta(1) * posy; + pos_exp[2] = p_geomSvc->getCostheta(5) * pos_exp[0] + p_geomSvc->getSintheta(5) * posy; + //std::cout<<"The window I'm using is centered at "<getCostheta(1) * pos_exp[0] + p_geomSvc->getSintheta(1) * posy<<", "<getCostheta(5) * pos_exp[0] + p_geomSvc->getSintheta(5) * posy<print()<stop(); + + _timers["global_link"]->restart(); + int tracklet_counter = 0; //WPM + + for(std::list::iterator tracklet1 = trackletsInSt[0].begin(); tracklet1 != trackletsInSt[0].end(); ++tracklet1) + { + /* + std::cout<<"PRINT possible x slopes"< 4) continue; + + for(std::list::iterator hit1 = tracklet1->hits.begin(); hit1 != tracklet1->hits.end(); ++hit1) + { + if(hit1->hit.detectorID == 4){ + if(bestTrackletX == 0){ + hit1->sign = 1; + } + if(bestTrackletX == 1){ + hit1->sign = 1; + } + if(bestTrackletX == 2){ + hit1->sign = -1; + } + if(bestTrackletX == 3){ + hit1->sign = -1; + } + } + if(hit1->hit.detectorID == 3){ + if(bestTrackletX == 0){ + hit1->sign = 1; + } + if(bestTrackletX == 1){ + hit1->sign = -1; + } + if(bestTrackletX == 2){ + hit1->sign = 1; + } + if(bestTrackletX == 3){ + hit1->sign = -1; + } + } + if(nValidUSlopes == 1){ + if(hit1->hit.detectorID == 1){ + if(bestTrackletU == 0){ + hit1->sign = 1; + } + if(bestTrackletU == 1){ + hit1->sign = 1; + } + if(bestTrackletU == 2){ + hit1->sign = -1; + } + if(bestTrackletU == 3){ + hit1->sign = -1; + } + } + if(hit1->hit.detectorID == 2){ + if(bestTrackletU == 0){ + hit1->sign = 1; + } + if(bestTrackletU == 1){ + hit1->sign = -1; + } + if(bestTrackletU == 2){ + hit1->sign = 1; + } + if(bestTrackletU == 3){ + hit1->sign = -1; + } + } + } + if(nValidVSlopes == 1){ + if(hit1->hit.detectorID == 5){ + if(bestTrackletV == 0){ + hit1->sign = 1; + } + if(bestTrackletV == 1){ + hit1->sign = 1; + } + if(bestTrackletV == 2){ + hit1->sign = -1; + } + if(bestTrackletV == 3){ + hit1->sign = -1; + } + } + if(hit1->hit.detectorID == 6){ + if(bestTrackletV == 0){ + hit1->sign = 1; + } + if(bestTrackletV == 1){ + hit1->sign = -1; + } + if(bestTrackletV == 2){ + hit1->sign = 1; + } + if(bestTrackletV == 3){ + hit1->sign = -1; + } + } + } + }*/ + + tracklet1->tx = expXZSlope; + tracklet1->ty = tracklet23->ty; + tracklet1->x0 = tracklet23->x0; + tracklet1->y0 = tracklet23->y0; + tracklet1->setCharge(charges[ch]); //WPM + + //std::cout<<"I GOT A GOOD TRACKLETX"<print(); + fitTracklet((*tracklet1)); + + //resolveLeftRight((*tracklet1), 75.); + //resolveLeftRight((*tracklet1), 150.); + + + tracklet_counter++; //WPM + //std::cout<<"try tracklet number "<print(); +#endif + + int unsignedHits = 0; + for(std::list::iterator hit1 = tracklet1->hits.begin(); hit1 != tracklet1->hits.end(); ++hit1) + { + if(hit1->sign == 0) unsignedHits++; + } + //if(unsignedHits>0){ + // for(std::list::iterator hit1 = tracklet1->hits.begin(); hit1 != tracklet1->hits.end(); ++hit1) + // { + // hit1->sign = 0; + // } + // tracklet1->tx = expXZSlope; + // tracklet1->ty = tracklet23->ty; + // tracklet1->x0 = tracklet23->x0; + // tracklet1->y0 = tracklet23->y0; + // tracklet1->setCharge(charges[ch]); //WPM + // fitTracklet((*tracklet1)); + //} + + //std::vector signs = {0,0,0,0,0,0}; + //for(std::list::iterator hit1 = tracklet1->hits.begin(); hit1 != tracklet1->hits.end(); ++hit1) + // { + // signs.at(hit1->hit.detectorID - 1) = hit1->sign; + // hit1->sign=0; + // } + + Tracklet tracklet_global = (*tracklet23) * (*tracklet1); + tracklet_global.setCharge(charges[ch]); //WPM + //std::cout<<"Prior to fitting my supposedly good station 7 tracklet, let's print it out:"<::iterator hit1 = tracklet_global.hits.begin(); hit1 != tracklet_global.hits.end(); ++hit1) + { + if(hit1->hit.detectorID == 3 || hit1->hit.detectorID == 4){ + hit1->sign = signs.at(hit1->hit.detectorID - 1); + } + }*/ + resolveLeftRight(tracklet_global, 75.); + resolveLeftRight(tracklet_global, 150.); + resolveSingleLeftRight(tracklet_global); + } + /*if(TRACK_DISPLACED){ + double firstChiSq = tracklet_global.calcChisq(); + Tracklet tracklet_global2 = (*tracklet23) * (*tracklet1); + tracklet_global2.setCharge(-1*tracklet_global2.getCharge()); //By default, the value returned by getCharge is based on the x0 of the tracklet. For a particle produced at the target, this is a valid way to extract charge. However, for a displaced particle, the x0 does not tell you anything useful about the charge of the particle, which is why we need to check both possible charge values. getCharge is used later on when extracting certain track quality values, so using the wrong charge leads to tracks getting rejected due to poor quality values + if(!COARSE_MODE) + { + resolveLeftRight(tracklet_global2, 75.); + resolveLeftRight(tracklet_global2, 150.); + resolveSingleLeftRight(tracklet_global2); + } + double secondChiSq = tracklet_global2.calcChisq(); + if(secondChiSq < firstChiSq){ + tracklet_global = tracklet_global2; + } + }*/ + + ///Remove bad hits if needed + removeBadHits(tracklet_global); + + //Most basic cuts + if(!acceptTracklet(tracklet_global)) continue; + + //Get the tracklets that has the best prob + if(tracklet_global < tracklet_best_prob) tracklet_best_prob = tracklet_global; + + ///Set vertex information - only applied when KF is enabled + ///TODO: maybe in the future add a Genfit-based equivalent here, for now leave as is + if(enable_KF && NOT_DISPLACED) + { + _timers["global_kalman"]->restart(); + SRecTrack recTrack = processOneTracklet(tracklet_global); + _timers["global_kalman"]->stop(); + tracklet_global.chisq_vtx = recTrack.getChisqVertex(); + + if(recTrack.isValid() && tracklet_global.chisq_vtx < tracklet_best_vtx.chisq_vtx) tracklet_best_vtx = tracklet_global; + } + +#ifdef _DEBUG_ON + LogInfo("New tracklet: "); + tracklet_global.print(); + + LogInfo("Current best by prob:"); + tracklet_best_prob.print(); + + LogInfo("Comparison I: " << (tracklet_global < tracklet_best_prob)); + LogInfo("Quality I : " << acceptTracklet(tracklet_global)); + + if(enable_KF && NOT_DISPLACED) + { + LogInfo("Current best by vtx:"); + tracklet_best_vtx.print(); + + LogInfo("Comparison II: " << (tracklet_global.chisq_vtx < tracklet_best_vtx.chisq_vtx)); + //LogInfo("Quality II : " << recTrack.isValid()); + } +#endif + } + //fitTracklet(tracklet_best_prob); + //std::cout<<"after refit"<stop(); + + //The selection logic is, prefer the tracks with best p-value, as long as it's not low-pz + if(enable_KF && NOT_DISPLACED && tracklet_best_prob.isValid() > 0 && 1./tracklet_best_prob.invP > 18.) + { + tracklet_best[i] = tracklet_best_prob; + //if(tracklet_best_prob.hits.size()==6) validTrackFound = true; + } + else if(enable_KF && NOT_DISPLACED && tracklet_best_vtx.isValid() > 0) //otherwise select the one with best vertex chisq, TODO: maybe add a z-vtx constraint + { + tracklet_best[i] = tracklet_best_vtx; + //if(tracklet_best_vtx.hits.size()==6) validTrackFound = true; + } + else if(tracklet_best_prob.isValid() > 0) //then fall back to the default only choice + { + tracklet_best[i] = tracklet_best_prob; + //if(tracklet_best_prob.hits.size()==6) validTrackFound = true; + } + } + if(tracklet_best_prob.chisq < 1.) break; + } + if(tracklet_best_prob.chisq < 1.) break; + } + + //Merge the tracklets from two stations if necessary + Tracklet tracklet_merge; + if(fabs(tracklet_best[0].getMomentum() - tracklet_best[1].getMomentum())/tracklet_best[0].getMomentum() < MERGE_THRES) + { + //Merge the track and re-fit + tracklet_merge = tracklet_best[0].merge(tracklet_best[1]); + fitTracklet(tracklet_merge); + +#ifdef _DEBUG_ON + LogInfo("Merging two track candidates with momentum: " << tracklet_best[0].getMomentum() << " " << tracklet_best[1].getMomentum()); + LogInfo("tracklet_best_1:"); tracklet_best[0].print(); + LogInfo("tracklet_best_2:"); tracklet_best[1].print(); + LogInfo("tracklet_merge:"); tracklet_merge.print(); +#endif + } + + if(tracklet_merge.isValid() > 0 && tracklet_merge < tracklet_best[0] && tracklet_merge < tracklet_best[1]) + { +#ifdef _DEBUG_ON + LogInfo("Choose merged tracklet"); +#endif + //tracklet_merge.tx = -0.022337; + //tracklet_merge.ty = -0.018866; + //tracklet_merge.x0 = 34.68; + //tracklet_merge.y0 = 19.815; + //tracklet_merge.invP = 0.06275; + //std::cout<<"I forced the tracklet to behave. Now chisq = "< 0 && tracklet_best[0] < tracklet_best[1]) + { +#ifdef _DEBUG_ON + LogInfo("Choose tracklet with station-0"); +#endif + //tracklet_best[0].tx = -0.022337; + //tracklet_best[0].ty = -0.018866; + //tracklet_best[0].x0 = 34.68; + //tracklet_best[0].y0 = 19.815; + //tracklet_best[0].invP = 0.06275; + //std::cout<<"I forced the tracklet to behave. Now chisq = "< 0) + { +#ifdef _DEBUG_ON + LogInfo("Choose tracklet with station-1"); +#endif + //tracklet_best[1].tx = -0.022337; + //tracklet_best[1].ty = -0.018866; + //tracklet_best[1].x0 = 34.68; + //tracklet_best[1].y0 = 19.815; + //tracklet_best[1].invP = 0.06275; + //std::cout<<"I forced the tracklet to behave. Now chisq = "<::iterator hit1 = tracklet.hits.begin(); + std::list::iterator hit2 = tracklet.hits.begin(); + ++hit2; + while(true) + { +#ifdef _DEBUG_ON + LogInfo(hit1->hit.index << " " << hit2->sign << " === " << hit2->hit.index << " " << hit2->sign); + int detectorID1 = hit1->hit.detectorID; + int detectorID2 = hit2->hit.detectorID; + LogInfo("Hit1: " << tracklet.getExpPositionX(z_plane[detectorID1])*costheta_plane[detectorID1] + tracklet.getExpPositionY(z_plane[detectorID1])*sintheta_plane[detectorID1] << " " << hit1->hit.pos + hit1->hit.driftDistance << " " << hit1->hit.pos - hit1->hit.driftDistance); + LogInfo("Hit2: " << tracklet.getExpPositionX(z_plane[detectorID2])*costheta_plane[detectorID2] + tracklet.getExpPositionY(z_plane[detectorID2])*sintheta_plane[detectorID2] << " " << hit2->hit.pos + hit2->hit.driftDistance << " " << hit2->hit.pos - hit2->hit.driftDistance); +#endif + + if(hit1->hit.index > 0 && hit2->hit.index > 0 && hit1->sign*hit2->sign == 0) + { + int index_min = -1; + double pull_min = 1E6; + for(int i = 0; i < 4; i++) + { + double slope_local = (hit1->pos(possibility[i][0]) - hit2->pos(possibility[i][1]))/(z_plane[hit1->hit.detectorID] - z_plane[hit2->hit.detectorID]); + double inter_local = hit1->pos(possibility[i][0]) - slope_local*z_plane[hit1->hit.detectorID]; + + if(fabs(slope_local) > slope_max[hit1->hit.detectorID] || fabs(inter_local) > intersection_max[hit1->hit.detectorID]) continue; + + double tx, ty, x0, y0; + double err_tx, err_ty, err_x0, err_y0; + if(tracklet.stationID == 7 && hit1->hit.detectorID <= 6) + { + tracklet.getXZInfoInSt1(tx, x0); + tracklet.getXZErrorInSt1(err_tx, err_x0); + } + else + { + tx = tracklet.tx; + x0 = tracklet.x0; + err_tx = tracklet.err_tx; + err_x0 = tracklet.err_x0; + } + ty = tracklet.ty; + y0 = tracklet.y0; + err_ty = tracklet.err_ty; + err_y0 = tracklet.err_y0; + + double slope_exp = costheta_plane[hit1->hit.detectorID]*tx + sintheta_plane[hit1->hit.detectorID]*ty; + double err_slope = fabs(costheta_plane[hit1->hit.detectorID]*err_tx) + fabs(sintheta_plane[hit2->hit.detectorID]*err_ty); + double inter_exp = costheta_plane[hit1->hit.detectorID]*x0 + sintheta_plane[hit1->hit.detectorID]*y0; + double err_inter = fabs(costheta_plane[hit1->hit.detectorID]*err_x0) + fabs(sintheta_plane[hit2->hit.detectorID]*err_y0); + + double pull = sqrt((slope_exp - slope_local)*(slope_exp - slope_local)/err_slope/err_slope + (inter_exp - inter_local)*(inter_exp - inter_local)/err_inter/err_inter); + if(pull < pull_min) + { + index_min = i; + pull_min = pull; + } + +#ifdef _DEBUG_ON + LogInfo(hit1->hit.detectorID << ": " << i << " " << possibility[i][0] << " " << possibility[i][1]); + LogInfo(tx << " " << x0 << " " << ty << " " << y0); + LogInfo("Slope: " << slope_local << " " << slope_exp << " " << err_slope); + LogInfo("Intersection: " << inter_local << " " << inter_exp << " " << err_inter); + LogInfo("Current: " << pull << " " << index_min << " " << pull_min); +#endif + } + + //LogInfo("Final: " << index_min << " " << pull_min); + if(index_min >= 0 && pull_min < threshold)//((tracklet.stationID == 5 && pull_min < 25.) || (tracklet.stationID == 6 && pull_min < 100.))) + { + hit1->sign = possibility[index_min][0]; + hit2->sign = possibility[index_min][1]; + isUpdated = true; + } + } + + ++nResolved; + if(nResolved >= nPairs) break; + + ++hit1; + ++hit1; + ++hit2; + ++hit2; + } + + if(isUpdated) fitTracklet(tracklet); +} + +void KalmanFastTracking::resolveSingleLeftRight(Tracklet& tracklet) +{ +#ifdef _DEBUG_ON + LogInfo("Single left right for this track.."); + tracklet.print(); +#endif + + //Check if the track has been updated + bool isUpdated = false; + for(std::list::iterator hit_sign = tracklet.hits.begin(); hit_sign != tracklet.hits.end(); ++hit_sign) + { + if(hit_sign->hit.index < 0 || hit_sign->sign != 0) continue; + + int detectorID = hit_sign->hit.detectorID; + double pos_exp = tracklet.getExpPositionX(z_plane[detectorID])*costheta_plane[detectorID] + tracklet.getExpPositionY(z_plane[detectorID])*sintheta_plane[detectorID]; + hit_sign->sign = pos_exp > hit_sign->hit.pos ? 1 : -1; + + isUpdated = true; + } + + if(isUpdated) fitTracklet(tracklet); +} + +void KalmanFastTracking::removeBadHits(Tracklet& tracklet) +{ +#ifdef _DEBUG_ON + LogInfo("Removing hits for this track.."); + tracklet.calcChisq(); + tracklet.print(); +#endif + + //Check if the track has beed updated + int signflipflag[nChamberPlanes]; + for(int i = 0; i < nChamberPlanes; ++i) signflipflag[i] = 0; + + bool isUpdated = true; + while(isUpdated) + { + isUpdated = false; + tracklet.calcChisq(); + + SignedHit* hit_remove = nullptr; + SignedHit* hit_neighbour = nullptr; + double res_remove1 = -1.; + double res_remove2 = -1.; + for(std::list::iterator hit_sign = tracklet.hits.begin(); hit_sign != tracklet.hits.end(); ++hit_sign) + { + if(hit_sign->hit.index < 0) continue; + + int detectorID = hit_sign->hit.detectorID; + double res_curr = fabs(tracklet.residual[detectorID-1]); + if(res_remove1 < res_curr) + { + res_remove1 = res_curr; + res_remove2 = fabs(tracklet.residual[detectorID-1] - 2.*hit_sign->sign*hit_sign->hit.driftDistance); + hit_remove = &(*hit_sign); + + std::list::iterator iter = hit_sign; + hit_neighbour = detectorID % 2 == 0 ? &(*(--iter)) : &(*(++iter)); + } + } + if(hit_remove == nullptr) continue; + if(hit_remove->sign == 0 && tracklet.isValid() > 0) continue; //if sign is undecided, and chisq is OKay, then pass + + double cut = hit_remove->sign == 0 ? hit_remove->hit.driftDistance + resol_plane[hit_remove->hit.detectorID] : resol_plane[hit_remove->hit.detectorID]; + if(res_remove1 > cut) + { +#ifdef _DEBUG_ON + LogInfo("Dropping this hit: " << res_remove1 << " " << res_remove2 << " " << signflipflag[hit_remove->hit.detectorID-1] << " " << cut); + hit_remove->hit.print(); + hit_neighbour->hit.print(); +#endif + + //can only be changed less than twice + if(res_remove2 < cut && signflipflag[hit_remove->hit.detectorID-1] < 2) + { + hit_remove->sign = -hit_remove->sign; + hit_neighbour->sign = 0; + ++signflipflag[hit_remove->hit.detectorID-1]; +#ifdef _DEBUG_ON + LogInfo("Only changing the sign."); +#endif + } + else + { + //Set the index of the hit to be removed to -1 so it's not used anymore + //also set the sign assignment of the neighbour hit to 0 (i.e. undecided) + hit_remove->hit.index = -1; + hit_neighbour->sign = 0; + int planeType = p_geomSvc->getPlaneType(hit_remove->hit.detectorID); + if(planeType == 1) + { + --tracklet.nXHits; + } + else if(planeType == 2) + { + --tracklet.nUHits; + } + else + { + --tracklet.nVHits; + } + + //If both hit pairs are not included, the track can be rejected + if(hit_neighbour->hit.index < 0) + { +#ifdef _DEBUG_ON + LogInfo("Both hits in a view are missing! Will exit the bad hit removal..."); +#endif + return; + } + } + isUpdated = true; + } + + if(isUpdated) + { + fitTracklet(tracklet); + resolveSingleLeftRight(tracklet); + } + } +} + +void KalmanFastTracking::resolveLeftRight(SRawEvent::hit_pair hpair, int& LR1, int& LR2) +{ + LR1 = 0; + LR2 = 0; + + //If either hit is missing, no left-right can be assigned + if(hpair.first < 0 || hpair.second < 0) + { + return; + } + + int possibility[4][2] = {{1, 1}, {1, -1}, {-1, 1}, {-1, -1}}; + int nResolved = 0; + for(int i = 0; i < 4; i++) + { + if(nResolved > 1) break; + + int hitID1 = hpair.first; + int hitID2 = hpair.second; + double slope_local = (hitAll[hitID1].pos + possibility[i][0]*hitAll[hitID1].driftDistance - hitAll[hitID2].pos - possibility[i][1]*hitAll[hitID2].driftDistance)/(z_plane[hitAll[hitID1].detectorID] - z_plane[hitAll[hitID2].detectorID]); + double intersection_local = hitAll[hitID1].pos + possibility[i][0]*hitAll[hitID1].driftDistance - slope_local*z_plane[hitAll[hitID1].detectorID]; + + //LogInfo(i << " " << nResolved << " " << slope_local << " " << intersection_local); + if(fabs(slope_local) < slope_max[hitAll[hitID1].detectorID] && fabs(intersection_local) < intersection_max[hitAll[hitID1].detectorID]) + { + nResolved++; + LR1 = possibility[i][0]; + LR2 = possibility[i][1]; + } + } + + if(nResolved > 1) + { + LR1 = 0; + LR2 = 0; + } + + //LogInfo("Final: " << LR1 << " " << LR2); +} + +void KalmanFastTracking::buildTrackletsInStation(int stationID, int listID, double* pos_exp, double* window) +{ +#ifdef _DEBUG_ON + LogInfo("Building tracklets in station " << stationID); +#endif + + //actuall ID of the tracklet lists + int sID = stationID - 1; + + //Extract the X, U, V hit pairs + std::list pairs_X, pairs_U, pairs_V; + if(pos_exp == nullptr) + { + pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0]); + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1]); + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2]); + } + else + { + //Note that in pos_exp[], index 0 stands for X, index 1 stands for U, index 2 stands for V + pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0], pos_exp[0], window[0]); + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1], pos_exp[1], window[1]); + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2], pos_exp[2], window[2]); + } + +#ifdef _DEBUG_ON + LogInfo("Hit pairs in this event: "); + for(std::list::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_U.begin(); iter != pairs_U.end(); ++iter) LogInfo("U :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_V.begin(); iter != pairs_V.end(); ++iter) LogInfo("V :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif + + if(pairs_X.empty() || pairs_U.empty() || pairs_V.empty()) + { +#ifdef _DEBUG_ON + LogInfo("Not all view has hits in station " << stationID); +#endif + return; + } + + //X-U combination first, then add V pairs + for(std::list::iterator xiter = pairs_X.begin(); xiter != pairs_X.end(); ++xiter) + { + //U projections from X plane + double x_pos = xiter->second >= 0 ? 0.5*(hitAll[xiter->first].pos + hitAll[xiter->second].pos) : hitAll[xiter->first].pos; + double u_min = x_pos*u_costheta[sID] - u_win[sID]; + double u_max = u_min + 2.*u_win[sID]; + +#ifdef _DEBUG_ON + LogInfo("Trying X hits " << xiter->first << " " << xiter->second << " " << hitAll[xiter->first].elementID << " at " << x_pos); + LogInfo("U plane window:" << u_min << " " << u_max); +#endif + for(std::list::iterator uiter = pairs_U.begin(); uiter != pairs_U.end(); ++uiter) + { + double u_pos = uiter->second >= 0 ? 0.5*(hitAll[uiter->first].pos + hitAll[uiter->second].pos) : hitAll[uiter->first].pos; +#ifdef _DEBUG_ON + LogInfo("Trying U hits " << uiter->first << " " << uiter->second << " " << hitAll[uiter->first].elementID << " at " << u_pos); +#endif + if(u_pos < u_min || u_pos > u_max) continue; + + //V projections from X and U plane + double z_x = xiter->second >= 0 ? z_plane_x[sID] : z_plane[hitAll[xiter->first].detectorID]; + double z_u = uiter->second >= 0 ? z_plane_u[sID] : z_plane[hitAll[uiter->first].detectorID]; + double z_v = z_plane_v[sID]; + double v_win1 = spacing_plane[hitAll[uiter->first].detectorID]*2.*u_costheta[sID]; + double v_win2 = fabs((z_u + z_v - 2.*z_x)*u_costheta[sID]*TX_MAX); + double v_win3 = fabs((z_v - z_u)*u_sintheta[sID]*TY_MAX); + double v_win = v_win1 + v_win2 + v_win3 + 2.*spacing_plane[hitAll[uiter->first].detectorID]; + double v_min = 2*x_pos*u_costheta[sID] - u_pos - v_win; + double v_max = v_min + 2.*v_win; + +#ifdef _DEBUG_ON + LogInfo("V plane window:" << v_min << " " << v_max); +#endif + for(std::list::iterator viter = pairs_V.begin(); viter != pairs_V.end(); ++viter) { - double slope_local = (hit1->pos(possibility[i][0]) - hit2->pos(possibility[i][1]))/(z_plane[hit1->hit.detectorID] - z_plane[hit2->hit.detectorID]); - double inter_local = hit1->pos(possibility[i][0]) - slope_local*z_plane[hit1->hit.detectorID]; + double v_pos = viter->second >= 0 ? 0.5*(hitAll[viter->first].pos + hitAll[viter->second].pos) : hitAll[viter->first].pos; +#ifdef _DEBUG_ON + LogInfo("Trying V hits " << viter->first << " " << viter->second << " " << hitAll[viter->first].elementID << " at " << v_pos); +#endif + if(v_pos < v_min || v_pos > v_max) continue; - if(fabs(slope_local) > slope_max[hit1->hit.detectorID] || fabs(inter_local) > intersection_max[hit1->hit.detectorID]) continue; + //Now add the tracklet + int LR1 = 0; + int LR2 = 0; + Tracklet tracklet_new; + tracklet_new.stationID = stationID; - double tx, ty, x0, y0; - double err_tx, err_ty, err_x0, err_y0; - if(tracklet.stationID == 6 && hit1->hit.detectorID <= 6) + //resolveLeftRight(*xiter, LR1, LR2); + if(xiter->first >= 0) { - tracklet.getXZInfoInSt1(tx, x0); - tracklet.getXZErrorInSt1(err_tx, err_x0); + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->first], LR1)); + tracklet_new.nXHits++; } - else + if(xiter->second >= 0) { - tx = tracklet.tx; - x0 = tracklet.x0; - err_tx = tracklet.err_tx; - err_x0 = tracklet.err_x0; + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->second], LR2)); + tracklet_new.nXHits++; } - ty = tracklet.ty; - y0 = tracklet.y0; - err_ty = tracklet.err_ty; - err_y0 = tracklet.err_y0; + if(!OLD_TRACKING){ + tracklet_new.getSlopesX(hitAll[xiter->first], hitAll[xiter->second]); //Here, we find the four possible X-Z lines + } + //resolveLeftRight(*uiter, LR1, LR2); + if(uiter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[uiter->first], LR1)); + tracklet_new.nUHits++; + } + if(uiter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[uiter->second], LR2)); + tracklet_new.nUHits++; + } + if(!OLD_TRACKING){ + tracklet_new.getSlopesU(hitAll[uiter->first], hitAll[uiter->second]); //find the four possible U-Z lines + } - double slope_exp = costheta_plane[hit1->hit.detectorID]*tx + sintheta_plane[hit1->hit.detectorID]*ty; - double err_slope = fabs(costheta_plane[hit1->hit.detectorID]*err_tx) + fabs(sintheta_plane[hit2->hit.detectorID]*err_ty); - double inter_exp = costheta_plane[hit1->hit.detectorID]*x0 + sintheta_plane[hit1->hit.detectorID]*y0; - double err_inter = fabs(costheta_plane[hit1->hit.detectorID]*err_x0) + fabs(sintheta_plane[hit2->hit.detectorID]*err_y0); + //resolveLeftRight(*viter, LR1, LR2); + if(viter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[viter->first], LR1)); + tracklet_new.nVHits++; + } + if(viter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[viter->second], LR2)); + tracklet_new.nVHits++; + } + if(!OLD_TRACKING){ + tracklet_new.getSlopesV(hitAll[viter->first], hitAll[viter->second]); //find the four possible V-Z lines + } - double pull = sqrt((slope_exp - slope_local)*(slope_exp - slope_local)/err_slope/err_slope + (inter_exp - inter_local)*(inter_exp - inter_local)/err_inter/err_inter); - if(pull < pull_min) + tracklet_new.sortHits(); + if(tracklet_new.isValid() == 0) //TODO: What IS THIS? { - index_min = i; - pull_min = pull; + fitTracklet(tracklet_new); //This is where the original DCA minimization is performed + } + else + { + continue; } #ifdef _DEBUG_ON - LogInfo(hit1->hit.detectorID << ": " << i << " " << possibility[i][0] << " " << possibility[i][1]); - LogInfo(tx << " " << x0 << " " << ty << " " << y0); - LogInfo("Slope: " << slope_local << " " << slope_exp << " " << err_slope); - LogInfo("Intersection: " << inter_local << " " << inter_exp << " " << err_inter); - LogInfo("Current: " << pull << " " << index_min << " " << pull_min); + tracklet_new.print(); +#endif + if(acceptTracklet(tracklet_new)) + { + trackletsInSt[listID].push_back(tracklet_new); + } +#ifdef _DEBUG_ON + else + { + LogInfo("Rejected!!!"); + } +#endif + } + } + } + + //Reduce the tracklet list and add dummy hits + //reduceTrackletList(trackletsInSt[listID]); + for(std::list::iterator iter = trackletsInSt[listID].begin(); iter != trackletsInSt[listID].end(); ++iter) + { + iter->addDummyHits(); + } + + //Only retain the best 200 tracklets if exceeded + //std::cout<<"NUMBER of tracklets before resize = "< 1000) + { + trackletsInSt[listID].sort(); + trackletsInSt[listID].resize(1000); + } +} + + + +bool KalmanFastTracking::buildTrackletsInStation1(int stationID, int listID, double expXZSlope, double* pos_exp, double* window) +{ +#ifdef _DEBUG_ON + LogInfo("Building tracklets in station " << stationID); +#endif + + bool st1TrackletFound = false; + + //actuall ID of the tracklet lists + int sID = stationID - 1; + + //Extract the X, U, V hit pairs + std::list pairs_X, pairs_U, pairs_V; + if(pos_exp == nullptr) + { + pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0]); + //pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1]); + //pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2]); + } + else + { + //Note that in pos_exp[], index 0 stands for X, index 1 stands for U, index 2 stands for V + pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0], pos_exp[0], window[0]); + //pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1], pos_exp[1], window[1]); + //pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2], pos_exp[2], window[2]); + } + +#ifdef _DEBUG_ON + LogInfo("Hit pairs in this event: "); + for(std::list::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + //for(std::list::iterator iter = pairs_U.begin(); iter != pairs_U.end(); ++iter) LogInfo("U :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + //for(std::list::iterator iter = pairs_V.begin(); iter != pairs_V.end(); ++iter) LogInfo("V :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif + + //if(pairs_X.empty() || pairs_U.empty() || pairs_V.empty()) + if(pairs_X.empty()) + { +#ifdef _DEBUG_ON + LogInfo("Not all view has hits in station " << stationID); +#endif + return st1TrackletFound; + } + + //X-U combination first, then add V pairs + for(std::list::iterator xiter = pairs_X.begin(); xiter != pairs_X.end(); ++xiter) + { + + if(!(xiter->first >= 0) || !(xiter->second >= 0)) continue; + + //make a tracklet + int LR1 = 0; + int LR2 = 0; + Tracklet tracklet_new; + tracklet_new.stationID = stationID; + + //resolveLeftRight(*xiter, LR1, LR2); + if(xiter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->first], LR1)); + tracklet_new.nXHits++; + } + if(xiter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->second], LR2)); + tracklet_new.nXHits++; + } + if(!OLD_TRACKING){ + tracklet_new.getSlopesX(hitAll[xiter->first], hitAll[xiter->second]); //Here, we find the four possible X-Z lines + } + + double bestSlopeDiffX = 1.0; + double slopeDiffX = 1.0; + int bestTrackletX = 5; + double trackletXslope = 1.0; + int nValidXSlopes = 0; + for(int t3 = 0; t3 < tracklet_new.possibleXLines.size(); t3++){ + //std::cout< 4) continue; + + if(pos_exp == nullptr) + { + //pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0]); + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1]); + //pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2]); + } + else + { + //Note that in pos_exp[], index 0 stands for X, index 1 stands for U, index 2 stands for V + //pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0], pos_exp[0], window[0]); + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1], pos_exp[1], window[1]); + //pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2], pos_exp[2], window[2]); + } + +#ifdef _DEBUG_ON + LogInfo("Hit pairs in this event: "); + //for(std::list::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_U.begin(); iter != pairs_U.end(); ++iter) LogInfo("U :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + //for(std::list::iterator iter = pairs_V.begin(); iter != pairs_V.end(); ++iter) LogInfo("V :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif + + //U projections from X plane + double x_pos = xiter->second >= 0 ? 0.5*(hitAll[xiter->first].pos + hitAll[xiter->second].pos) : hitAll[xiter->first].pos; + double u_min = x_pos*u_costheta[sID] - u_win[sID]; + double u_max = u_min + 2.*u_win[sID]; + +#ifdef _DEBUG_ON + LogInfo("Trying X hits " << xiter->first << " " << xiter->second << " " << hitAll[xiter->first].elementID << " at " << x_pos); + LogInfo("U plane window:" << u_min << " " << u_max); +#endif + for(std::list::iterator uiter = pairs_U.begin(); uiter != pairs_U.end(); ++uiter) + { + + if(!(uiter->first >= 0) || !(uiter->second >= 0)) continue; + + double u_pos = uiter->second >= 0 ? 0.5*(hitAll[uiter->first].pos + hitAll[uiter->second].pos) : hitAll[uiter->first].pos; +#ifdef _DEBUG_ON + LogInfo("Trying U hits " << uiter->first << " " << uiter->second << " " << hitAll[uiter->first].elementID << " at " << u_pos); +#endif + if(u_pos < u_min || u_pos > u_max) continue; + + + Tracklet tracklet_newU; + tracklet_newU = tracklet_new; + //tracklet_newU.stationID = stationID; + + //resolveLeftRight(*uiter, LR1, LR2); + if(uiter->first >= 0) + { + tracklet_newU.hits.push_back(SignedHit(hitAll[uiter->first], LR1)); + tracklet_newU.nUHits++; + } + if(uiter->second >= 0) + { + tracklet_newU.hits.push_back(SignedHit(hitAll[uiter->second], LR2)); + tracklet_newU.nUHits++; + } + if(!OLD_TRACKING){ + tracklet_newU.getSlopesU(hitAll[uiter->first], hitAll[uiter->second]); //find the four possible U-Z lines + } + + int nValidUSlopes = 0; + int bestTrackletU = 5; + for(int t3 = 0; t3 < tracklet_newU.possibleULines.size(); t3++){ + if( std::abs(tracklet_newU.possibleULines.at(t3).slopeU) < 0.15 ){ + nValidUSlopes++; + bestTrackletU = t3; + } + } + + if(nValidUSlopes == 0) continue; + + + if(pos_exp == nullptr) + { + //pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0]); + //pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1]); + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2]); + } + else + { + //Note that in pos_exp[], index 0 stands for X, index 1 stands for U, index 2 stands for V + //pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0], pos_exp[0], window[0]); + //pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1], pos_exp[1], window[1]); + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2], pos_exp[2], window[2]); + } + +#ifdef _DEBUG_ON + LogInfo("Hit pairs in this event: "); + //for(std::list::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + //for(std::list::iterator iter = pairs_U.begin(); iter != pairs_U.end(); ++iter) LogInfo("U :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_V.begin(); iter != pairs_V.end(); ++iter) LogInfo("V :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif + + + + //V projections from X and U plane + double z_x = xiter->second >= 0 ? z_plane_x[sID] : z_plane[hitAll[xiter->first].detectorID]; + double z_u = uiter->second >= 0 ? z_plane_u[sID] : z_plane[hitAll[uiter->first].detectorID]; + double z_v = z_plane_v[sID]; + double v_win1 = spacing_plane[hitAll[uiter->first].detectorID]*2.*u_costheta[sID]; + double v_win2 = fabs((z_u + z_v - 2.*z_x)*u_costheta[sID]*TX_MAX); + double v_win3 = fabs((z_v - z_u)*u_sintheta[sID]*TY_MAX); + double v_win = v_win1 + v_win2 + v_win3 + 2.*spacing_plane[hitAll[uiter->first].detectorID]; + double v_min = 2*x_pos*u_costheta[sID] - u_pos - v_win; + double v_max = v_min + 2.*v_win; + +#ifdef _DEBUG_ON + LogInfo("V plane window:" << v_min << " " << v_max); +#endif + for(std::list::iterator viter = pairs_V.begin(); viter != pairs_V.end(); ++viter) + { + + if(!(viter->first >= 0) || !(viter->second >= 0)) continue; + + double v_pos = viter->second >= 0 ? 0.5*(hitAll[viter->first].pos + hitAll[viter->second].pos) : hitAll[viter->first].pos; +#ifdef _DEBUG_ON + LogInfo("Trying V hits " << viter->first << " " << viter->second << " " << hitAll[viter->first].elementID << " at " << v_pos); #endif - } + if(v_pos < v_min || v_pos > v_max) continue; + + + Tracklet tracklet_newV; + tracklet_newV = tracklet_newU; + //tracklet_newV.stationID = stationID; + + + //resolveLeftRight(*viter, LR1, LR2); + if(viter->first >= 0) + { + tracklet_newV.hits.push_back(SignedHit(hitAll[viter->first], LR1)); + tracklet_newV.nVHits++; + } + if(viter->second >= 0) + { + tracklet_newV.hits.push_back(SignedHit(hitAll[viter->second], LR2)); + tracklet_newV.nVHits++; + } + if(!OLD_TRACKING){ + tracklet_newV.getSlopesV(hitAll[viter->first], hitAll[viter->second]); //find the four possible V-Z lines + } + + int nValidVSlopes = 0; + int bestTrackletV = 5; + for(int t3 = 0; t3 < tracklet_newV.possibleVLines.size(); t3++){ + if( std::abs(tracklet_newV.possibleVLines.at(t3).slopeV) < 0.15 ){ + nValidVSlopes++; + bestTrackletV = t3; + } + } - //LogInfo("Final: " << index_min << " " << pull_min); - if(index_min >= 0 && pull_min < threshold)//((tracklet.stationID == 5 && pull_min < 25.) || (tracklet.stationID == 6 && pull_min < 100.))) - { - hit1->sign = possibility[index_min][0]; - hit2->sign = possibility[index_min][1]; - isUpdated = true; + if(nValidVSlopes == 0) continue; + + tracklet_newV.sortHits(); + + st1TrackletFound=true; + + for(std::list::iterator hit1 = tracklet_newV.hits.begin(); hit1 != tracklet_newV.hits.end(); ++hit1) + { + if(nValidUSlopes == 1){ + if(hit1->hit.detectorID == 4){ + if(bestTrackletX == 0){ + hit1->sign = 1; + } + if(bestTrackletX == 1){ + hit1->sign = -1; + } + if(bestTrackletX == 2){ + hit1->sign = 1; + } + if(bestTrackletX == 3){ + hit1->sign = -1; + } + } + if(hit1->hit.detectorID == 3){ + if(bestTrackletX == 0){ + hit1->sign = 1; + } + if(bestTrackletX == 1){ + hit1->sign = 1; + } + if(bestTrackletX == 2){ + hit1->sign = -1; + } + if(bestTrackletX == 3){ + hit1->sign = -1; + } + } + } + if(nValidUSlopes == 1){ + if(hit1->hit.detectorID == 1){ + if(bestTrackletU == 0){ + hit1->sign = 1; + } + if(bestTrackletU == 1){ + hit1->sign = -1; + } + if(bestTrackletU == 2){ + hit1->sign = 1; + } + if(bestTrackletU == 3){ + hit1->sign = -1; + } + } + if(hit1->hit.detectorID == 2){ + if(bestTrackletU == 0){ + hit1->sign = 1; + } + if(bestTrackletU == 1){ + hit1->sign = 1; + } + if(bestTrackletU == 2){ + hit1->sign = -1; + } + if(bestTrackletU == 3){ + hit1->sign = -1; + } + } + } + if(nValidVSlopes == 1){ + if(hit1->hit.detectorID == 5){ + if(bestTrackletV == 0){ + hit1->sign = 1; + } + if(bestTrackletV == 1){ + hit1->sign = -1; + } + if(bestTrackletV == 2){ + hit1->sign = 1; + } + if(bestTrackletV == 3){ + hit1->sign = -1; + } + } + if(hit1->hit.detectorID == 6){ + if(bestTrackletV == 0){ + hit1->sign = 1; + } + if(bestTrackletV == 1){ + hit1->sign = 1; + } + if(bestTrackletV == 2){ + hit1->sign = -1; + } + if(bestTrackletV == 3){ + hit1->sign = -1; + } + } + } + } + + trackletsInSt[listID].push_back(tracklet_newV); + } } + } - ++nResolved; - if(nResolved >= nPairs) break; - - ++hit1; - ++hit1; - ++hit2; - ++hit2; + //Reduce the tracklet list and add dummy hits + //reduceTrackletList(trackletsInSt[listID]); + for(std::list::iterator iter = trackletsInSt[listID].begin(); iter != trackletsInSt[listID].end(); ++iter) + { + iter->addDummyHits(); } - if(isUpdated) fitTracklet(tracklet); + //std::cout<<"NUMBER of tracklets before resize = "<::iterator hit_sign = tracklet.hits.begin(); hit_sign != tracklet.hits.end(); ++hit_sign) - { - if(hit_sign->hit.index < 0 || hit_sign->sign != 0) continue; - - int detectorID = hit_sign->hit.detectorID; - double pos_exp = tracklet.getExpPositionX(z_plane[detectorID])*costheta_plane[detectorID] + tracklet.getExpPositionY(z_plane[detectorID])*sintheta_plane[detectorID]; - hit_sign->sign = pos_exp > hit_sign->hit.pos ? 1 : -1; + //actuall ID of the tracklet lists + int sID = stationID - 1; - isUpdated = true; + //Extract the X, U, V hit pairs + std::list pairs_X, pairs_U, pairs_V; + if(pos_exp == nullptr) + { + pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0]); + //pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1]); + //pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2]); + } + else + { + //Note that in pos_exp[], index 0 stands for X, index 1 stands for U, index 2 stands for V + pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0], pos_exp[0], window[0]); + //pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1], pos_exp[1], window[1]); + //pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2], pos_exp[2], window[2]); } - if(isUpdated) fitTracklet(tracklet); -} - -void KalmanFastTracking::removeBadHits(Tracklet& tracklet) -{ #ifdef _DEBUG_ON - LogInfo("Removing hits for this track.."); - tracklet.calcChisq(); - tracklet.print(); + LogInfo("Hit pairs in this event: "); + for(std::list::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + //for(std::list::iterator iter = pairs_U.begin(); iter != pairs_U.end(); ++iter) LogInfo("U :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + //for(std::list::iterator iter = pairs_V.begin(); iter != pairs_V.end(); ++iter) LogInfo("V :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); #endif - //Check if the track has beed updated - int signflipflag[nChamberPlanes]; - for(int i = 0; i < nChamberPlanes; ++i) signflipflag[i] = 0; + //if(pairs_X.empty() || pairs_U.empty() || pairs_V.empty()) + if(pairs_X.empty()) + { +#ifdef _DEBUG_ON + LogInfo("Not all view has hits in station " << stationID); +#endif + return; + } - bool isUpdated = true; - while(isUpdated) + //X-U combination first, then add V pairs + for(std::list::iterator xiter = pairs_X.begin(); xiter != pairs_X.end(); ++xiter) { - isUpdated = false; - tracklet.calcChisq(); - SignedHit* hit_remove = nullptr; - SignedHit* hit_neighbour = nullptr; - double res_remove1 = -1.; - double res_remove2 = -1.; - for(std::list::iterator hit_sign = tracklet.hits.begin(); hit_sign != tracklet.hits.end(); ++hit_sign) - { - if(hit_sign->hit.index < 0) continue; + int LR1 = 0; + int LR2 = 0; + Tracklet tracklet_new; + tracklet_new.stationID = stationID; + + //resolveLeftRight(*xiter, LR1, LR2); + if(xiter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->first], LR1)); + tracklet_new.nXHits++; + } + if(xiter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->second], LR2)); + tracklet_new.nXHits++; + } + if(!OLD_TRACKING){ + tracklet_new.getSlopesX(hitAll[xiter->first], hitAll[xiter->second]); //Here, we find the four possible X-Z lines + } + + tracklet_new.sortHits(); +#ifdef _DEBUG_ON + //std::cout<<"About to print new tracklet"<hit.detectorID; - double res_curr = fabs(tracklet.residual[detectorID-1]); - if(res_remove1 < res_curr) - { - res_remove1 = res_curr; - res_remove2 = fabs(tracklet.residual[detectorID-1] - 2.*hit_sign->sign*hit_sign->hit.driftDistance); - hit_remove = &(*hit_sign); + //std::cout<<"Number of x pairs in station "<::iterator iter = hit_sign; - hit_neighbour = detectorID % 2 == 0 ? &(*(--iter)) : &(*(++iter)); - } - } - if(hit_remove == nullptr) continue; - if(hit_remove->sign == 0 && tracklet.isValid() > 0) continue; //if sign is undecided, and chisq is OKay, then pass - double cut = hit_remove->sign == 0 ? hit_remove->hit.driftDistance + resol_plane[hit_remove->hit.detectorID] : resol_plane[hit_remove->hit.detectorID]; - if(res_remove1 > cut) - { +void KalmanFastTracking::buildTrackletsInStationSlimU(int stationID, int listID, double* pos_exp, double* window) +{ #ifdef _DEBUG_ON - LogInfo("Dropping this hit: " << res_remove1 << " " << res_remove2 << " " << signflipflag[hit_remove->hit.detectorID-1] << " " << cut); - hit_remove->hit.print(); - hit_neighbour->hit.print(); + LogInfo("Building U tracklets in station (slim version) " << stationID); #endif - //can only be changed less than twice - if(res_remove2 < cut && signflipflag[hit_remove->hit.detectorID-1] < 2) - { - hit_remove->sign = -hit_remove->sign; - hit_neighbour->sign = 0; - ++signflipflag[hit_remove->hit.detectorID-1]; + //actuall ID of the tracklet lists + int sID = stationID - 1; + + //Extract the X, U, V hit pairs + std::list pairs_X, pairs_U, pairs_V; + if(pos_exp == nullptr) + { + if(stationID == 4 || stationID == 5){ + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2]); + } + else{ + //pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0]); + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1]); + //pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2]); + } + } + else + { + if(stationID == 4 || stationID == 5){ + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2], pos_exp[2], window[2]); + } + else{ + //Note that in pos_exp[], index 0 stands for X, index 1 stands for U, index 2 stands for V + //pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0], pos_exp[0], window[0]); + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1], pos_exp[1], window[1]); + //pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2], pos_exp[2], window[2]); + } + } + #ifdef _DEBUG_ON - LogInfo("Only changing the sign."); + LogInfo("Hit pairs in this event: "); + //for(std::list::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_U.begin(); iter != pairs_U.end(); ++iter) LogInfo("U :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + //for(std::list::iterator iter = pairs_V.begin(); iter != pairs_V.end(); ++iter) LogInfo("V :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); #endif - } - else - { - //Set the index of the hit to be removed to -1 so it's not used anymore - //also set the sign assignment of the neighbour hit to 0 (i.e. undecided) - hit_remove->hit.index = -1; - hit_neighbour->sign = 0; - int planeType = p_geomSvc->getPlaneType(hit_remove->hit.detectorID); - if(planeType == 1) - { - --tracklet.nXHits; - } - else if(planeType == 2) - { - --tracklet.nUHits; - } - else - { - --tracklet.nVHits; - } - //If both hit pairs are not included, the track can be rejected - if(hit_neighbour->hit.index < 0) - { + //if(pairs_X.empty() || pairs_U.empty() || pairs_V.empty()) + if(pairs_U.empty()) + { #ifdef _DEBUG_ON - LogInfo("Both hits in a view are missing! Will exit the bad hit removal..."); + LogInfo("Not all view has hits in station " << stationID); #endif - return; - } - } - isUpdated = true; - } + return; + } - if(isUpdated) - { - fitTracklet(tracklet); - resolveSingleLeftRight(tracklet); - } + //X-U combination first, then add V pairs + for(std::list::iterator xiter = pairs_U.begin(); xiter != pairs_U.end(); ++xiter) + { + + int LR1 = 0; + int LR2 = 0; + Tracklet tracklet_new; + tracklet_new.stationID = stationID; + + //resolveLeftRight(*xiter, LR1, LR2); + if(xiter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->first], LR1)); + tracklet_new.nUHits++; + } + if(xiter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->second], LR2)); + tracklet_new.nUHits++; + } + if(!OLD_TRACKING){ + tracklet_new.getSlopesU(hitAll[xiter->first], hitAll[xiter->second]); //Here, we find the four possible X-Z lines + } + + tracklet_new.sortHits(); +#ifdef _DEBUG_ON + //std::cout<<"About to print new U tracklet"< pairs_X, pairs_U, pairs_V; + if(pos_exp == nullptr) { - return; + if(stationID == 4 || stationID == 5){ + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1]); + } + else{ + //pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0]); + //pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1]); + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2]); + } } - - int possibility[4][2] = {{1, 1}, {1, -1}, {-1, 1}, {-1, -1}}; - int nResolved = 0; - for(int i = 0; i < 4; i++) + else { - if(nResolved > 1) break; + if(stationID == 4 || stationID == 5){ + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1], pos_exp[1], window[1]); + } + else{ + //Note that in pos_exp[], index 0 stands for X, index 1 stands for U, index 2 stands for V + //pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0], pos_exp[0], window[0]); + //pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1], pos_exp[1], window[1]); + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2], pos_exp[2], window[2]); + } + } - int hitID1 = hpair.first; - int hitID2 = hpair.second; - double slope_local = (hitAll[hitID1].pos + possibility[i][0]*hitAll[hitID1].driftDistance - hitAll[hitID2].pos - possibility[i][1]*hitAll[hitID2].driftDistance)/(z_plane[hitAll[hitID1].detectorID] - z_plane[hitAll[hitID2].detectorID]); - double intersection_local = hitAll[hitID1].pos + possibility[i][0]*hitAll[hitID1].driftDistance - slope_local*z_plane[hitAll[hitID1].detectorID]; +#ifdef _DEBUG_ON + LogInfo("Hit pairs in this event: "); + //for(std::list::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + //for(std::list::iterator iter = pairs_U.begin(); iter != pairs_U.end(); ++iter) LogInfo("U :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_V.begin(); iter != pairs_V.end(); ++iter) LogInfo("V :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif - //LogInfo(i << " " << nResolved << " " << slope_local << " " << intersection_local); - if(fabs(slope_local) < slope_max[hitAll[hitID1].detectorID] && fabs(intersection_local) < intersection_max[hitAll[hitID1].detectorID]) - { - nResolved++; - LR1 = possibility[i][0]; - LR2 = possibility[i][1]; - } + //if(pairs_X.empty() || pairs_U.empty() || pairs_V.empty()) + if(pairs_V.empty()) + { +#ifdef _DEBUG_ON + LogInfo("Not all view has hits in station " << stationID); +#endif + return; } - if(nResolved > 1) + //X-V combination first, then add V pairs + for(std::list::iterator xiter = pairs_V.begin(); xiter != pairs_V.end(); ++xiter) { - LR1 = 0; - LR2 = 0; + + int LR1 = 0; + int LR2 = 0; + Tracklet tracklet_new; + tracklet_new.stationID = stationID; + + //resolveLeftRight(*xiter, LR1, LR2); + if(xiter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->first], LR1)); + tracklet_new.nVHits++; + } + if(xiter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->second], LR2)); + tracklet_new.nVHits++; + } + if(!OLD_TRACKING){ + tracklet_new.getSlopesV(hitAll[xiter->first], hitAll[xiter->second]); //Here, we find the four possible X-Z lines + } + + tracklet_new.sortHits(); +#ifdef _DEBUG_ON + //std::cout<<"About to print new V tracklet"<::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); - for(std::list::iterator iter = pairs_U.begin(); iter != pairs_U.end(); ++iter) LogInfo("U :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); - for(std::list::iterator iter = pairs_V.begin(); iter != pairs_V.end(); ++iter) LogInfo("V :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + LogInfo("Building withUV tracklets. Hit pairs in this event: "); + //for(std::list::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_U2.begin(); iter != pairs_U2.end(); ++iter) LogInfo("U2 :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_V2.begin(); iter != pairs_V2.end(); ++iter) LogInfo("V2 :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_U3.begin(); iter != pairs_U3.end(); ++iter) LogInfo("U3 :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_V3.begin(); iter != pairs_V3.end(); ++iter) LogInfo("V3 :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); #endif - if(pairs_X.empty() || pairs_U.empty() || pairs_V.empty()) + if(pairs_U2.empty() || pairs_V2.empty() || pairs_U3.empty() || pairs_V3.empty()) { #ifdef _DEBUG_ON LogInfo("Not all view has hits in station " << stationID); @@ -1242,105 +3548,238 @@ void KalmanFastTracking::buildTrackletsInStation(int stationID, int listID, doub } //X-U combination first, then add V pairs - for(std::list::iterator xiter = pairs_X.begin(); xiter != pairs_X.end(); ++xiter) - { - //U projections from X plane - double x_pos = xiter->second >= 0 ? 0.5*(hitAll[xiter->first].pos + hitAll[xiter->second].pos) : hitAll[xiter->first].pos; - double u_min = x_pos*u_costheta[sID] - u_win[sID]; - double u_max = u_min + 2.*u_win[sID]; + //U projections from X plane + double x_pos2 = 0.5*(tracklet23.getHit(0).hit.pos + tracklet23.getHit(1).hit.pos); + double x_pos3 = 0.5*(tracklet23.getHit(2).hit.pos + tracklet23.getHit(3).hit.pos); + //double x_pos = xiter->second >= 0 ? 0.5*(hitAll[xiter->first].pos + hitAll[xiter->second].pos) : hitAll[xiter->first].pos; + double u_min2 = x_pos2*u_costheta[sID2] - u_win[sID2]; + double u_max2 = u_min2 + 2.*u_win[sID2]; #ifdef _DEBUG_ON - LogInfo("Trying X hits " << xiter->first << " " << xiter->second << " " << hitAll[xiter->first].elementID << " at " << x_pos); - LogInfo("U plane window:" << u_min << " " << u_max); + //LogInfo("Trying X hits " << xiter->first << " " << xiter->second << " " << hitAll[xiter->first].elementID << " at " << x_pos); + LogInfo("U2 plane window:" << u_min2 << " " << u_max2); #endif - for(std::list::iterator uiter = pairs_U.begin(); uiter != pairs_U.end(); ++uiter) + for(std::list::iterator uiter2 = pairs_U2.begin(); uiter2 != pairs_U2.end(); ++uiter2) { - double u_pos = uiter->second >= 0 ? 0.5*(hitAll[uiter->first].pos + hitAll[uiter->second].pos) : hitAll[uiter->first].pos; + double u_pos2 = uiter2->second >= 0 ? 0.5*(hitAll[uiter2->first].pos + hitAll[uiter2->second].pos) : hitAll[uiter2->first].pos; #ifdef _DEBUG_ON - LogInfo("Trying U hits " << uiter->first << " " << uiter->second << " " << hitAll[uiter->first].elementID << " at " << u_pos); + LogInfo("Trying U2 hits " << uiter2->first << " " << uiter2->second << " " << hitAll[uiter2->first].elementID << " at " << u_pos2); #endif - if(u_pos < u_min || u_pos > u_max) continue; + if(u_pos2 < u_min2 || u_pos2 > u_max2) continue; //V projections from X and U plane - double z_x = xiter->second >= 0 ? z_plane_x[sID] : z_plane[hitAll[xiter->first].detectorID]; - double z_u = uiter->second >= 0 ? z_plane_u[sID] : z_plane[hitAll[uiter->first].detectorID]; - double z_v = z_plane_v[sID]; - double v_win1 = spacing_plane[hitAll[uiter->first].detectorID]*2.*u_costheta[sID]; - double v_win2 = fabs((z_u + z_v - 2.*z_x)*u_costheta[sID]*TX_MAX); - double v_win3 = fabs((z_v - z_u)*u_sintheta[sID]*TY_MAX); - double v_win = v_win1 + v_win2 + v_win3 + 2.*spacing_plane[hitAll[uiter->first].detectorID]; - double v_min = 2*x_pos*u_costheta[sID] - u_pos - v_win; - double v_max = v_min + 2.*v_win; + //double z_x2 = xiter->second >= 0 ? z_plane_x[sID] : z_plane[hitAll[xiter->first].detectorID]; + double z_x2 = z_plane_x[sID2]; + double z_u2 = uiter2->second >= 0 ? z_plane_u[sID2] : z_plane[hitAll[uiter2->first].detectorID]; + double z_v2 = z_plane_v[sID2]; + double v_win1_2 = spacing_plane[hitAll[uiter2->first].detectorID]*2.*u_costheta[sID2]; + double v_win2_2 = fabs((z_u2 + z_v2 - 2.*z_x2)*u_costheta[sID2]*TX_MAX); + double v_win3_2 = fabs((z_v2 - z_u2)*u_sintheta[sID2]*TY_MAX); + double v_win_2 = v_win1_2 + v_win2_2 + v_win3_2 + 2.*spacing_plane[hitAll[uiter2->first].detectorID]; + double v_min_2 = 2*x_pos2*u_costheta[sID2] - u_pos2 - v_win_2; + double v_max_2 = v_min_2 + 2.*v_win_2; #ifdef _DEBUG_ON - LogInfo("V plane window:" << v_min << " " << v_max); + LogInfo("V2 plane window:" << v_min_2 << " " << v_max_2); #endif - for(std::list::iterator viter = pairs_V.begin(); viter != pairs_V.end(); ++viter) + for(std::list::iterator viter2 = pairs_V2.begin(); viter2 != pairs_V2.end(); ++viter2) { - double v_pos = viter->second >= 0 ? 0.5*(hitAll[viter->first].pos + hitAll[viter->second].pos) : hitAll[viter->first].pos; + double v_pos2 = viter2->second >= 0 ? 0.5*(hitAll[viter2->first].pos + hitAll[viter2->second].pos) : hitAll[viter2->first].pos; #ifdef _DEBUG_ON - LogInfo("Trying V hits " << viter->first << " " << viter->second << " " << hitAll[viter->first].elementID << " at " << v_pos); + LogInfo("Trying V2 hits " << viter2->first << " " << viter2->second << " " << hitAll[viter2->first].elementID << " at " << v_pos2); #endif - if(v_pos < v_min || v_pos > v_max) continue; + if(v_pos2 < v_min_2 || v_pos2 > v_max_2) continue; //Now add the tracklet int LR1 = 0; int LR2 = 0; - Tracklet tracklet_new; - tracklet_new.stationID = stationID; + Tracklet tracklet_new2; + tracklet_new2.stationID = sID2+1; //resolveLeftRight(*xiter, LR1, LR2); - if(xiter->first >= 0) + tracklet_new2.hits.push_back(SignedHit(tracklet23.getHit(0).hit, LR1)); + tracklet_new2.hits.push_back(SignedHit(tracklet23.getHit(1).hit, LR2)); + if(!OLD_TRACKING){ + tracklet_new2.getSlopesX(tracklet23.getHit(0).hit, tracklet23.getHit(1).hit); //Here, we find the four possible X-Z lines + } + //resolveLeftRight(*uiter, LR1, LR2); + if(uiter2->first >= 0) { - tracklet_new.hits.push_back(SignedHit(hitAll[xiter->first], LR1)); - tracklet_new.nXHits++; + tracklet_new2.hits.push_back(SignedHit(hitAll[uiter2->first], LR1)); + tracklet_new2.nUHits++; } - if(xiter->second >= 0) + if(uiter2->second >= 0) { - tracklet_new.hits.push_back(SignedHit(hitAll[xiter->second], LR2)); - tracklet_new.nXHits++; + tracklet_new2.hits.push_back(SignedHit(hitAll[uiter2->second], LR2)); + tracklet_new2.nUHits++; } + if(!OLD_TRACKING){ + tracklet_new2.getSlopesU(hitAll[uiter2->first], hitAll[uiter2->second]); //find the four possible U-Z lines + } - //resolveLeftRight(*uiter, LR1, LR2); - if(uiter->first >= 0) + //resolveLeftRight(*viter, LR1, LR2); + if(viter2->first >= 0) { - tracklet_new.hits.push_back(SignedHit(hitAll[uiter->first], LR1)); - tracklet_new.nUHits++; + tracklet_new2.hits.push_back(SignedHit(hitAll[viter2->first], LR1)); + tracklet_new2.nVHits++; } - if(uiter->second >= 0) + if(viter2->second >= 0) { - tracklet_new.hits.push_back(SignedHit(hitAll[uiter->second], LR2)); - tracklet_new.nUHits++; + tracklet_new2.hits.push_back(SignedHit(hitAll[viter2->second], LR2)); + tracklet_new2.nVHits++; + } + if(!OLD_TRACKING){ + tracklet_new2.getSlopesV(hitAll[viter2->first], hitAll[viter2->second]); //find the four possible V-Z lines + } + + tracklet_new2.sortHits(); + //if(!(tracklet_new2.isValid() == 0)) //TODO: What IS THIS? + //{ + // continue; + //} + /* + { + //fitTracklet(tracklet_new); //This is where the original DCA minimization is performed } + else + { + continue; + }*/ - //resolveLeftRight(*viter, LR1, LR2); - if(viter->first >= 0) +#ifdef _DEBUG_ON + //std::cout<<"OK HERE'S A STATION 2 TRACKLET:"<first << " " << xiter->second << " " << hitAll[xiter->first].elementID << " at " << x_pos); + LogInfo("U3 plane window:" << u_min3 << " " << u_max3); +#endif + for(std::list::iterator uiter3 = pairs_U3.begin(); uiter3 != pairs_U3.end(); ++uiter3) + { + double u_pos3 = uiter3->second >= 0 ? 0.5*(hitAll[uiter3->first].pos + hitAll[uiter3->second].pos) : hitAll[uiter3->first].pos; +#ifdef _DEBUG_ON + LogInfo("Trying U3 hits " << uiter3->first << " " << uiter3->second << " " << hitAll[uiter3->first].elementID << " at " << u_pos3); +#endif + if(u_pos3 < u_min3 || u_pos3 > u_max3) continue; + + //V projections from X and U plane + //double z_x3 = xiter->second >= 0 ? z_plane_x[sID] : z_plane[hitAll[xiter->first].detectorID]; + double z_x3 = z_plane_x[sID3]; + double z_u3 = uiter3->second >= 0 ? z_plane_u[sID3] : z_plane[hitAll[uiter3->first].detectorID]; + double z_v3 = z_plane_v[sID3]; + double v_win1_3 = spacing_plane[hitAll[uiter3->first].detectorID]*2.*u_costheta[sID3]; + double v_win2_3 = fabs((z_u3 + z_v3 - 2.*z_x3)*u_costheta[sID3]*TX_MAX); + double v_win3_3 = fabs((z_v3 - z_u3)*u_sintheta[sID3]*TY_MAX); + double v_win_3 = v_win1_3 + v_win2_3 + v_win3_3 + 2.*spacing_plane[hitAll[uiter3->first].detectorID]; + double v_min_3 = 2*x_pos3*u_costheta[sID3] - u_pos3 - v_win_3; + double v_max_3 = v_min_3 + 2.*v_win_3; + +#ifdef _DEBUG_ON + LogInfo("V3 plane window:" << v_min_3 << " " << v_max_3); +#endif + for(std::list::iterator viter3 = pairs_V3.begin(); viter3 != pairs_V3.end(); ++viter3) + { + double v_pos3 = viter3->second >= 0 ? 0.5*(hitAll[viter3->first].pos + hitAll[viter3->second].pos) : hitAll[viter3->first].pos; +#ifdef _DEBUG_ON + LogInfo("Trying V3 hits " << viter3->first << " " << viter3->second << " " << hitAll[viter3->first].elementID << " at " << v_pos3); +#endif + if(v_pos3 < v_min_3 || v_pos3 > v_max_3) continue; + + //Now add the tracklet + //int LR1 = 0; + //int LR2 = 0; + Tracklet tracklet_new3; + tracklet_new3.stationID = sID3+1; + + //resolveLeftRight(*xiter, LR1, LR2); + tracklet_new3.hits.push_back(SignedHit(tracklet23.getHit(2).hit,LR1)); + tracklet_new3.hits.push_back(SignedHit(tracklet23.getHit(3).hit,LR2)); + if(!OLD_TRACKING){ + tracklet_new3.getSlopesX(tracklet23.getHit(2).hit, tracklet23.getHit(3).hit); //Here, we find the four possible X-Z lines + } + //resolveLeftRight(*uiter, LR1, LR2); + if(uiter3->first >= 0) { - tracklet_new.hits.push_back(SignedHit(hitAll[viter->first], LR1)); - tracklet_new.nVHits++; + tracklet_new3.hits.push_back(SignedHit(hitAll[uiter3->first], LR1)); + tracklet_new3.nUHits++; } - if(viter->second >= 0) + if(uiter3->second >= 0) { - tracklet_new.hits.push_back(SignedHit(hitAll[viter->second], LR2)); - tracklet_new.nVHits++; + tracklet_new3.hits.push_back(SignedHit(hitAll[uiter3->second], LR2)); + tracklet_new3.nUHits++; } + if(!OLD_TRACKING){ + tracklet_new3.getSlopesU(hitAll[uiter3->first], hitAll[uiter3->second]); //find the four possible U-Z lines + } - tracklet_new.sortHits(); - if(tracklet_new.isValid() == 0) //TODO: What IS THIS? + //resolveLeftRight(*viter, LR1, LR2); + if(viter3->first >= 0) { - fitTracklet(tracklet_new); + tracklet_new3.hits.push_back(SignedHit(hitAll[viter3->first], LR1)); + tracklet_new3.nVHits++; } - else + if(viter3->second >= 0) { - continue; + tracklet_new3.hits.push_back(SignedHit(hitAll[viter3->second], LR2)); + tracklet_new3.nVHits++; } + if(!OLD_TRACKING){ + tracklet_new3.getSlopesV(hitAll[viter3->first], hitAll[viter3->second]); //find the four possible V-Z lines + } + + tracklet_new3.sortHits(); + //if(!(tracklet_new3.isValid() == 0)) //TODO: What IS THIS? + //{ + // continue; + //} #ifdef _DEBUG_ON - tracklet_new.print(); + //std::cout<<"OK HERE'S A STATION 3 TRACKLET:"< 9000.) + { +#ifdef _DEBUG_ON + tracklet_new_23.print(); + LogInfo("Impossible combination!"); +#endif + continue; + } + + + if(acceptTracklet(tracklet_new_23)) { - trackletsInSt[listID].push_back(tracklet_new); + if(tracklet_new_23 < tracklet_best){ + tracklet_best = tracklet_new_23; + } + //trackletsInSt[listID].push_back(tracklet_new_23); } #ifdef _DEBUG_ON else @@ -1350,8 +3789,12 @@ void KalmanFastTracking::buildTrackletsInStation(int stationID, int listID, doub #endif } } - } + } + } + if(acceptTracklet(tracklet_best)){ + trackletsInSt[listID].push_back(tracklet_best); + } //Reduce the tracklet list and add dummy hits //reduceTrackletList(trackletsInSt[listID]); for(std::list::iterator iter = trackletsInSt[listID].begin(); iter != trackletsInSt[listID].end(); ++iter) @@ -1360,13 +3803,15 @@ void KalmanFastTracking::buildTrackletsInStation(int stationID, int listID, doub } //Only retain the best 200 tracklets if exceeded - if(trackletsInSt[listID].size() > 200) + //std::cout<<"NUMBER of tracklets before resize = "< 1000) { trackletsInSt[listID].sort(); - trackletsInSt[listID].resize(200); + trackletsInSt[listID].resize(1000); } } + bool KalmanFastTracking::acceptTracklet(Tracklet& tracklet) { //Tracklet itself is okay with enough hits (4-out-of-6) and small chi square @@ -1379,7 +3824,7 @@ bool KalmanFastTracking::acceptTracklet(Tracklet& tracklet) } if(COARSE_MODE) return true; - + /* //Hodoscope masking requirement if(!hodoMask(tracklet)) return false; @@ -1391,8 +3836,13 @@ bool KalmanFastTracking::acceptTracklet(Tracklet& tracklet) if(TRACK_ELECTRONS && !(muonID_comp(tracklet) || muonID_search(tracklet) || tracklet.stationID > 5)){ return false; } - } + }*/ //WPM + +#ifdef _DEBUG_ON + LogInfo("Made it through various checks"); +#endif + //If everything is fine ... #ifdef _DEBUG_ON LogInfo("AcceptTracklet!!!"); @@ -1403,8 +3853,42 @@ bool KalmanFastTracking::acceptTracklet(Tracklet& tracklet) bool KalmanFastTracking::hodoMask(Tracklet& tracklet) { //LogInfo(tracklet.stationID); - if(TRACK_ELECTRONS && (tracklet.stationID == 4 || tracklet.stationID == 5)) return true; //Patrick's skip of hodoscope checks for station 3 tracks in the electron-tracking setup - int nHodoHits = 0; + if(TRACK_ELECTRONS && (tracklet.stationID == 4 || tracklet.stationID == 5)) return true; //Patrick's skip of hodoscope checks for station 3 tracks in the electron-tracking setup. I could actually probably extrapolate backwards the station 2 hodoscope, now that I get an accurate X-Z slope in station 3 + int nHodoHits = 0; + if(!OLD_TRACKING){ + //Performing a valid extrapolation in X-Z for station 2 tracklets. This should be improved. Currently carries around the old fudge factor + if(tracklet.stationID == 3){ + for(std::vector::iterator stationID = stationIDs_mask[tracklet.stationID-1].begin(); stationID != stationIDs_mask[tracklet.stationID-1].end(); ++stationID){ + bool masked = false; + for(std::list::iterator iter = hitIDs_mask[*stationID-1].begin(); iter != hitIDs_mask[*stationID-1].end(); ++iter){ + int detectorID = hitAll[*iter].detectorID; + int elementID = hitAll[*iter].elementID; + + int idx1 = detectorID - nChamberPlanes - 1; + int idx2 = elementID - 1; + + double factor = tracklet.stationID == nChamberPlanes/6-2 ? 5. : 3.; //special for station-2, based on real data tuning + double xfudge = tracklet.stationID < nStations-1 ? 0.5*(x_mask_max[idx1][idx2] - x_mask_min[idx1][idx2]) : 0.15*(x_mask_max[idx1][idx2] - x_mask_min[idx1][idx2]); + double z_hodo = z_mask[idx1]; + + for(unsigned int pl = 0; pl < tracklet.possibleXLines.size(); pl++){ + double extrapolation = tracklet.possibleXLines.at(pl).slopeX*(z_hodo - tracklet.possibleXLines.at(pl).initialZ) + tracklet.possibleXLines.at(pl).initialX; + double err_x = std::abs(factor*extrapolation + xfudge); + double x_min = x_mask_min[idx1][idx2] - err_x; + double x_max = x_mask_max[idx1][idx2] + err_x; + if(extrapolation > x_min && extrapolation < x_max){ + masked = true; + break; + } + } + } + if(!masked) return false; + } + } + } + + if(tracklet.stationID > 5){ + for(std::vector::iterator stationID = stationIDs_mask[tracklet.stationID-1].begin(); stationID != stationIDs_mask[tracklet.stationID-1].end(); ++stationID) { bool masked = false; @@ -1447,6 +3931,7 @@ bool KalmanFastTracking::hodoMask(Tracklet& tracklet) if(!masked) return false; } + } #ifdef _DEBUG_ON LogInfo(tracklet.stationID << " " << nHodoHits << " " << stationIDs_mask[tracklet.stationID-1].size()); @@ -1647,7 +4132,7 @@ void KalmanFastTracking::buildPropSegments() std::list pairs_backward = rawEvent->getPartialHitPairsInSuperDetector(superIDs[i+5][1]); #ifdef _DEBUG_ON - std::cout << "superID: " << superIDs[i+5][0] << ", " << superIDs[i+5][1] << std::endl; + //std::cout << "superID: " << superIDs[i+5][0] << ", " << superIDs[i+5][1] << std::endl; for(std::list::iterator iter = pairs_forward.begin(); iter != pairs_forward.end(); ++iter) LogInfo("Forward: " << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); for(std::list::iterator iter = pairs_backward.begin(); iter != pairs_backward.end(); ++iter) @@ -1707,12 +4192,16 @@ int KalmanFastTracking::fitTracklet(Tracklet& tracklet) if(tracklet.stationID < nStations-1) idx = 0; #endif + //std::cout<<"in fitTracklet :(. invP = "<SetLimitedVariable(0, "tx", tracklet.tx, 0.001, -TX_MAX, TX_MAX); minimizer[idx]->SetLimitedVariable(1, "ty", tracklet.ty, 0.001, -TY_MAX, TY_MAX); minimizer[idx]->SetLimitedVariable(2, "x0", tracklet.x0, 0.1, -X0_MAX, X0_MAX); minimizer[idx]->SetLimitedVariable(3, "y0", tracklet.y0, 0.1, -Y0_MAX, Y0_MAX); if(KMAG_ON) { + //std::cout<<"hello now invp = "<Minimize(); @@ -1727,6 +4216,8 @@ int KalmanFastTracking::fitTracklet(Tracklet& tracklet) tracklet.err_x0 = minimizer[idx]->Errors()[2]; tracklet.err_y0 = minimizer[idx]->Errors()[3]; + //std::cout<<"in fitTracklet :(. KMAG_ON = "< 0.007) return false; //This has not been optimized at all. I just chose a random value (previous slope comparison allowed for a difference of 0.1) + double extrapolation = line2X.slopeX*(line3X.initialZ - line2X.initialZ) + line2X.initialX; + + if(std::abs(extrapolation - line3X.initialX) > 7. ){ //allow for a 5 cm difference of the tracklet in station 3 from the station 2 extrapolation. This also should be optimized + if(secondSlope > 0.007) return false; //If both the closest and second closest slopes don't match, then this is not a good combination + double extrapolation_v2 = line2X_v2.slopeX*(line3X_v2.initialZ - line2X_v2.initialZ) + line2X_v2.initialX; //Perform the extrapolation in the rare case that the closest slope combination did not yield a valid extrapolation. Rare, but necessary + if(std::abs(extrapolation_v2 - line3X_v2.initialX) > 7. ){ //Same window size! Could be optimized + return false; + } else{ + line2X = line2X_v2; //These are the possible X-Z lines that we actually want, if the closest combination wasn't valid based on the extrapolation + line3X = line3X_v2; + } + } + + + //Here we will compare the possible X-Z slopes within the station 2 and station 3 tracklets + Tracklet::linedef line2U; + Tracklet::linedef line3U; + Tracklet::linedef line2U_v2; + Tracklet::linedef line3U_v2; + + //It is rare, but sometimes, you will have slopes that match coincidentally. Therefore, I keep track of best two combinations. This seems to be sufficienct + double slopeCompU = 1.0; + double secondSlopeU = 1.1; + for(unsigned int t2 = 0; t2 < tracklet2.possibleULines.size(); t2++){ + for(unsigned int t3 = 0; t3 < tracklet3.possibleULines.size(); t3++){ + if(std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU) < slopeCompU){ + + //if the new combination is the closest so far, then the previous closest becomes the second closest... + secondSlopeU = slopeCompU; + line2U_v2 = line2U; + line3U_v2 = line3U; + + slopeCompU = std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU); + line2U = tracklet2.possibleULines.at(t2); + line3U = tracklet3.possibleULines.at(t3); + } + else if(std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU) < secondSlopeU){ + //not as close as the closest combination, but closer than the previously existing second combination + secondSlopeU = std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU); + line2U_v2 = tracklet2.possibleULines.at(t2); + line3U_v2 = tracklet3.possibleULines.at(t3); + } + } + } + + if(slopeCompU > 0.005) return false; //This has not been optimized at all. I just chose a random value (previous slope comparison allowed for a difference of 0.1) + double extrapolationU = line2U.slopeU*(line3U.initialZ - line2U.initialZ) + line2U.initialU; + + if(std::abs(extrapolationU - line3U.initialU) > 7. ){ //allow for a 5 cm difference of the tracklet in station 3 from the station 2 extrapolation. This also should be optimized + if(secondSlopeU > 0.005) return false; //If both the closest and second closest slopes don't match, then this is not a good combination + double extrapolationU_v2 = line2U_v2.slopeU*(line3U_v2.initialZ - line2U_v2.initialZ) + line2U_v2.initialU; //Perform the extrapolation in the rare case that the closest slope combination did not yield a valid extrapolation. Rare, but necessary + if(std::abs(extrapolationU_v2 - line3U_v2.initialU) > 7. ){ //Same window size! Could be optimized + return false; + } else{ + line2U = line2U_v2; //These are the possible X-Z lines that we actually want, if the closest combination wasn't valid based on the extrapolation + line3U = line3U_v2; + } + } + + + + //Here we will compare the possible X-Z slopes within the station 2 and station 3 tracklets + Tracklet::linedef line2V; + Tracklet::linedef line3V; + Tracklet::linedef line2V_v2; + Tracklet::linedef line3V_v2; + + //It is rare, but sometimes, you will have slopes that match coincidentally. Therefore, I keep track of best two combinations. This seems to be sufficienct + double slopeCompV = 1.0; + double secondSlopeV = 1.1; + for(unsigned int t2 = 0; t2 < tracklet2.possibleVLines.size(); t2++){ + for(unsigned int t3 = 0; t3 < tracklet3.possibleVLines.size(); t3++){ + if(std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV) < slopeCompV){ + + //if the new combination is the closest so far, then the previous closest becomes the second closest... + secondSlopeV = slopeCompV; + line2V_v2 = line2V; + line3V_v2 = line3V; + + slopeCompV = std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV); + line2V = tracklet2.possibleVLines.at(t2); + line3V = tracklet3.possibleVLines.at(t3); + } + else if(std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV) < secondSlopeV){ + //not as close as the closest combination, but closer than the previously existing second combination + secondSlopeV = std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV); + line2V_v2 = tracklet2.possibleVLines.at(t2); + line3V_v2 = tracklet3.possibleVLines.at(t3); + } + } + } + + if(slopeCompV > 0.005) return false; //This has not been optimized at all. I just chose a random value (previous slope comparison allowed for a difference of 0.1) + double extrapolationV = line2V.slopeV*(line3V.initialZ - line2V.initialZ) + line2V.initialV; + + if(std::abs(extrapolationV - line3V.initialV) > 5. ){ //allow for a 5 cm difference of the tracklet in station 3 from the station 2 extrapolation. This also should be optimized + if(secondSlopeV > 0.005) return false; //If both the closest and second closest slopes don't match, then this is not a good combination + double extrapolationV_v2 = line2V_v2.slopeV*(line3V_v2.initialZ - line2V_v2.initialZ) + line2V_v2.initialV; //Perform the extrapolation in the rare case that the closest slope combination did not yield a valid extrapolation. Rare, but necessary + if(std::abs(extrapolationV_v2 - line3V_v2.initialV) > 5. ){ //Same window size! Could be optimized + return false; + } else{ + line2V = line2V_v2; //These are the possible X-Z lines that we actually want, if the closest combination wasn't valid based on the extrapolation + line3V = line3V_v2; + } + } + + /* + Tracklet::linedef line2U; + Tracklet::linedef line3U; + double slopeCompU = 1.0; + for(unsigned int t2 = 0; t2 < tracklet2.possibleULines.size(); t2++){ + for(unsigned int t3 = 0; t3 < tracklet3.possibleULines.size(); t3++){ + if(std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU) < slopeCompU){ + slopeCompU = std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU); + line2U = tracklet2.possibleULines.at(t2); + line3U = tracklet3.possibleULines.at(t3); + } + } + } //As of now, I don't keep track of the second-closest combination for the U and V layers + + if(slopeCompU > 0.005) return false; //Larger window here. From what I can tell, the resolution is worse in this plane, or maybe my slope calculations are somewhat incorrect + + Tracklet::linedef line2V; + Tracklet::linedef line3V; + double slopeCompV = 1.0; + for(unsigned int t2 = 0; t2 < tracklet2.possibleVLines.size(); t2++){ + for(unsigned int t3 = 0; t3 < tracklet3.possibleVLines.size(); t3++){ + if(std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV) < slopeCompV){ + slopeCompV = std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV); + line2V = tracklet2.possibleVLines.at(t2); + line3V = tracklet3.possibleVLines.at(t3); + } + } + } + + if(slopeCompV > 0.005) return false; //same comment about resolution as for the U layer +*/ + //Now we find the Y-values of the hits in the U and V planes + double tracklet2Ys_D = 0.; //This is the sum of the Y-values of the hits in the U and V planes of the two tracklets. The sum is taken to be used in an average. The _D here stands for driftDistance. I originally did this part of the code without taking the drift distance in the slanted layers into account + double tracklet3Ys_D = 0.; + tracklet2Ys_D += line2V.wire1Slope * (line2X.slopeX*(line2V.wireHit1PosZ - line2X.initialZ) + line2X.initialX) + line2V.wireIntercept1; + tracklet2Ys_D += line2V.wire2Slope * (line2X.slopeX*(line2V.wireHit2PosZ - line2X.initialZ) + line2X.initialX) + line2V.wireIntercept2; + tracklet2Ys_D += line2U.wire1Slope * (line2X.slopeX*(line2U.wireHit1PosZ - line2X.initialZ) + line2X.initialX) + line2U.wireIntercept1; + tracklet2Ys_D += line2U.wire2Slope * (line2X.slopeX*(line2U.wireHit2PosZ - line2X.initialZ) + line2X.initialX) + line2U.wireIntercept2; + + //std::cout<<"In COMPARETRACKLETS. st2 v wire y's are "< 0.005 ) return false; + if( std::abs(st2VWireCos*tracklet2.tx - st2VWireSin*tracklet2.ty - line2V.slopeV) > 0.005 ) return false; + if( std::abs(st3UWireCos*tracklet3.tx - st3UWireSin*tracklet3.ty - line3U.slopeU) > 0.005 ) return false; + if( std::abs(st3VWireCos*tracklet3.tx - st3VWireSin*tracklet3.ty - line3V.slopeV) > 0.005 ) return false; + + //std::cout<<"pass serious comparison"< slopeWindow) return false; //This has not been optimized at all. I just chose a random value (previous slope comparison allowed for a difference of 0.1) + double extrapolation = line2X.slopeX*(line3X.initialZ - line2X.initialZ) + line2X.initialX; + double extrapolation_toSt1 = line2X.slopeX*(z_plane[3] - line2X.initialZ) + line2X.initialX; + //std::cout<<"extrapolation is "< extrapoWindow || std::abs(extrapolation_toSt1) > 100. ){ //allow for a 5 cm difference of the tracklet in station 3 from the station 2 extrapolation. This also should be optimized + if(secondSlope > slopeWindow) return false; //If both the closest and second closest slopes don't match, then this is not a good combination + double extrapolation_v2 = line2X_v2.slopeX*(line3X_v2.initialZ - line2X_v2.initialZ) + line2X_v2.initialX; //Perform the extrapolation in the rare case that the closest slope combination did not yield a valid extrapolation. Rare, but necessary + double extrapolation_toSt1_v2 = line2X_v2.slopeX*(z_plane[3] - line2X_v2.initialZ) + line2X_v2.initialX; + //std::cout<<"V2 extrapolation is "< extrapoWindow || std::abs(extrapolation_toSt1_v2) > 100. ){ //Same window size! Could be optimized + return false; + } else{ + line2X = line2X_v2; //These are the possible X-Z lines that we actually want, if the closest combination wasn't valid based on the extrapolation + line3X = line3X_v2; + choiceOfT2 = choiceOfT2_v2; + choiceOfT3 = choiceOfT3_v2; + } + } + + tracklet2.acceptedXLine2 = line2X; + tracklet3.acceptedXLine3 = line3X; + //Give the station 2 and station 3 tracklets the same tx and ty value. I could get an X0 and Y0 extrapolation, but that doesn't seem to be strictly necessary. The X0 and Y0 values are found in the fittracklet function for the combined station 2 + station 3 tracklet + tracklet2.tx = (line2X.slopeX + line3X.slopeX)/2; + //tracklet2.ty = (tracklet3Ys_D/4. - tracklet2Ys_D/4.)/(line3U.wireHit1PosZ - line2V.wireHit1PosZ); //The y slope is found by taking the average Y position in the station3 and subtracting the average Y position in station2. This is then divided by the z difference, of course + tracklet3.tx = (line2X.slopeX + line3X.slopeX)/2; + //tracklet3.ty = (tracklet3Ys_D/4. - tracklet2Ys_D/4.)/(line3U.wireHit1PosZ - line2V.wireHit1PosZ); + + tracklet2.st2Z = line2X.initialZ; + tracklet2.st2X = line2X.initialX; + tracklet3.st2Z = line3X.initialZ; + tracklet3.st2X = line3X.initialX; + + tracklet2.st2Xsl = line2X.slopeX; + tracklet3.st2Xsl = line3X.slopeX; + + //std::cout<<"THERE WAS A TRACKLET MATCH!"< slopeWindow) return false; //This has not been optimized at all. I just chose a random value (previous slope comparison allowed for a difference of 0.1) + + if(std::abs(extrapolation - line3U.initialU) > extrapoWindow || std::abs(extrapolation_toSt1) > 100. || std::abs(line3U.slopeU) > 0.15 || std::abs(line2U.slopeU) > 0.15 ){ //allow for a 5 cm difference of the tracklet in station 3 from the station 2 extrapolation. This also should be optimized + if(secondSlope > slopeWindow) return false; //If both the closest and second closest slopes don't match, then this is not a good combination + + if(std::abs(extrapolation_v2 - line3U_v2.initialU) > extrapoWindow || std::abs(extrapolation_toSt1_v2) > 100. || std::abs(line3U_v2.slopeU) > 0.15 || std::abs(line2U_v2.slopeU) > 0.15 ){ //Same window size! Could be optimized + return false; + } else{ + line2U = line2U_v2; //These are the possible U-Z lines that we actually want, if the closest combination wasn't valid based on the extrapolation + line3U = line3U_v2; + choiceOfT2 = choiceOfT2_v2; + choiceOfT3 = choiceOfT3_v2; + } + } + + tracklet2.acceptedULine2 = line2U; + tracklet3.acceptedULine3 = line3U; + + //Give the station 2 and station 3 tracklets the same tx and ty value. I could get an X0 and Y0 extrapolation, but that doesn't seem to be strictly necessary. The X0 and Y0 values are found in the fittracklet function for the combined station 2 + station 3 tracklet + //tracklet2.tx = (line2X.slopeX + line3X.slopeX)/2; + //tracklet2.ty = (tracklet3Ys_D/4. - tracklet2Ys_D/4.)/(line3U.wireHit1PosZ - line2V.wireHit1PosZ); //The y slope is found by taking the average Y position in the station3 and subtracting the average Y position in station2. This is then divided by the z difference, of course + //tracklet3.tx = (line2X.slopeX + line3X.slopeX)/2; + //tracklet3.ty = (tracklet3Ys_D/4. - tracklet2Ys_D/4.)/(line3U.wireHit1PosZ - line2V.wireHit1PosZ); + + tracklet2.st2Z = line2U.initialZ; + tracklet2.st2U = line2U.initialU; + tracklet3.st2Z = line3U.initialZ; + tracklet3.st2U = line3U.initialU; + + tracklet2.st2Usl = line2U.slopeU; + tracklet3.st2Usl = line3U.slopeU; + + //std::cout<<"THERE WAS A U TRACKLET MATCH!"< slopeWindow) return false; //This has not been optimized at all. I just chose a random value (previous slope comparison allowed for a difference of 0.1) + + if(std::abs(extrapolation - line3V.initialV) > extrapoWindow || std::abs(extrapolation_toSt1) > 100. || std::abs(line3V.slopeV) > 0.15 || std::abs(line2V.slopeV) > 0.15 ){ //allow for a 5 cm difference of the tracklet in station 3 from the station 2 extrapolation. This also should be optimized + if(secondSlope > slopeWindow) return false; //If both the closest and second closest slopes don't match, then this is not a good combination + + if(std::abs(extrapolation_v2 - line3V_v2.initialV) > extrapoWindow || std::abs(extrapolation_toSt1_v2) > 100. || std::abs(line3V_v2.slopeV) > 0.15 || std::abs(line2V_v2.slopeV) > 0.15 ){ //Same window size! Could be optimized + return false; + } else{ + line2V = line2V_v2; //These are the possible V-Z lines that we actually want, if the closest combination wasn't valid based on the extrapolation + line3V = line3V_v2; + choiceOfT2 = choiceOfT2_v2; + choiceOfT3 = choiceOfT3_v2; + } + } + + tracklet2.acceptedVLine2 = line2V; + //std::cout<<"TEST OF LINE2 "<::iterator iter = tracklet2.hits.begin(); iter != tracklet2.hits.end(); ++iter) + { + if(iter->sign > 0) std::cout << "L: "; + if(iter->sign < 0) std::cout << "R: "; + if(iter->sign == 0) std::cout << "U: "; + + std::cout << iter->hit.index << " " << p_geomSvc->getDetectorName(iter->hit.detectorID) << "(" << iter->hit.detectorID << ") " << iter->hit.elementID << " = "; + } + std::cout<::iterator iter = tracklet3.hits.begin(); iter != tracklet3.hits.end(); ++iter) + { + if(iter->sign > 0) std::cout << "L: "; + if(iter->sign < 0) std::cout << "R: "; + if(iter->sign == 0) std::cout << "U: "; + + std::cout << iter->hit.index << " " << p_geomSvc->getDetectorName(iter->hit.detectorID) << "(" << iter->hit.detectorID << ") " << iter->hit.elementID << " = "; + } + std::cout<::iterator iter2 = tracklet2.hits.begin(); iter2 != tracklet2.hits.end(); ++iter2){ + for(std::list::iterator iter3 = tracklet3.hits.begin(); iter3 != tracklet3.hits.end(); ++iter3){ + if( iter2->hit.index != iter3->hit.index || iter2->hit.detectorID != iter3->hit.detectorID || iter2->hit.elementID != iter3->hit.elementID ){ + sameTracklet = false; + break; + } + } + if(!sameTracklet) break; + } + + if(sameTracklet){ + std::cout<<"these are the same tracklet"<tx * ( z_plane[3] - tracklet23->st2Z ) + tracklet23->st2X; //WPM pick up here. do u and v extrapolations + //double posu = tracklet23->st2Usl * ( z_plane[1] - tracklet23->st2Z ) + tracklet23->st2U; //WPM + //double posv = tracklet23->st2Vsl * ( z_plane[5] - tracklet23->st2Z ) + tracklet23->st2V; //WPM + //double posy = tracklet23->ty * ( z_plane[3] - tracklet23->st2Z ) + tracklet23->st2Y; //WPM + + pos_exp[0] = posx+charges[ch]*pxSlices[pxs]; + pos_exp[1] = p_geomSvc->getCostheta(1) * pos_exp[0] + p_geomSvc->getSintheta(1) * posy; + pos_exp[2] = p_geomSvc->getCostheta(5) * pos_exp[0] + p_geomSvc->getSintheta(5) * posy; + */ + std::vector u_layers = {17, 18, 23, 24, 29, 30}; + std::vector v_layers = {13, 14, 19, 20, 25, 26}; + + double posx; + double posy; + double expU; + for(int l = 0; lgetCostheta(1) * posx + p_geomSvc->getSintheta(u_layers.at(l)) * posy; + for(unsigned int h = 0; h < tracklet23.hits.size(); h++){ + if(tracklet23.getHit(h).hit.detectorID == u_layers.at(l)){ + if( std::abs(expU - tracklet23.getHit(h).hit.pos) > 3.1 ){ + acceptableTracklet = false; + return false; + } + } + } + } + + double expV; + for(int l = 0; lgetCostheta(1) * posx + p_geomSvc->getSintheta(v_layers.at(l)) * posy; + for(unsigned int h = 0; h < tracklet23.hits.size(); h++){ + if(tracklet23.getHit(h).hit.detectorID == v_layers.at(l)){ + if( std::abs(expV - tracklet23.getHit(h).hit.pos) > 3.1 ){ + acceptableTracklet = false; + return false; + } + } + } + } + + + return acceptableTracklet; +} diff --git a/packages/reco/ktracker/KalmanFastTracking.h b/packages/reco/ktracker/KalmanFastTracking.h index 1a029273..abeb599c 100644 --- a/packages/reco/ktracker/KalmanFastTracking.h +++ b/packages/reco/ktracker/KalmanFastTracking.h @@ -21,6 +21,8 @@ Created: 05-24-2013 #include #include +#include "TMathBase.h" + #include "SRawEvent.h" #include "KalmanTrack.h" #include "KalmanFitter.h" @@ -52,13 +54,27 @@ class KalmanFastTracking ///Tracklet finding stuff //Build tracklets in a station void buildTrackletsInStation(int stationID, int listID, double* pos_exp = nullptr, double* window = nullptr); + void buildTrackletsInStationSlim(int stationID, int listID, double* pos_exp = nullptr, double* window = nullptr); + void buildTrackletsInStationSlimU(int stationID, int listID, double* pos_exp = nullptr, double* window = nullptr); + void buildTrackletsInStationSlimV(int stationID, int listID, double* pos_exp = nullptr, double* window = nullptr); + bool buildTrackletsInStation1(int stationID, int listID, double expXZSlope, double* pos_exp = nullptr, double* window = nullptr); + void buildTrackletsInStation1X(int stationID, int listID, double* pos_exp = nullptr, double* window = nullptr); + void buildTrackletsInStationWithUV(int stationID, int listID, Tracklet& tracklet23, double* pos_exp = nullptr, double* window = nullptr); //Build back partial tracks using tracklets in station 2 & 3 void buildBackPartialTracks(); + void buildBackPartialTracksSlim(); + void buildBackPartialTracksSlim_v2(); + void buildBackPartialTracksSlimX(int pass); + void buildBackPartialTracksSlimU(int pass); + void buildBackPartialTracksSlimV(int pass); //Build global tracks by connecting station 23 tracklets and station 1 tracklets void buildGlobalTracks(); + //Build global tracks by connecting station 23 tracklets and station 1 tracklets + void buildGlobalTracksDisplaced(); + //Fit tracklets int fitTracklet(Tracklet& tracklet); @@ -69,6 +85,21 @@ class KalmanFastTracking bool muonID_search(Tracklet& tracklet); bool muonID_hodoAid(Tracklet& tracklet); + bool compareTracklets(Tracklet& tracklet1, Tracklet& tracklet2); + bool compareTrackletsSlim(Tracklet& tracklet1, Tracklet& tracklet2, int pass); + bool compareTrackletsSlimU(Tracklet& tracklet1, Tracklet& tracklet2, int pass); + bool compareTrackletsSlimV(Tracklet& tracklet1, Tracklet& tracklet2, int pass); + + bool compareTrackletsSerious(Tracklet& tracklet1, Tracklet& tracklet2); + + bool compareTracklets_v2(Tracklet& tracklet1, Tracklet& tracklet2); + bool compareTrackletsSlim_v2(Tracklet& tracklet1, Tracklet& tracklet2, int pass); + bool compareTrackletsSlimU_v2(Tracklet& tracklet1, Tracklet& tracklet2, int pass); + bool compareTrackletsSlimV_v2(Tracklet& tracklet1, Tracklet& tracklet2, int pass); + + bool checkTwoTracklets(Tracklet& tracklet1, Tracklet& tracklet2); + bool checkSingleTracklet(Tracklet& tracklet1); + void buildPropSegments(); //Resolve left-right when possible @@ -123,6 +154,9 @@ class KalmanFastTracking //Tracklets in one event, id = 0, 1, 2 for station 0/1, 2, 3+/-, id = 3 for station 2&3 combined, id = 4 for global tracks //Likewise for the next part std::list trackletsInSt[5]; + std::list trackletsInStSlimX[5]; + std::list trackletsInStSlimU[5]; + std::list trackletsInStSlimV[5]; //Final SRecTrack list std::list stracks; diff --git a/packages/reco/ktracker/KalmanFastTracking_NEW.cxx b/packages/reco/ktracker/KalmanFastTracking_NEW.cxx new file mode 100644 index 00000000..f1831d36 --- /dev/null +++ b/packages/reco/ktracker/KalmanFastTracking_NEW.cxx @@ -0,0 +1,6814 @@ +/* +KalmanFastTracking_NEW.cxx + +Implementation of class Tracklet, KalmanFastTracking_NEW + +Author: Kun Liu, liuk@fnal.gov +Created: 05-28-2013 +*/ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "KalmanFastTracking_NEW.h" +#include "TriggerRoad.h" + +#define _DEBUG_ON +#define _DEBUG_PATRICK +#define _DEBUG_PATRICK_EXTRA + +namespace +{ + //static flag to indicate the initialized has been done + static bool inited = false; + + //Event acceptance cut + static int MaxHitsDC0; + static int MaxHitsDC1; + static int MaxHitsDC2; + static int MaxHitsDC3p; + static int MaxHitsDC3m; + + //Sagitta ratio + static double SAGITTA_DUMP_CENTER; + static double SAGITTA_DUMP_WIDTH; + static double SAGITTA_TARGET_CENTER; + static double SAGITTA_TARGET_WIDTH; + static double Z_TARGET; + static double Z_DUMP; + + //Track quality cuts + static double TX_MAX; + static double TY_MAX; + static double X0_MAX; + static double Y0_MAX; + static double INVP_MAX; + static double INVP_MIN; + static double Z_KMAG_BEND; + + //MuID cuts + static double MUID_REJECTION; + static double MUID_Z_REF; + static double MUID_R_CUT; + static double MUID_THE_P0; + static double MUID_EMP_P0; + static double MUID_EMP_P1; + static double MUID_EMP_P2; + static int MUID_MINHITS; + + //Track merging threshold + static double MERGE_THRES; + + //static flag of kmag on/off + static bool KMAG_ON; + + //running mode + static bool MC_MODE; + static bool COSMIC_MODE; + static bool COARSE_MODE; + + //if displaced, skip fit to the target/vertex + static bool NOT_DISPLACED; + static bool TRACK_ELECTRONS; //please see comment in framework/phool/recoConsts.cc + static bool TRACK_DISPLACED; //please see comment in framework/phool/recoConsts.cc + static bool OLD_TRACKING; //please see comment in framework/phool/recoConsts.cc + + static double KMAGSTR; + static double PT_KICK_KMAG; + + //initialize global variables + void initGlobalVariables() + { + if(!inited) + { + inited = true; + + recoConsts* rc = recoConsts::instance(); + MC_MODE = rc->get_BoolFlag("MC_MODE"); + KMAG_ON = rc->get_BoolFlag("KMAG_ON"); + COSMIC_MODE = rc->get_BoolFlag("COSMIC_MODE"); + COARSE_MODE = rc->get_BoolFlag("COARSE_MODE"); + + NOT_DISPLACED = rc->get_BoolFlag("NOT_DISPLACED"); + TRACK_ELECTRONS = rc->get_BoolFlag("TRACK_ELECTRONS"); + TRACK_DISPLACED = rc->get_BoolFlag("TRACK_DISPLACED"); + OLD_TRACKING = rc->get_BoolFlag("OLD_TRACKING"); + + MaxHitsDC0 = rc->get_IntFlag("MaxHitsDC0"); + MaxHitsDC1 = rc->get_IntFlag("MaxHitsDC1"); + MaxHitsDC2 = rc->get_IntFlag("MaxHitsDC2"); + MaxHitsDC3p = rc->get_IntFlag("MaxHitsDC3p"); + MaxHitsDC3m = rc->get_IntFlag("MaxHitsDC3m"); + + TX_MAX = rc->get_DoubleFlag("TX_MAX"); + TY_MAX = rc->get_DoubleFlag("TY_MAX"); + X0_MAX = rc->get_DoubleFlag("X0_MAX"); + Y0_MAX = rc->get_DoubleFlag("Y0_MAX"); + INVP_MAX = rc->get_DoubleFlag("INVP_MAX"); + INVP_MIN = rc->get_DoubleFlag("INVP_MIN"); + Z_KMAG_BEND = rc->get_DoubleFlag("Z_KMAG_BEND"); + + SAGITTA_TARGET_CENTER = rc->get_DoubleFlag("SAGITTA_TARGET_CENTER"); + SAGITTA_TARGET_WIDTH = rc->get_DoubleFlag("SAGITTA_TARGET_WIDTH"); + SAGITTA_DUMP_CENTER = rc->get_DoubleFlag("SAGITTA_DUMP_CENTER"); + SAGITTA_DUMP_WIDTH = rc->get_DoubleFlag("SAGITTA_DUMP_WIDTH"); + Z_TARGET = rc->get_DoubleFlag("Z_TARGET"); + Z_DUMP = rc->get_DoubleFlag("Z_DUMP"); + + MUID_REJECTION = rc->get_DoubleFlag("MUID_REJECTION"); + MUID_Z_REF = rc->get_DoubleFlag("MUID_Z_REF"); + MUID_R_CUT = rc->get_DoubleFlag("MUID_R_CUT"); + MUID_THE_P0 = rc->get_DoubleFlag("MUID_THE_P0"); + MUID_EMP_P0 = rc->get_DoubleFlag("MUID_EMP_P0"); + MUID_EMP_P1 = rc->get_DoubleFlag("MUID_EMP_P1"); + MUID_EMP_P2 = rc->get_DoubleFlag("MUID_EMP_P2"); + MUID_MINHITS = rc->get_IntFlag("MUID_MINHITS"); + + KMAGSTR = rc->get_DoubleFlag("KMAGSTR"); + PT_KICK_KMAG = rc->get_DoubleFlag("PT_KICK_KMAG")*KMAGSTR; + } + } +} + +KalmanFastTracking_NEW::KalmanFastTracking_NEW(const PHField* field, const TGeoManager* geom, bool flag): verbosity(0), enable_KF(flag), outputListIdx(4) +{ + using namespace std; + initGlobalVariables(); + +#ifdef _DEBUG_ON + cout << "Initialization of KalmanFastTracking_NEW ..." << endl; + cout << "========================================" << endl; +#endif + + _timers.insert(std::make_pair("st2", new PHTimer("st2"))); + _timers.insert(std::make_pair("st3", new PHTimer("st3"))); + _timers.insert(std::make_pair("st23", new PHTimer("st23"))); + _timers.insert(std::make_pair("global", new PHTimer("global"))); + _timers.insert(std::make_pair("global_st1", new PHTimer("global_st1"))); + _timers.insert(std::make_pair("global_link", new PHTimer("global_link"))); + _timers.insert(std::make_pair("global_kalman", new PHTimer("global_kalman"))); + _timers.insert(std::make_pair("kalman", new PHTimer("kalman"))); + + //Initialize Kalman fitter + if(enable_KF) + { + kmfitter = new KalmanFitter(field, geom); + kmfitter->setControlParameter(50, 0.001); + } + + //Initialize minuit minimizer + minimizer[0] = ROOT::Math::Factory::CreateMinimizer("Minuit2", "Simplex"); + minimizer[1] = ROOT::Math::Factory::CreateMinimizer("Minuit2", "Combined"); + fcn = ROOT::Math::Functor(&tracklet_curr, &Tracklet::Eval, KMAG_ON ? 5 : 4); + for(int i = 0; i < 2; ++i) + { + minimizer[i]->SetMaxFunctionCalls(1000000); + minimizer[i]->SetMaxIterations(100); + minimizer[i]->SetTolerance(1E-2); + minimizer[i]->SetFunction(fcn); + minimizer[i]->SetPrintLevel(0); + } + + //Minimize ROOT output + extern Int_t gErrorIgnoreLevel; + gErrorIgnoreLevel = 9999; + + //Initialize geometry service + p_geomSvc = GeomSvc::instance(); +#ifdef _DEBUG_ON + p_geomSvc->printTable(); + p_geomSvc->printWirePosition(); + p_geomSvc->printAlignPar(); +#endif + + //Initialize plane angles for all planes + for(int i = 1; i <= nChamberPlanes; ++i) + { + costheta_plane[i] = p_geomSvc->getCostheta(i); + sintheta_plane[i] = p_geomSvc->getSintheta(i); + } + + //Initialize hodoscope IDs + detectorIDs_mask[0] = p_geomSvc->getDetectorIDs("H1"); + detectorIDs_mask[1] = p_geomSvc->getDetectorIDs("H2"); + detectorIDs_mask[2] = p_geomSvc->getDetectorIDs("H3"); + detectorIDs_mask[3] = p_geomSvc->getDetectorIDs("H4"); + detectorIDs_maskX[0] = p_geomSvc->getDetectorIDs("H1[TB]"); + detectorIDs_maskX[1] = p_geomSvc->getDetectorIDs("H2[TB]"); + detectorIDs_maskX[2] = p_geomSvc->getDetectorIDs("H3[TB]"); + detectorIDs_maskX[3] = p_geomSvc->getDetectorIDs("H4[TB]"); + detectorIDs_maskY[0] = p_geomSvc->getDetectorIDs("H1[LR]"); + detectorIDs_maskY[1] = p_geomSvc->getDetectorIDs("H2[LR]"); + detectorIDs_maskY[2] = p_geomSvc->getDetectorIDs("H4Y1[LR]"); + detectorIDs_maskY[3] = p_geomSvc->getDetectorIDs("H4Y2[LR]"); + detectorIDs_muidHodoAid[0] = p_geomSvc->getDetectorIDs("H4[TB]"); + detectorIDs_muidHodoAid[1] = p_geomSvc->getDetectorIDs("H4Y"); + + //Register masking stations for tracklets in station-0/1, 2, 3+/- + stationIDs_mask[0].push_back(1); + stationIDs_mask[1].push_back(1); + stationIDs_mask[2].push_back(2); + stationIDs_mask[3].push_back(3); + stationIDs_mask[4].push_back(3); + + //Masking stations for back partial + stationIDs_mask[5].push_back(2); + stationIDs_mask[5].push_back(3); + stationIDs_mask[5].push_back(4); + + //Masking stations for global track + stationIDs_mask[6].push_back(1); + stationIDs_mask[6].push_back(2); + stationIDs_mask[6].push_back(3); + stationIDs_mask[6].push_back(4); + + //prop. tube IDs for mu id + detectorIDs_muid[0][0] = p_geomSvc->getDetectorID("P1X1"); + detectorIDs_muid[0][1] = p_geomSvc->getDetectorID("P1X2"); + detectorIDs_muid[0][2] = p_geomSvc->getDetectorID("P2X1"); + detectorIDs_muid[0][3] = p_geomSvc->getDetectorID("P2X2"); + detectorIDs_muid[1][0] = p_geomSvc->getDetectorID("P1Y1"); + detectorIDs_muid[1][1] = p_geomSvc->getDetectorID("P1Y2"); + detectorIDs_muid[1][2] = p_geomSvc->getDetectorID("P2Y1"); + detectorIDs_muid[1][3] = p_geomSvc->getDetectorID("P2Y2"); + + //Reference z_ref for mu id + z_ref_muid[0][0] = MUID_Z_REF; + z_ref_muid[0][1] = MUID_Z_REF; + z_ref_muid[0][2] = 0.5*(p_geomSvc->getPlanePosition(detectorIDs_muid[0][0]) + p_geomSvc->getPlanePosition(detectorIDs_muid[0][1])); + z_ref_muid[0][3] = z_ref_muid[0][2]; + + z_ref_muid[1][0] = MUID_Z_REF; + z_ref_muid[1][1] = MUID_Z_REF; + z_ref_muid[1][2] = 0.5*(p_geomSvc->getPlanePosition(detectorIDs_muid[1][0]) + p_geomSvc->getPlanePosition(detectorIDs_muid[1][1])); + z_ref_muid[1][3] = z_ref_muid[1][2]; + + //Initialize masking window sizes, with optimized contingency + for(int i = nChamberPlanes+1; i <= nChamberPlanes+nHodoPlanes+nPropPlanes; i++) + { + double factor = 0.; + if(i > nChamberPlanes && i <= nChamberPlanes+4) factor = 0.25; //for station-1 hodo + if(i > nChamberPlanes+4 && i <= nChamberPlanes+8) factor = 0.2; //for station-2 hodo + if(i > nChamberPlanes+8 && i <= nChamberPlanes+10) factor = 0.15; //for station-3 hodo + if(i > nChamberPlanes+10 && i <= nChamberPlanes+nHodoPlanes) factor = 0.; //for station-4 hodo + if(i > nChamberPlanes+nHodoPlanes) factor = 0.15; //for station-4 proptube + + z_mask[i-nChamberPlanes-1] = p_geomSvc->getPlanePosition(i); + for(int j = 1; j <= p_geomSvc->getPlaneNElements(i); j++) + { + double x_min, x_max, y_min, y_max; + p_geomSvc->get2DBoxSize(i, j, x_min, x_max, y_min, y_max); + + x_min -= (factor*(x_max - x_min)); + x_max += (factor*(x_max - x_min)); + y_min -= (factor*(y_max - y_min)); + y_max += (factor*(y_max - y_min)); + + x_mask_min[i-nChamberPlanes-1][j-1] = x_min; + x_mask_max[i-nChamberPlanes-1][j-1] = x_max; + y_mask_min[i-nChamberPlanes-1][j-1] = y_min; + y_mask_max[i-nChamberPlanes-1][j-1] = y_max; + } + } + +#ifdef _DEBUG_ON + cout << "========================" << endl; + cout << "Hodo. masking settings: " << endl; + for(int i = 0; i < 4; i++) + { + cout << "For station " << i+1 << endl; + for(std::vector::iterator iter = detectorIDs_mask[i].begin(); iter != detectorIDs_mask[i].end(); ++iter) cout << "All: " << *iter << endl; + for(std::vector::iterator iter = detectorIDs_maskX[i].begin(); iter != detectorIDs_maskX[i].end(); ++iter) cout << "X: " << *iter << endl; + for(std::vector::iterator iter = detectorIDs_maskY[i].begin(); iter != detectorIDs_maskY[i].end(); ++iter) cout << "Y: " << *iter << endl; + } + + for(int i = 0; i < nStations; ++i) + { + std::cout << "Masking stations for tracklets with stationID = " << i + 1 << ": " << std::endl; + for(std::vector::iterator iter = stationIDs_mask[i].begin(); iter != stationIDs_mask[i].end(); ++iter) + { + std::cout << *iter << " "; + } + std::cout << std::endl; + } +#endif + + //Initialize super stationIDs + for(int i = 0; i < nChamberPlanes/6+2; i++) superIDs[i].clear(); + superIDs[0].push_back((p_geomSvc->getDetectorIDs("D0X")[0] + 1)/2); + superIDs[0].push_back((p_geomSvc->getDetectorIDs("D0U")[0] + 1)/2); + superIDs[0].push_back((p_geomSvc->getDetectorIDs("D0V")[0] + 1)/2); + superIDs[1].push_back((p_geomSvc->getDetectorIDs("D1X")[0] + 1)/2); + superIDs[1].push_back((p_geomSvc->getDetectorIDs("D1U")[0] + 1)/2); + superIDs[1].push_back((p_geomSvc->getDetectorIDs("D1V")[0] + 1)/2); + superIDs[2].push_back((p_geomSvc->getDetectorIDs("D2X")[0] + 1)/2); + superIDs[2].push_back((p_geomSvc->getDetectorIDs("D2U")[0] + 1)/2); + superIDs[2].push_back((p_geomSvc->getDetectorIDs("D2V")[0] + 1)/2); + superIDs[3].push_back((p_geomSvc->getDetectorIDs("D3pX")[0] + 1)/2); + superIDs[3].push_back((p_geomSvc->getDetectorIDs("D3pU")[0] + 1)/2); + superIDs[3].push_back((p_geomSvc->getDetectorIDs("D3pV")[0] + 1)/2); + superIDs[4].push_back((p_geomSvc->getDetectorIDs("D3mX")[0] + 1)/2); + superIDs[4].push_back((p_geomSvc->getDetectorIDs("D3mU")[0] + 1)/2); + superIDs[4].push_back((p_geomSvc->getDetectorIDs("D3mV")[0] + 1)/2); + + superIDs[5].push_back((p_geomSvc->getDetectorIDs("P1X")[0] + 1)/2); + superIDs[5].push_back((p_geomSvc->getDetectorIDs("P2X")[0] + 1)/2); + superIDs[6].push_back((p_geomSvc->getDetectorIDs("P1Y")[0] + 1)/2); + superIDs[6].push_back((p_geomSvc->getDetectorIDs("P2Y")[0] + 1)/2); + +#ifdef _DEBUG_ON + cout << "=============" << endl; + cout << "Chamber IDs: " << endl; + TString stereoNames[3] = {"X", "U", "V"}; + for(int i = 0; i < nChamberPlanes/6; i++) + { + for(int j = 0; j < 3; j++) cout << i << " " << stereoNames[j].Data() << ": " << superIDs[i][j] << endl; + } + + cout << "Proptube IDs: " << endl; + for(int i = nChamberPlanes/6; i < nChamberPlanes/6+2; i++) + { + for(int j = 0; j < 2; j++) cout << i << " " << j << ": " << superIDs[i][j] << endl; + } + + //Initialize widow sizes for X-U matching and z positions of all chambers + cout << "======================" << endl; + cout << "U plane window sizes: " << endl; +#endif + + double u_factor[] = {5., 5., 5., 15., 15.}; + for(int i = 0; i < nChamberPlanes/6; i++) + { + int xID = 2*superIDs[i][0] - 1; + int uID = 2*superIDs[i][1] - 1; + int vID = 2*superIDs[i][2] - 1; + double spacing = p_geomSvc->getPlaneSpacing(uID); + double x_span = p_geomSvc->getPlaneScaleY(uID); + + z_plane_x[i] = 0.5*(p_geomSvc->getPlanePosition(xID) + p_geomSvc->getPlanePosition(xID+1)); + z_plane_u[i] = 0.5*(p_geomSvc->getPlanePosition(uID) + p_geomSvc->getPlanePosition(uID+1)); + z_plane_v[i] = 0.5*(p_geomSvc->getPlanePosition(vID) + p_geomSvc->getPlanePosition(vID+1)); + + u_costheta[i] = costheta_plane[uID]; + u_sintheta[i] = sintheta_plane[uID]; + + //u_win[i] = fabs(0.5*x_span/(spacing/sintheta_plane[uID])) + 2.*spacing + u_factor[i]; + u_win[i] = fabs(0.5*x_span*sintheta_plane[uID]) + TX_MAX*fabs((z_plane_u[i] - z_plane_x[i])*u_costheta[i]) + TY_MAX*fabs((z_plane_u[i] - z_plane_x[i])*u_sintheta[i]) + 2.*spacing + u_factor[i]; + +#ifdef _DEBUG_ON + cout << "Station " << i << ": " << xID << " " << uID << " " << vID << " " << u_win[i] << endl; +#endif + } + + //Initialize Z positions and maximum parameters of all planes + for(int i = 1; i <= nChamberPlanes; i++) + { + z_plane[i] = p_geomSvc->getPlanePosition(i); + slope_max[i] = costheta_plane[i]*TX_MAX + sintheta_plane[i]*TY_MAX; + intersection_max[i] = costheta_plane[i]*X0_MAX + sintheta_plane[i]*Y0_MAX; + +#ifdef COARSE_MODE + resol_plane[i] = 3.*p_geomSvc->getPlaneSpacing(i)/sqrt(12.); +#else + if(i <= 6) + { + resol_plane[i] = recoConsts::instance()->get_DoubleFlag("RejectWinDC0"); + } + else if(i <= 12) + { + resol_plane[i] = recoConsts::instance()->get_DoubleFlag("RejectWinDC1"); + } + else if(i <= 18) + { + resol_plane[i] = recoConsts::instance()->get_DoubleFlag("RejectWinDC2"); + } + else if(i <= 24) + { + resol_plane[i] = recoConsts::instance()->get_DoubleFlag("RejectWinDC3p"); + } + else + { + resol_plane[i] = recoConsts::instance()->get_DoubleFlag("RejectWinDC3m"); + } +#endif + spacing_plane[i] = p_geomSvc->getPlaneSpacing(i); + } + +#ifdef _DEBUG_ON + cout << "======================================" << endl; + cout << "Maximum local slope and intersection: " << endl; +#endif + for(int i = 1; i <= nChamberPlanes/2; i++) + { + double d_slope = (p_geomSvc->getPlaneResolution(2*i - 1) + p_geomSvc->getPlaneResolution(2*i))/(z_plane[2*i] - z_plane[2*i-1]); + double d_intersection = d_slope*z_plane[2*i]; + + slope_max[2*i-1] += d_slope; + intersection_max[2*i-1] += d_intersection; + slope_max[2*i] += d_slope; + intersection_max[2*i] += d_intersection; + +#ifdef _DEBUG_ON + cout << "Super plane " << i << ": " << slope_max[2*i-1] << " " << intersection_max[2*i-1] << endl; +#endif + } + + //Initialize sagitta ratios, index 0, 1, 2 are for X, U, V, this is the incrementing order of plane type + s_detectorID[0] = p_geomSvc->getDetectorID("D2X"); + s_detectorID[1] = p_geomSvc->getDetectorID("D2Up"); + s_detectorID[2] = p_geomSvc->getDetectorID("D2Vp"); +} + +KalmanFastTracking_NEW::~KalmanFastTracking_NEW() +{ + if(enable_KF) delete kmfitter; + delete minimizer[0]; + delete minimizer[1]; +} + +void KalmanFastTracking_NEW::setRawEventDebug(SRawEvent* event_input) +{ + rawEvent = event_input; + hitAll = event_input->getAllHits(); +} + +int KalmanFastTracking_NEW::setRawEvent(SRawEvent* event_input) +{ + //reset timer + for(auto iter=_timers.begin(); iter != _timers.end(); ++iter) + { + iter->second->reset(); + } + + //Initialize tracklet lists + for(int i = 0; i < 5; i++){ + trackletsInSt[i].clear(); + trackletsInStSlimX[i].clear(); + trackletsInStSlimU[i].clear(); + trackletsInStSlimV[i].clear(); + } + stracks.clear(); + + //pre-tracking cuts + rawEvent = event_input; + if(!acceptEvent(rawEvent)) return TFEXIT_FAIL_MULTIPLICITY; + hitAll = event_input->getAllHits(); +#ifdef _DEBUG_ON + for(std::vector::iterator iter = hitAll.begin(); iter != hitAll.end(); ++iter) iter->print(); +#endif + + //Initialize hodo and masking IDs + for(int i = 0; i < 4; i++) + { + //std::cout << "For station " << i << std::endl; + hitIDs_mask[i].clear(); + if(MC_MODE || COSMIC_MODE || rawEvent->isFPGATriggered()) + { + hitIDs_mask[i] = rawEvent->getHitsIndexInDetectors(detectorIDs_maskX[i]); + } + else + { + hitIDs_mask[i] = rawEvent->getHitsIndexInDetectors(detectorIDs_maskY[i]); + } + + //for(std::list::iterator iter = hitIDs_mask[i].begin(); iter != hitIDs_mask[i].end(); ++iter) std::cout << *iter << " " << hitAll[*iter].detectorID << " === "; + //std::cout << std::endl; + } + + //Initialize prop. tube IDs + for(int i = 0; i < 2; ++i) + { + for(int j = 0; j < 4; ++j) + { + hitIDs_muid[i][j].clear(); + hitIDs_muid[i][j] = rawEvent->getHitsIndexInDetector(detectorIDs_muid[i][j]); + } + hitIDs_muidHodoAid[i].clear(); + hitIDs_muidHodoAid[i] = rawEvent->getHitsIndexInDetectors(detectorIDs_muidHodoAid[i]); + } + + if(!COARSE_MODE) + { + buildPropSegments(); + if(propSegs[0].empty() || propSegs[1].empty()) + { +#ifdef _DEBUG_ON + LogInfo("Failed in prop tube segment building: " << propSegs[0].size() << ", " << propSegs[1].size()); +#endif + //return TFEXIT_FAIL_ROUGH_MUONID; + } + } + + //Build tracklets in station 2, 3+, 3- + _timers["st2"]->restart(); + //buildTrackletsInStation(3, 1); //3 for station-2, 1 for list position 1 + buildTrackletsInStationSlim(3, 1); //3 for station-2, 1 for list position 1 + std::cout<<"Station 2 x combos = "<getCostheta(1) * pos_exp[0] + p_geomSvc->getSintheta(1) * 0<<", "<getCostheta(5) * pos_exp[0] + p_geomSvc->getSintheta(5) * 0<stop(); + if(verbosity >= 2) LogInfo("NTracklets in St2: " << trackletsInSt[1].size()); + + if(outputListIdx > 1 && trackletsInSt[1].empty()) + { +#ifdef _DEBUG_ON + LogInfo("Failed in tracklet build at station 2"); +#endif + //return TFEXIT_FAIL_ST2_TRACKLET; + } + + _timers["st3"]->restart(); + //buildTrackletsInStation(4, 2); //4 for station-3+ + //buildTrackletsInStation(5, 2); //5 for station-3- + buildTrackletsInStationSlim(4, 2); //4 for station-3+ + buildTrackletsInStationSlim(5, 2); //5 for station-3- + std::cout<<"Station 3 x combos = "<stop(); + if(verbosity >= 2) LogInfo("NTracklets in St3: " << trackletsInSt[2].size()); + + if(outputListIdx > 2 && trackletsInSt[2].empty()) + { +#ifdef _DEBUG_ON + LogInfo("Failed in tracklet build at station 3"); +#endif + //return TFEXIT_FAIL_ST3_TRACKLET; + } + + //Build back partial tracks in station 2, 3+ and 3- + _timers["st23"]->restart(); + //buildBackPartialTracks(); + buildBackPartialTracksSlimX(1); + std::cout<<"Station 2+3 x combos = "< 500){ + trackletsInStSlimX[3].clear(); + buildBackPartialTracksSlimX(2); + std::cout<<"Station 2+3 x combos = "< 100){ + return TFEXIT_FAIL_BACKPARTIAL; + } + } + buildBackPartialTracksSlimU(1); + std::cout<<"Station 2+3 u combos = "< 500){ + trackletsInStSlimU[3].clear(); + buildBackPartialTracksSlimU(2); + std::cout<<"Station 2+3 u combos = "< 100){ + return TFEXIT_FAIL_BACKPARTIAL; + } + } + buildBackPartialTracksSlimV(1); + std::cout<<"Station 2+3 v combos = "< 500){ + trackletsInStSlimV[3].clear(); + buildBackPartialTracksSlimV(2); + std::cout<<"Station 2+3 v combos = "< 100){ + return TFEXIT_FAIL_BACKPARTIAL; + } + } + buildBackPartialTracksSlim_v2(); + std::cout<<"Station 2+3 all combos = "<::iterator tracklet23 = trackletsInStSlimX[3].begin(); tracklet23 != trackletsInStSlimX[3].end(); ++tracklet23){ + // buildTrackletsInStationWithUV(6, 3, *tracklet23); + //} + _timers["st23"]->stop(); + if(verbosity >= 2) LogInfo("NTracklets St2+St3: " << trackletsInSt[3].size()); + + + if(outputListIdx > 3 && trackletsInSt[3].empty()) + { +#ifdef _DEBUG_ON + LogInfo("Failed in connecting station-2 and 3 tracks"); +#endif + return TFEXIT_FAIL_BACKPARTIAL; + } + + //Connect tracklets in station 2/3 and station 1 to form global tracks + _timers["global"]->restart(); + /*if(!TRACK_DISPLACED){ + buildGlobalTracks(); + } else{ + buildGlobalTracksDisplaced(); + }*/ + _timers["global"]->stop(); + if(verbosity >= 2) LogInfo("NTracklets Global: " << trackletsInSt[4].size()); + +#ifdef _DEBUG_ON + for(int i = 0; i < 2; ++i) + { + std::cout << "=======================================================================================" << std::endl; + LogInfo("Prop tube segments in " << (i == 0 ? "X-Z" : "Y-Z")); + for(std::list::iterator seg = propSegs[i].begin(); seg != propSegs[i].end(); ++seg) + { + seg->print(); + } + std::cout << "=======================================================================================" << std::endl; + } + + for(int i = 0; i <= 4; i++) + { + std::cout << "=======================================================================================" << std::endl; + LogInfo("Final tracklets in station: " << i+1 << " is " << trackletsInSt[i].size()); + for(std::list::iterator tracklet = trackletsInSt[i].begin(); tracklet != trackletsInSt[i].end(); ++tracklet) + { + tracklet->print(); + } + std::cout << "=======================================================================================" << std::endl; + } +#endif + + if(outputListIdx == 4 && trackletsInSt[4].empty()) return TFEXIT_FAIL_GLOABL; + if(!enable_KF) return TFEXIT_SUCCESS; + + //Build kalman tracks + _timers["kalman"]->restart(); + for(std::list::iterator tracklet = trackletsInSt[outputListIdx].begin(); tracklet != trackletsInSt[outputListIdx].end(); ++tracklet) + { + SRecTrack strack = processOneTracklet(*tracklet); + stracks.push_back(strack); + } + _timers["kalman"]->stop(); + +#ifdef _DEBUG_ON + LogInfo(stracks.size() << " final tracks:"); + for(std::list::iterator strack = stracks.begin(); strack != stracks.end(); ++strack) + { + strack->print(); + } +#endif + + return TFEXIT_SUCCESS; +} + +bool KalmanFastTracking_NEW::acceptEvent(SRawEvent* rawEvent) +{ + //if(Verbosity() >= Fun4AllBase::VERBOSITY_A_LOT) //WPM + //{ //WPM + LogInfo("D0: " << rawEvent->getNHitsInD0()); + LogInfo("D1: " << rawEvent->getNHitsInD1()); + LogInfo("D2: " << rawEvent->getNHitsInD2()); + LogInfo("D3p: " << rawEvent->getNHitsInD3p()); + LogInfo("D3m: " << rawEvent->getNHitsInD3m()); + LogInfo("H1: " << rawEvent->getNHitsInDetectors(detectorIDs_maskX[0])); + LogInfo("H2: " << rawEvent->getNHitsInDetectors(detectorIDs_maskX[1])); + LogInfo("H3: " << rawEvent->getNHitsInDetectors(detectorIDs_maskX[2])); + LogInfo("H4: " << rawEvent->getNHitsInDetectors(detectorIDs_maskX[3])); + LogInfo("Prop:" << rawEvent->getNPropHitsAll()); + LogInfo("NRoadsPos: " << rawEvent->getNRoadsPos()); + LogInfo("NRoadsNeg: " << rawEvent->getNRoadsNeg()); + //} //WPM + + if(rawEvent->getNHitsInD0() > MaxHitsDC0) return false; + //if(rawEvent->getNHitsInD1() > MaxHitsDC1) return false; + if(rawEvent->getNHitsInD2() > MaxHitsDC2) return false; + if(rawEvent->getNHitsInD3p() > MaxHitsDC3p) return false; + if(rawEvent->getNHitsInD3m() > MaxHitsDC3m) return false; + + /* + if(rawEvent->getNHitsInDetectors(detectorIDs_maskX[0]) > 15) return false; + if(rawEvent->getNHitsInDetectors(detectorIDs_maskX[1]) > 10) return false; + if(rawEvent->getNHitsInDetectors(detectorIDs_maskX[2]) > 10) return false; + if(rawEvent->getNHitsInDetectors(detectorIDs_maskX[3]) > 10) return false; + if(rawEvent->getNPropHitsAll() > 300) return false; + + if(rawEvent->getNRoadsPos() > 5) return false; + if(rawEvent->getNRoadsNeg() > 5) return false; + */ + + return true; +} + +void KalmanFastTracking_NEW::buildBackPartialTracks() +{ + //Temporary container for a simple chisq fit + int nHitsX2, nHitsX3; + double z_fit[4], x_fit[4]; + double a, b; + + for(std::list::iterator tracklet3 = trackletsInSt[2].begin(); tracklet3 != trackletsInSt[2].end(); ++tracklet3) + { + //tracklet3->print(); + if(!COARSE_MODE) + { + //Extract the X hits only from station-3 tracks + nHitsX3 = 0; + for(std::list::iterator ptr_hit = tracklet3->hits.begin(); ptr_hit != tracklet3->hits.end(); ++ptr_hit) + { + if(ptr_hit->hit.index < 0) continue; + if(p_geomSvc->getPlaneType(ptr_hit->hit.detectorID) == 1) + { + z_fit[nHitsX3] = z_plane[ptr_hit->hit.detectorID]; + x_fit[nHitsX3] = ptr_hit->hit.pos; + ++nHitsX3; + } + } + } + + Tracklet tracklet_best; + for(std::list::iterator tracklet2 = trackletsInSt[1].begin(); tracklet2 != trackletsInSt[1].end(); ++tracklet2) + { + //tracklet2->print(); + if(!COARSE_MODE) + { + if(OLD_TRACKING){ + if(fabs(tracklet2->tx - tracklet3->tx) > 0.15 || fabs(tracklet2->ty - tracklet3->ty) > 0.1) continue; + } + //Extract the X hits from station-2 tracke + nHitsX2 = nHitsX3; + for(std::list::iterator ptr_hit = tracklet2->hits.begin(); ptr_hit != tracklet2->hits.end(); ++ptr_hit) + { + if(ptr_hit->hit.index < 0) continue; + if(p_geomSvc->getPlaneType(ptr_hit->hit.detectorID) == 1) + { + z_fit[nHitsX2] = z_plane[ptr_hit->hit.detectorID]; + x_fit[nHitsX2] = ptr_hit->hit.pos; + ++nHitsX2; + } + } + + //Apply a simple linear fit to get rough estimation of X-Z slope and intersection + chi2fit(nHitsX2, z_fit, x_fit, a, b); + if(fabs(a) > 2.*TX_MAX || fabs(b) > 2.*X0_MAX) continue; + + //Project to proportional tubes to see if there is enough + int nPropHits = 0; + for(int i = 0; i < 4; ++i) + { + double x_exp = a*z_mask[detectorIDs_muid[0][i] - nChamberPlanes - 1] + b; + for(std::list::iterator iter = hitIDs_muid[0][i].begin(); iter != hitIDs_muid[0][i].end(); ++iter) + { + if(fabs(hitAll[*iter].pos - x_exp) < 5.08) + { + ++nPropHits; + break; + } + } + if(nPropHits > 0) break; + } + if(!TRACK_ELECTRONS && nPropHits == 0) continue; //Turned off by Patrick for electron tracks + } + + Tracklet tracklet_23; + if(OLD_TRACKING){ + tracklet_23 = (*tracklet2) + (*tracklet3); + } + else{ + if(compareTracklets(*tracklet2, *tracklet3)){ + tracklet_23 = (*tracklet2) + (*tracklet3); + tracklet_23.tx = tracklet2->tx; //This is needed to "seed" the tracklet fit that happens below. This tx and ty information is assigned in compareTracklets below + tracklet_23.ty = tracklet2->ty; + + tracklet_23.st2Z = tracklet2->st2Z; + tracklet_23.st2X = tracklet2->st2X; + tracklet_23.st2Y = tracklet2->st2Y; + tracklet_23.st3Y = tracklet2->st3Y; + tracklet_23.st2U = tracklet2->st2U; + tracklet_23.st2V = tracklet2->st2V; + tracklet_23.st2Usl = tracklet2->st2Usl; + tracklet_23.st2Vsl = tracklet2->st2Vsl; + } + else{ + continue; + } + } +#ifdef _DEBUG_ON + LogInfo("Using following two tracklets:"); + tracklet2->print(); + tracklet3->print(); + LogInfo("Yield this combination:"); + tracklet_23.print(); +#endif + fitTracklet(tracklet_23); //This is the fit that needs the seeded tx and ty information. Without the seed information, the fit occasionally finds bad slope and X0 or Y0 values, much in the same way that it does for single-station tracklets. Note from Patrick: this fit could probably be throw out, as we already know the tx and ty information from compareTracklets. I would just need to extrapolate back to z = 0 and calculate the chisq by hand + if(tracklet_23.chisq > 9000.) + { +#ifdef _DEBUG_ON + tracklet_23.print(); + LogInfo("Impossible combination!"); +#endif + continue; + } + + if(!COARSE_MODE && !hodoMask(tracklet_23)) + { +#ifdef _DEBUG_ON + LogInfo("Hodomasking failed!"); +#endif + continue; + } +#ifdef _DEBUG_ON + LogInfo("Hodomasking Scucess!"); +#endif + + if(!COARSE_MODE) + { + resolveLeftRight(tracklet_23, 40.); //resolveLeftRight at this stage is, in truth, not needed. We already know which side of the wire the particle passed by from compareTracklet. However, getting rid of this would take a bit of work + resolveLeftRight(tracklet_23, 150.); + } + + ///Remove bad hits if needed + removeBadHits(tracklet_23); + +#ifdef _DEBUG_ON + LogInfo("New tracklet: "); + tracklet_23.print(); + + LogInfo("Current best:"); + tracklet_best.print(); + + LogInfo("Comparison: " << (tracklet_23 < tracklet_best)); + LogInfo("Quality: " << acceptTracklet(tracklet_23)); +#endif + + //If current tracklet is better than the best tracklet up-to-now + if(acceptTracklet(tracklet_23) && tracklet_23 < tracklet_best) + { + tracklet_best = tracklet_23; + } +#ifdef _DEBUG_ON + else + { + LogInfo("Rejected!!"); + } +#endif + } + + if(tracklet_best.isValid() > 0) trackletsInSt[3].push_back(tracklet_best); + } + + reduceTrackletList(trackletsInSt[3]); + trackletsInSt[3].sort(); +} + + +void KalmanFastTracking_NEW::buildBackPartialTracksSlim() +{ +#ifdef _DEBUG_ON + LogInfo("HELLO I'm in buildBackPartialTracksSlim"); +#endif + //std::cout<<"trackletsInStSlimV[3].size() = "<::iterator trackletV = trackletsInStSlimV[3].begin(); trackletV != trackletsInStSlimV[3].end(); ++trackletV){ + //std::cout<<"FIFTH TEST trackletV->acceptedVLine2.wireHit1PosZ = "<<(*trackletV).acceptedVLine2.wireHit1PosZ< acceptedStation2Tracklets; + std::vector acceptedStation3Tracklets; + + for(std::list::iterator trackletX = trackletsInStSlimX[3].begin(); trackletX != trackletsInStSlimX[3].end(); ++trackletX){ + Tracklet tracklet_best; + for(std::list::iterator trackletU = trackletsInStSlimU[3].begin(); trackletU != trackletsInStSlimU[3].end(); ++trackletU){ + Tracklet tracklet_best_UX; + for(std::list::iterator trackletV = trackletsInStSlimV[3].begin(); trackletV != trackletsInStSlimV[3].end(); ++trackletV){ + + double posy2U = ((*trackletU).st2U - p_geomSvc->getCostheta((*trackletX).getHit(0).hit.detectorID+2)*((*trackletX).st2X + (*trackletX).st2Xsl * ((*trackletU).st2Z - (*trackletX).st2Z) ))/p_geomSvc->getSintheta((*trackletX).getHit(0).hit.detectorID+2); + double posy2V = ((*trackletV).st2V - p_geomSvc->getCostheta((*trackletX).getHit(0).hit.detectorID-2)*((*trackletX).st2X + (*trackletX).st2Xsl * ((*trackletV).st2Z - (*trackletX).st2Z) ))/p_geomSvc->getSintheta((*trackletX).getHit(0).hit.detectorID-2); + double posy3U = ((*trackletU).st3U - p_geomSvc->getCostheta((*trackletX).getHit(2).hit.detectorID+2)*((*trackletX).st3X + (*trackletX).st3Xsl * ((*trackletU).st3Z - (*trackletX).st3Z) ))/p_geomSvc->getSintheta((*trackletX).getHit(2).hit.detectorID+2); + double posy3V = ((*trackletV).st3V - p_geomSvc->getCostheta((*trackletX).getHit(2).hit.detectorID-2)*((*trackletX).st3X + (*trackletX).st3Xsl * ((*trackletV).st3Z - (*trackletX).st3Z) ))/p_geomSvc->getSintheta((*trackletX).getHit(2).hit.detectorID-2); + +#ifdef _DEBUG_PATRICK + LogInfo("HELLO I'm in buildBackPartialTracksSlim"); +#endif + + double st2UWireSin = TMath::Sin(TMath::ATan(1./trackletU->acceptedULine2.wire1Slope)); + double st2VWireSin = TMath::Sin(TMath::ATan(1./trackletV->acceptedVLine2.wire1Slope)); + double st3UWireSin = TMath::Sin(TMath::ATan(1./trackletU->acceptedULine3.wire1Slope)); + double st3VWireSin = TMath::Sin(TMath::ATan(1./trackletV->acceptedVLine3.wire1Slope)); + + double st2UWireCos = TMath::Cos(TMath::ATan(1./trackletU->acceptedULine2.wire1Slope)); + double st2VWireCos = TMath::Cos(TMath::ATan(1./trackletV->acceptedVLine2.wire1Slope)); + double st3UWireCos = TMath::Cos(TMath::ATan(1./trackletU->acceptedULine3.wire1Slope)); + double st3VWireCos = TMath::Cos(TMath::ATan(1./trackletV->acceptedVLine3.wire1Slope)); + + double testTY2 = ( trackletV->st2Vsl - (st2VWireCos/st2UWireCos)*trackletU->st2Usl )/( (st2VWireCos * st2UWireSin)/(st2UWireCos) - st2VWireSin ); + double testTY3 = ( trackletV->st3Vsl - (st3VWireCos/st3UWireCos)*trackletU->st3Usl )/( (st3VWireCos * st3UWireSin)/(st3UWireCos) - st3VWireSin ); + double testTX2 = ( trackletU->st2Usl - (st2UWireSin/st2VWireSin)*trackletV->st2Vsl )/( st2UWireCos - ( st2UWireSin * st2VWireCos )/st2VWireSin ); + double testTX3 = ( trackletU->st3Usl - (st3UWireSin/st3VWireSin)*trackletV->st3Vsl )/( st3UWireCos - ( st3UWireSin * st3VWireCos )/st3VWireSin ); + +#ifdef _DEBUG_PATRICK + std::cout<<"testTY2 = "<st2Xsl - testTX2) > 0.005 || std::abs(trackletX->st2Xsl - testTX3) > 0.005) continue; +#ifdef _DEBUG_PATRICK + LogInfo("past cont 2"); +#endif + //double posy = tracklet23->ty * ( z_plane[3] - tracklet23->st2Z ) + tracklet23->st2Y; //WPM + + double tracklet2Ys_D = 0.; //This is the sum of the Y-values of the hits in the U and V planes of the two tracklets. The sum is taken to be used in an average. The _D here stands for driftDistance. I originally did this part of the code without taking the drift distance in the slanted layers into account + double tracklet3Ys_D = 0.; + + for(unsigned int h = 0; h < trackletU->hits.size(); h++){ + double posx = trackletX->st2Xsl * (z_plane[(*trackletU).getHit(h).hit.detectorID] - trackletX->st2Z) + trackletX->st2X; + if((*trackletU).getHit(h).hit.detectorID == 17){ + tracklet2Ys_D += trackletU->acceptedULine2.wire1Slope * posx + trackletU->acceptedULine2.wireIntercept1; + } + if((*trackletU).getHit(h).hit.detectorID == 18){ + tracklet2Ys_D += trackletU->acceptedULine2.wire2Slope * posx + trackletU->acceptedULine2.wireIntercept2; + } + if((*trackletU).getHit(h).hit.detectorID == 19 || (*trackletU).getHit(h).hit.detectorID == 25){ + tracklet3Ys_D += trackletU->acceptedULine3.wire1Slope * posx + trackletU->acceptedULine3.wireIntercept1; + } + if((*trackletU).getHit(h).hit.detectorID == 20 || (*trackletU).getHit(h).hit.detectorID == 26){ + tracklet3Ys_D += trackletU->acceptedULine3.wire2Slope * posx + trackletU->acceptedULine3.wireIntercept2; + } + } + + for(unsigned int h = 0; h < trackletV->hits.size(); h++){ + double posx = trackletX->st2Xsl * (z_plane[(*trackletV).getHit(h).hit.detectorID] - trackletX->st2Z) + trackletX->st2X; + if((*trackletV).getHit(h).hit.detectorID == 13){ + tracklet2Ys_D += trackletV->acceptedVLine2.wire1Slope * posx + trackletV->acceptedVLine2.wireIntercept1; + } + if((*trackletV).getHit(h).hit.detectorID == 14){ + tracklet2Ys_D += trackletV->acceptedVLine2.wire2Slope * posx + trackletV->acceptedVLine2.wireIntercept2; + } + if((*trackletV).getHit(h).hit.detectorID == 23 || (*trackletV).getHit(h).hit.detectorID == 29){ + tracklet3Ys_D += trackletV->acceptedVLine3.wire1Slope * posx + trackletV->acceptedVLine3.wireIntercept1; + } + if((*trackletV).getHit(h).hit.detectorID == 24 || (*trackletV).getHit(h).hit.detectorID == 30){ + tracklet3Ys_D += trackletV->acceptedVLine3.wire2Slope * posx + trackletV->acceptedVLine3.wireIntercept2; + } + } + + double differentYSlope = (tracklet3Ys_D/4. - tracklet2Ys_D/4.)/(trackletX->st3Z - trackletX->st2Z); +#ifdef _DEBUG_PATRICK + std::cout<<"differentYSlope = "<st2Xsl; + //tracklet_TEST_23.ty = (differentYSlope + testTY2 + testTY3)/3.; + tracklet_TEST_23.ty = (testTY2 + testTY3)/2.; + tracklet_TEST_23.invP = 1./50.; + tracklet_TEST_23.x0 = trackletX->st2Xsl * (0. - trackletX->st2Z) + trackletX->st2X; + + tracklet_TEST_23.sortHits(); + + std::cout<<"about to test out y0 vals?"< 18 && (*trackletX).getHit(2).hit.detectorID < 25){ + tracklet_st3.stationID = 4; + } + + if((*trackletX).getHit(2).hit.detectorID > 24 && (*trackletX).getHit(2).hit.detectorID < 31){ + tracklet_st3.stationID = 5; + } + + //resolveLeftRight(*xiter, LR1, LR2); + tracklet_st3.hits.push_back(SignedHit((*trackletX).getHit(2).hit, (*trackletX).getHit(2).sign)); + tracklet_st3.nXHits++; + tracklet_st3.hits.push_back(SignedHit((*trackletX).getHit(3).hit, (*trackletX).getHit(3).sign)); + tracklet_st3.nXHits++; + tracklet_st3.getSlopesX((*trackletX).getHit(2).hit, (*trackletX).getHit(3).hit); + + tracklet_st3.hits.push_back(SignedHit((*trackletU).getHit(2).hit, (*trackletU).getHit(2).sign)); + tracklet_st3.nUHits++; + tracklet_st3.hits.push_back(SignedHit((*trackletU).getHit(3).hit, (*trackletU).getHit(3).sign)); + tracklet_st3.nUHits++; + tracklet_st3.getSlopesU((*trackletU).getHit(2).hit, (*trackletU).getHit(3).hit); + + tracklet_st3.hits.push_back(SignedHit((*trackletV).getHit(2).hit, (*trackletV).getHit(2).sign)); + tracklet_st3.nVHits++; + tracklet_st3.hits.push_back(SignedHit((*trackletV).getHit(3).hit, (*trackletV).getHit(3).sign)); + tracklet_st3.nVHits++; + tracklet_st3.getSlopesV((*trackletV).getHit(2).hit, (*trackletV).getHit(3).hit); + + tracklet_st3.sortHits(); + + for(unsigned int tr3 = 0; tr3::iterator iter = tracklet_st2.hits.begin(); iter != tracklet_st2.hits.end(); ++iter) + { + if(iter->sign > 0) std::cout << "L: "; + if(iter->sign < 0) std::cout << "R: "; + if(iter->sign == 0) std::cout << "U: "; + + std::cout << iter->hit.index << " " << p_geomSvc->getDetectorName(iter->hit.detectorID) << "(" << iter->hit.detectorID << ") " << iter->hit.elementID << " = "; + } + std::cout<::iterator iter = tracklet_st3.hits.begin(); iter != tracklet_st3.hits.end(); ++iter) + { + if(iter->sign > 0) std::cout << "L: "; + if(iter->sign < 0) std::cout << "R: "; + if(iter->sign == 0) std::cout << "U: "; + + std::cout << iter->hit.index << " " << p_geomSvc->getDetectorName(iter->hit.detectorID) << "(" << iter->hit.detectorID << ") " << iter->hit.elementID << " = "; + } + std::cout< 9000.) + { +#ifdef _DEBUG_ON + tracklet_23.print(); + LogInfo("Impossible combination!"); +#endif + continue; + } + /* + if(!COARSE_MODE && !hodoMask(tracklet_23)) + { +#ifdef _DEBUG_ON + LogInfo("Hodomasking failed!"); +#endif + continue; + } +#ifdef _DEBUG_ON + LogInfo("Hodomasking Scucess!"); +#endif + */ + if(!COARSE_MODE) + { + resolveLeftRight(tracklet_23, 40.); //resolveLeftRight at this stage is, in truth, not needed. We already know which side of the wire the particle passed by from compareTracklet. However, getting rid of this would take a bit of work + resolveLeftRight(tracklet_23, 150.); + } + + ///Remove bad hits if needed + removeBadHits(tracklet_23); + +#ifdef _DEBUG_ON + LogInfo("New tracklet: "); + tracklet_23.print(); + + LogInfo("Current best:"); + tracklet_best_UX.print(); + + LogInfo("Comparison: " << (tracklet_23 < tracklet_best_UX)); + LogInfo("Candidate chisq: " << tracklet_23.chisq); + LogInfo("Quality: " << acceptTracklet(tracklet_23)); +#endif + + //If current tracklet is better than the best tracklet up-to-now + if(acceptTracklet(tracklet_23) && tracklet_23 < tracklet_best_UX) + { + tracklet_best_UX = tracklet_23; + } +#ifdef _DEBUG_ON + else + { + LogInfo("Rejected!!"); + } +#endif + + } + if(tracklet_best_UX < tracklet_best){ + tracklet_best = tracklet_best_UX; + } + } + if(acceptTracklet(tracklet_best)){ + if(tracklet_best.isValid() > 0){ + //std::cout<<"pushing back 2+3 tracklets with candidate with the following chisq: "< acceptedStation2Tracklets; + std::vector acceptedStation3Tracklets; + +#ifdef _DEBUG_PATRICK + LogInfo("starting X loop. trackletsInStSlimX[3].size() = "<::iterator trackletX = trackletsInStSlimX[3].begin(); trackletX != trackletsInStSlimX[3].end(); ++trackletX){ + Tracklet tracklet_best; +#ifdef _DEBUG_PATRICK + LogInfo("starting U loop. trackletsInStSlimU[3].size() = "<::iterator trackletU = trackletsInStSlimU[3].begin(); trackletU != trackletsInStSlimU[3].end(); ++trackletU){ + Tracklet tracklet_best_UX; +#ifdef _DEBUG_PATRICK + LogInfo("starting V loop. trackletsInStSlimV[3].size() = "<::iterator trackletV = trackletsInStSlimV[3].begin(); trackletV != trackletsInStSlimV[3].end(); ++trackletV){ + +#ifdef _DEBUG_PATRICK + LogInfo("beginning of V loop"); +#endif + /* + double posy2U = ((*trackletU).st2U - p_geomSvc->getCostheta((*trackletX).getHit(0).hit.detectorID+2)*((*trackletX).st2X + (*trackletX).st2Xsl * ((*trackletU).st2Z - (*trackletX).st2Z) ))/p_geomSvc->getSintheta((*trackletX).getHit(0).hit.detectorID+2); + double posy2V = ((*trackletV).st2V - p_geomSvc->getCostheta((*trackletX).getHit(0).hit.detectorID-2)*((*trackletX).st2X + (*trackletX).st2Xsl * ((*trackletV).st2Z - (*trackletX).st2Z) ))/p_geomSvc->getSintheta((*trackletX).getHit(0).hit.detectorID-2); + double posy3U = ((*trackletU).st3U - p_geomSvc->getCostheta((*trackletX).getHit(2).hit.detectorID+2)*((*trackletX).st3X + (*trackletX).st3Xsl * ((*trackletU).st3Z - (*trackletX).st3Z) ))/p_geomSvc->getSintheta((*trackletX).getHit(2).hit.detectorID+2); + double posy3V = ((*trackletV).st3V - p_geomSvc->getCostheta((*trackletX).getHit(2).hit.detectorID-2)*((*trackletX).st3X + (*trackletX).st3Xsl * ((*trackletV).st3Z - (*trackletX).st3Z) ))/p_geomSvc->getSintheta((*trackletX).getHit(2).hit.detectorID-2); + */ + +#ifdef _DEBUG_PATRICK + LogInfo("HELLO I'm in buildBackPartialTracksSlim_v2"); +#endif + + double st2UWireSin = TMath::Sin(TMath::ATan(1./trackletU->acceptedULine2.wire1Slope)); + double st2VWireSin = TMath::Sin(TMath::ATan(1./trackletV->acceptedVLine2.wire1Slope)); + double st3UWireSin = TMath::Sin(TMath::ATan(1./trackletU->acceptedULine3.wire1Slope)); + double st3VWireSin = TMath::Sin(TMath::ATan(1./trackletV->acceptedVLine3.wire1Slope)); + + double st2UWireCos = TMath::Cos(TMath::ATan(1./trackletU->acceptedULine2.wire1Slope)); + double st2VWireCos = TMath::Cos(TMath::ATan(1./trackletV->acceptedVLine2.wire1Slope)); + double st3UWireCos = TMath::Cos(TMath::ATan(1./trackletU->acceptedULine3.wire1Slope)); + double st3VWireCos = TMath::Cos(TMath::ATan(1./trackletV->acceptedVLine3.wire1Slope)); + + double testTY2 = ( trackletV->st2Vsl - (st2VWireCos/st2UWireCos)*trackletU->st2Usl )/( (st2VWireCos * st2UWireSin)/(st2UWireCos) - st2VWireSin ); + double testTY3 = ( trackletV->st3Vsl - (st3VWireCos/st3UWireCos)*trackletU->st3Usl )/( (st3VWireCos * st3UWireSin)/(st3UWireCos) - st3VWireSin ); + double testTX2 = ( trackletU->st2Usl - (st2UWireSin/st2VWireSin)*trackletV->st2Vsl )/( st2UWireCos - ( st2UWireSin * st2VWireCos )/st2VWireSin ); + double testTX3 = ( trackletU->st3Usl - (st3UWireSin/st3VWireSin)*trackletV->st3Vsl )/( st3UWireCos - ( st3UWireSin * st3VWireCos )/st3VWireSin ); + +#ifdef _DEBUG_PATRICK + std::cout<<"trackletV->st2Vsl = "<st2Vsl<<", trackletV->st3Vsl = "<st3Vsl<<", trackletU->st2Usl = "<st2Usl<<", trackletU->st3Usl = "<st3Usl<st2Xsl - testTX2) > 0.005 || std::abs(trackletX->st2Xsl - testTX3) > 0.005) continue; +#ifdef _DEBUG_PATRICK + LogInfo("past cont 2"); +#endif + //double posy = tracklet23->ty * ( z_plane[3] - tracklet23->st2Z ) + tracklet23->st2Y; //WPM + + double tracklet2Ys_D = 0.; //This is the sum of the Y-values of the hits in the U and V planes of the two tracklets. The sum is taken to be used in an average. The _D here stands for driftDistance. I originally did this part of the code without taking the drift distance in the slanted layers into account + double tracklet3Ys_D = 0.; + + for(unsigned int h = 0; h < trackletU->hits.size(); h++){ + double posx = trackletX->st2Xsl * (z_plane[(*trackletU).getHit(h).hit.detectorID] - trackletX->st2Z) + trackletX->st2X; + if((*trackletU).getHit(h).hit.detectorID == 17){ + tracklet2Ys_D += trackletU->acceptedULine2.wire1Slope * posx + trackletU->acceptedULine2.wireIntercept1; + } + if((*trackletU).getHit(h).hit.detectorID == 18){ + tracklet2Ys_D += trackletU->acceptedULine2.wire2Slope * posx + trackletU->acceptedULine2.wireIntercept2; + } + if((*trackletU).getHit(h).hit.detectorID == 19 || (*trackletU).getHit(h).hit.detectorID == 25){ + tracklet3Ys_D += trackletU->acceptedULine3.wire1Slope * posx + trackletU->acceptedULine3.wireIntercept1; + } + if((*trackletU).getHit(h).hit.detectorID == 20 || (*trackletU).getHit(h).hit.detectorID == 26){ + tracklet3Ys_D += trackletU->acceptedULine3.wire2Slope * posx + trackletU->acceptedULine3.wireIntercept2; + } + } + + for(unsigned int h = 0; h < trackletV->hits.size(); h++){ + double posx = trackletX->st2Xsl * (z_plane[(*trackletV).getHit(h).hit.detectorID] - trackletX->st2Z) + trackletX->st2X; + if((*trackletV).getHit(h).hit.detectorID == 13){ + tracklet2Ys_D += trackletV->acceptedVLine2.wire1Slope * posx + trackletV->acceptedVLine2.wireIntercept1; + } + if((*trackletV).getHit(h).hit.detectorID == 14){ + tracklet2Ys_D += trackletV->acceptedVLine2.wire2Slope * posx + trackletV->acceptedVLine2.wireIntercept2; + } + if((*trackletV).getHit(h).hit.detectorID == 23 || (*trackletV).getHit(h).hit.detectorID == 29){ + tracklet3Ys_D += trackletV->acceptedVLine3.wire1Slope * posx + trackletV->acceptedVLine3.wireIntercept1; + } + if((*trackletV).getHit(h).hit.detectorID == 24 || (*trackletV).getHit(h).hit.detectorID == 30){ + tracklet3Ys_D += trackletV->acceptedVLine3.wire2Slope * posx + trackletV->acceptedVLine3.wireIntercept2; + } + } + + double differentYSlope = (tracklet3Ys_D/4. - tracklet2Ys_D/4.)/(trackletX->st3Z - trackletX->st2Z); +#ifdef _DEBUG_PATRICK + std::cout<<"differentYSlope = "<st2Xsl; + //tracklet_TEST_23.ty = (differentYSlope + testTY2 + testTY3)/3.; + tracklet_TEST_23.ty = (testTY2 + testTY3)/2.; + tracklet_TEST_23.invP = 1./50.; + tracklet_TEST_23.x0 = trackletX->st2Xsl * (0. - trackletX->st2Z) + trackletX->st2X; + + tracklet_TEST_23.sortHits(); + + std::cout<<"about to test out y0 vals?"<st2Z; + tracklet_TEST_23.st2X = trackletX->st2X; + //tracklet_TEST_23.st2Y = tracklet2Ys_D/4.; + //tracklet_TEST_23.st3Y = tracklet3Ys_D/4.; + tracklet_TEST_23.st2Y = tracklet_TEST_23.y0 + tracklet_TEST_23.ty * tracklet_TEST_23.st2Z; + tracklet_TEST_23.st3Y = tracklet_TEST_23.y0 + tracklet_TEST_23.ty * trackletX->st3Z; + tracklet_TEST_23.st2U = trackletU->st2U; + tracklet_TEST_23.st2V = trackletV->st2V; + tracklet_TEST_23.st2Usl = trackletU->st2Usl; + tracklet_TEST_23.st2Vsl = trackletV->st2Vsl; + + + + + int hitCounter = 0; + //for(unsigned int h = 0; h < tracklet_TEST_23.hits.size(); h++){ + for(std::list::iterator hit1 = tracklet_TEST_23.hits.begin(); hit1 != tracklet_TEST_23.hits.end(); ++hit1){ + hit1->sign = candidateSigns.at(hitCounter); + hitCounter++; + } + tracklet_TEST_23.calcChisq(); +#ifdef _DEBUG_PATRICK + tracklet_TEST_23.print(); +#endif + + +#ifdef _DEBUG_PATRICK + LogInfo("now test my sign assignments"); + tracklet_TEST_23.print(); +#endif + + + + fitTracklet(tracklet_TEST_23); + +#ifdef _DEBUG_PATRICK + LogInfo("right after fitting"); + tracklet_TEST_23.print(); +#endif + + for(std::list::iterator hit1 = tracklet_TEST_23.hits.begin(); hit1 != tracklet_TEST_23.hits.end(); ++hit1){ + if(hit1->sign == 0){ + hit1->sign = 1; + double dcaPlus = p_geomSvc->getDCA(hit1->hit.detectorID, hit1->hit.elementID, tracklet_TEST_23.tx, tracklet_TEST_23.ty, tracklet_TEST_23.x0, tracklet_TEST_23.y0); + hit1->sign = -1; + double dcaMinus = p_geomSvc->getDCA(hit1->hit.detectorID, hit1->hit.elementID, tracklet_TEST_23.tx, tracklet_TEST_23.ty, tracklet_TEST_23.x0, tracklet_TEST_23.y0); + if(std::abs(dcaPlus) < std::abs(dcaMinus)){ + hit1->sign = 1; + } else{ + hit1->sign = -1; + } + } + } + + /* + if(!COARSE_MODE) + { + resolveLeftRight(tracklet_TEST_23, 40.); //resolveLeftRight at this stage is, in truth, not needed. We already know which side of the wire the particle passed by from compareTracklet. However, getting rid of this would take a bit of work + resolveLeftRight(tracklet_TEST_23, 150.); + } + */ + ///Remove bad hits if needed + removeBadHits(tracklet_TEST_23); + + fitTracklet(tracklet_TEST_23); //This is the fit that needs the seeded tx and ty information. Without the seed information, the fit occasionally finds bad slope and X0 or Y0 values, much in the same way that it does for single-station tracklets. Note from Patrick: this fit could probably be throw out, as we already know the tx and ty information from compareTracklets. I would just need to extrapolate back to z = 0 and calculate the chisq by hand + + + + + +#ifdef _DEBUG_PATRICK + LogInfo("after original resolve left-right and re-fitting"); + tracklet_TEST_23.print(); +#endif + + + + + + if(tracklet_TEST_23.chisq > 9000.) + { +#ifdef _DEBUG_ON + tracklet_TEST_23.print(); + LogInfo("Impossible combination!"); +#endif + continue; + } + +#ifdef _DEBUG_PATRICK + LogInfo("New tracklet: "); + tracklet_TEST_23.print(); + + LogInfo("Current best:"); + tracklet_best_UX.print(); + + LogInfo("Comparison: " << (tracklet_TEST_23 < tracklet_best_UX)); + LogInfo("Candidate chisq: " << tracklet_TEST_23.chisq); + LogInfo("Quality: " << acceptTracklet(tracklet_TEST_23)); +#endif + +#ifdef _DEBUG_PATRICK + LogInfo("going to print tracklet_best_UX"); + tracklet_best_UX.print(); + LogInfo("going to print tracklet_TEST_23"); + tracklet_TEST_23.print(); +#endif + if(!(tracklet_TEST_23 < tracklet_best_UX)) continue; + + //If current tracklet is better than the best tracklet up-to-now + if(acceptTracklet(tracklet_TEST_23) && tracklet_TEST_23 < tracklet_best_UX) + { +#ifdef _DEBUG_PATRICK + LogInfo("test 23 is best ux"); +#endif + tracklet_best_UX = tracklet_TEST_23; + } +#ifdef _DEBUG_ON + else + { + LogInfo("Rejected!!"); + } +#endif +#ifdef _DEBUG_PATRICK + LogInfo("end of V loop"); + LogInfo("going to print tracklet_best_UX"); + tracklet_best_UX.print(); + LogInfo("going to print tracklet_TEST_23"); + tracklet_TEST_23.print(); +#endif + } +#ifdef _DEBUG_PATRICK + LogInfo("through V loop"); +#endif + if(tracklet_best_UX < tracklet_best){ + tracklet_best = tracklet_best_UX; +#ifdef _DEBUG_PATRICK + LogInfo("past best ux"); +#endif + } +#ifdef _DEBUG_PATRICK + LogInfo("end of U loop"); +#endif + } +#ifdef _DEBUG_PATRICK + LogInfo("through U oop"); +#endif + if(acceptTracklet(tracklet_best)){ + if(tracklet_best.isValid() > 0){ +#ifdef _DEBUG_PATRICK + LogInfo("through isvalid"); +#endif + //std::cout<<"pushing back 2+3 tracklets with candidate with the following chisq: "<::iterator tracklet3 = trackletsInStSlimX[2].begin(); tracklet3 != trackletsInStSlimX[2].end(); ++tracklet3) + { + //tracklet3->print(); + /*if(!COARSE_MODE) + { + //Extract the X hits only from station-3 tracks + nHitsX3 = 0; + for(std::list::iterator ptr_hit = tracklet3->hits.begin(); ptr_hit != tracklet3->hits.end(); ++ptr_hit) + { + if(ptr_hit->hit.index < 0) continue; + if(p_geomSvc->getPlaneType(ptr_hit->hit.detectorID) == 1) + { + z_fit[nHitsX3] = z_plane[ptr_hit->hit.detectorID]; + x_fit[nHitsX3] = ptr_hit->hit.pos; + ++nHitsX3; + } + } + }*/ + + Tracklet tracklet_best; + for(std::list::iterator tracklet2 = trackletsInStSlimX[1].begin(); tracklet2 != trackletsInStSlimX[1].end(); ++tracklet2) + { + //tracklet2->print(); + /*if(!COARSE_MODE) + { + if(OLD_TRACKING){ + if(fabs(tracklet2->tx - tracklet3->tx) > 0.15 || fabs(tracklet2->ty - tracklet3->ty) > 0.1) continue; + } + //Extract the X hits from station-2 tracke + nHitsX2 = nHitsX3; + for(std::list::iterator ptr_hit = tracklet2->hits.begin(); ptr_hit != tracklet2->hits.end(); ++ptr_hit) + { + if(ptr_hit->hit.index < 0) continue; + if(p_geomSvc->getPlaneType(ptr_hit->hit.detectorID) == 1) + { + z_fit[nHitsX2] = z_plane[ptr_hit->hit.detectorID]; + x_fit[nHitsX2] = ptr_hit->hit.pos; + ++nHitsX2; + } + } + + //Apply a simple linear fit to get rough estimation of X-Z slope and intersection + chi2fit(nHitsX2, z_fit, x_fit, a, b); + if(fabs(a) > 2.*TX_MAX || fabs(b) > 2.*X0_MAX) continue; + + //Project to proportional tubes to see if there is enough + int nPropHits = 0; + for(int i = 0; i < 4; ++i) + { + double x_exp = a*z_mask[detectorIDs_muid[0][i] - nChamberPlanes - 1] + b; + for(std::list::iterator iter = hitIDs_muid[0][i].begin(); iter != hitIDs_muid[0][i].end(); ++iter) + { + if(fabs(hitAll[*iter].pos - x_exp) < 5.08) + { + ++nPropHits; + break; + } + } + if(nPropHits > 0) break; + } + if(!TRACK_ELECTRONS && nPropHits == 0) continue; //Turned off by Patrick for electron tracks + }*/ + + Tracklet tracklet_23; + if(OLD_TRACKING){ + tracklet_23 = (*tracklet2) + (*tracklet3); + } + else{ + if(compareTrackletsSlim(*tracklet2, *tracklet3, pass) || compareTrackletsSlim_3hits(*tracklet2, *tracklet3, pass)){ + tracklet_23 = (*tracklet2) + (*tracklet3); + tracklet_23.tx = tracklet2->tx; //This is needed to "seed" the tracklet fit that happens below. This tx and ty information is assigned in compareTracklets below + tracklet_23.st2X = tracklet2->st2X; + tracklet_23.st2Z = tracklet2->st2Z; + tracklet_23.st3X = tracklet3->st2X; + tracklet_23.st3Z = tracklet3->st2Z; + tracklet_23.st2Xsl = tracklet2->st2Xsl; + tracklet_23.st3Xsl = tracklet3->st2Xsl; + tracklet_23.acceptedXLine2 = tracklet2->acceptedXLine2; + tracklet_23.acceptedXLine3 = tracklet3->acceptedXLine3; + //std::cout<<"tracklet 2 tx is "<tx<<" and tracklet 3 tx is "<tx<st2X<<" and tracklet 3 st2X is "<st2X<print(); + tracklet3->print(); + LogInfo("Yield this combination:"); + tracklet_23.print(); +#endif + + trackletsInStSlimX[3].push_back(tracklet_23); + /*tracklet_23.ty = tracklet2->ty; + + tracklet_23.st2Z = tracklet2->st2Z; + tracklet_23.st2X = tracklet2->st2X; + tracklet_23.st2Y = tracklet2->st2Y; + tracklet_23.st3Y = tracklet2->st3Y; + tracklet_23.st2U = tracklet2->st2U; + tracklet_23.st2V = tracklet2->st2V; + tracklet_23.st2Usl = tracklet2->st2Usl; + tracklet_23.st2Vsl = tracklet2->st2Vsl;*/ + } + else{ + continue; + } + } + } + } + + //std::cout<<"Number of x pairs for 2+3 tracklets is "< 9000.) + { +#ifdef _DEBUG_ON + tracklet_23.print(); + LogInfo("Impossible combination!"); +#endif + continue; + } + + if(!COARSE_MODE && !hodoMask(tracklet_23)) + { +#ifdef _DEBUG_ON + LogInfo("Hodomasking failed!"); +#endif + continue; + } +#ifdef _DEBUG_ON + LogInfo("Hodomasking Scucess!"); +#endif + + if(!COARSE_MODE) + { + resolveLeftRight(tracklet_23, 40.); //resolveLeftRight at this stage is, in truth, not needed. We already know which side of the wire the particle passed by from compareTracklet. However, getting rid of this would take a bit of work + resolveLeftRight(tracklet_23, 150.); + } + + ///Remove bad hits if needed + removeBadHits(tracklet_23); + +#ifdef _DEBUG_ON + LogInfo("New tracklet: "); + tracklet_23.print(); + + LogInfo("Current best:"); + tracklet_best.print(); + + LogInfo("Comparison: " << (tracklet_23 < tracklet_best)); + LogInfo("Quality: " << acceptTracklet(tracklet_23)); +#endif + + //If current tracklet is better than the best tracklet up-to-now + if(acceptTracklet(tracklet_23) && tracklet_23 < tracklet_best) + { + tracklet_best = tracklet_23; + } +#ifdef _DEBUG_ON + else + { + LogInfo("Rejected!!"); + } +#endif + } + + if(tracklet_best.isValid() > 0) trackletsInSt[3].push_back(tracklet_best); + } + + reduceTrackletList(trackletsInSt[3]); + trackletsInSt[3].sort();*/ +} + +void KalmanFastTracking_NEW::buildBackPartialTracksSlimU(int pass) +{ + //Temporary container for a simple chisq fit + int nHitsX2, nHitsX3; + double z_fit[4], x_fit[4]; + double a, b; + + for(std::list::iterator tracklet3 = trackletsInStSlimU[2].begin(); tracklet3 != trackletsInStSlimU[2].end(); ++tracklet3) + { + Tracklet tracklet_best; + for(std::list::iterator tracklet2 = trackletsInStSlimU[1].begin(); tracklet2 != trackletsInStSlimU[1].end(); ++tracklet2) + { + Tracklet tracklet_23; + if(OLD_TRACKING){ + tracklet_23 = (*tracklet2) + (*tracklet3); + } + else{ + if(compareTrackletsSlimU(*tracklet2, *tracklet3, pass) || compareTrackletsSlimU_3hits(*tracklet2, *tracklet3, pass)){ + tracklet_23 = (*tracklet2) + (*tracklet3); + tracklet_23.tx = tracklet2->tx; //This is needed to "seed" the tracklet fit that happens below. This tx and ty information is assigned in compareTracklets below + tracklet_23.st2U = tracklet2->st2U; + tracklet_23.st2Z = tracklet2->st2Z; + tracklet_23.st3U = tracklet3->st2U; + tracklet_23.st3Z = tracklet3->st2Z; + tracklet_23.st2Usl = tracklet2->st2Usl; + tracklet_23.st3Usl = tracklet3->st2Usl; + tracklet_23.acceptedULine2 = tracklet2->acceptedULine2; + tracklet_23.acceptedULine3 = tracklet3->acceptedULine3; + //std::cout<<"tracklet 2 tx is "<tx<<" and tracklet 3 tx is "<tx<st2U<<" and tracklet 3 st2U is "<st2U<print(); + tracklet3->print(); + LogInfo("Yield this combination:"); + tracklet_23.print(); +#endif + + trackletsInStSlimU[3].push_back(tracklet_23); + /*tracklet_23.ty = tracklet2->ty; + + tracklet_23.st2Z = tracklet2->st2Z; + tracklet_23.st2X = tracklet2->st2X; + tracklet_23.st2Y = tracklet2->st2Y; + tracklet_23.st3Y = tracklet2->st3Y; + tracklet_23.st2U = tracklet2->st2U; + tracklet_23.st2V = tracklet2->st2V; + tracklet_23.st2Usl = tracklet2->st2Usl; + tracklet_23.st2Vsl = tracklet2->st2Vsl;*/ + } + else{ + continue; + } + } + } + } + + //std::cout<<"Number of U pairs for 2+3 tracklets is "<::iterator tracklet3 = trackletsInStSlimV[2].begin(); tracklet3 != trackletsInStSlimV[2].end(); ++tracklet3) + { + Tracklet tracklet_best; + for(std::list::iterator tracklet2 = trackletsInStSlimV[1].begin(); tracklet2 != trackletsInStSlimV[1].end(); ++tracklet2) + { + Tracklet tracklet_23; + if(OLD_TRACKING){ + tracklet_23 = (*tracklet2) + (*tracklet3); + } + else{ + if(compareTrackletsSlimV(*tracklet2, *tracklet3, pass) || compareTrackletsSlimV_3hits(*tracklet2, *tracklet3, pass)){ + tracklet_23 = (*tracklet2) + (*tracklet3); + tracklet_23.tx = tracklet2->tx; //This is needed to "seed" the tracklet fit that happens below. This tx and ty information is assigned in compareTracklets below + tracklet_23.st2V = tracklet2->st2V; + tracklet_23.st2Z = tracklet2->st2Z; + tracklet_23.st3V = tracklet3->st2V; + tracklet_23.st3Z = tracklet3->st2Z; + tracklet_23.st2Vsl = tracklet2->st2Vsl; + tracklet_23.st3Vsl = tracklet3->st2Vsl; + //std::cout<<"SECOND TEST OF LINE2 "<acceptedVLine2.wireHit1PosZ<acceptedVLine2; + //std::cout<<"THIRD TEST OF LINE2 "<acceptedVLine3; + //std::cout<<"tracklet 2 tx is "<tx<<" and tracklet 3 tx is "<tx<st2V<<" and tracklet 3 st2V is "<st2V<print(); + tracklet3->print(); + LogInfo("Yield this combination:"); + tracklet_23.print(); +#endif + + trackletsInStSlimV[3].push_back(tracklet_23); + /*tracklet_23.ty = tracklet2->ty; + + tracklet_23.st2Z = tracklet2->st2Z; + tracklet_23.st2X = tracklet2->st2X; + tracklet_23.st2Y = tracklet2->st2Y; + tracklet_23.st3Y = tracklet2->st3Y; + tracklet_23.st2U = tracklet2->st2U; + tracklet_23.st2V = tracklet2->st2V; + tracklet_23.st2Usl = tracklet2->st2Usl; + tracklet_23.st2Vsl = tracklet2->st2Vsl;*/ + } + else{ + continue; + } + } + } + } + + //std::cout<<"Number of V pairs for 2+3 tracklets is "<::iterator tracklet23 = trackletsInSt[3].begin(); tracklet23 != trackletsInSt[3].end(); ++tracklet23) + { + Tracklet tracklet_best[2]; + for(int i = 0; i < 2; ++i) //for two station-1 chambers + { + trackletsInSt[0].clear(); + if(!TRACK_DISPLACED){ + //Calculate the window in station 1 + if(KMAG_ON) + { + getSagittaWindowsInSt1(*tracklet23, pos_exp, window, i+1); + } + else + { + getExtrapoWindowsInSt1(*tracklet23, pos_exp, window, i+1); + } + } +#ifdef _DEBUG_ON + LogInfo("Using this back partial: "); + tracklet23->print(); + for(int j = 0; j < 3; j++) LogInfo("Extrapo: " << pos_exp[j] << " " << window[j]); +#endif + + _timers["global_st1"]->restart(); + if(!TRACK_DISPLACED){ + buildTrackletsInStation(i+1, 0, pos_exp, window); + } + if(TRACK_DISPLACED){ + buildTrackletsInStation(i+1, 0); + } + + _timers["global_st1"]->stop(); + + _timers["global_link"]->restart(); + Tracklet tracklet_best_prob, tracklet_best_vtx; + for(std::list::iterator tracklet1 = trackletsInSt[0].begin(); tracklet1 != trackletsInSt[0].end(); ++tracklet1) + { +#ifdef _DEBUG_ON + LogInfo("With this station 1 track:"); + tracklet1->print(); +#endif + + Tracklet tracklet_global = (*tracklet23) * (*tracklet1); + fitTracklet(tracklet_global); + if(!hodoMask(tracklet_global)) continue; + + ///Resolve the left-right with a tight pull cut, then a loose one, then resolve by single projections + if(!COARSE_MODE) + { + resolveLeftRight(tracklet_global, 75.); + resolveLeftRight(tracklet_global, 150.); + resolveSingleLeftRight(tracklet_global); + } + if(TRACK_DISPLACED){ + double firstChiSq = tracklet_global.calcChisq(); + Tracklet tracklet_global2 = (*tracklet23) * (*tracklet1); + tracklet_global2.setCharge(-1*tracklet_global2.getCharge()); /**By default, the value returned by getCharge is based on the x0 of the tracklet. For a particle produced at the target, this is a valid way to extract charge. However, for a displaced particle, the x0 does not tell you anything useful about the charge of the particle, which is why we need to check both possible charge values. getCharge is used later on when extracting certain track quality values, so using the wrong charge leads to tracks getting rejected due to poor quality values*/ + if(!COARSE_MODE) + { + resolveLeftRight(tracklet_global2, 75.); + resolveLeftRight(tracklet_global2, 150.); + resolveSingleLeftRight(tracklet_global2); + } + double secondChiSq = tracklet_global2.calcChisq(); + if(secondChiSq < firstChiSq){ + tracklet_global = tracklet_global2; + } + } + + ///Remove bad hits if needed + removeBadHits(tracklet_global); + + //Most basic cuts + if(!acceptTracklet(tracklet_global)) continue; + + //Get the tracklets that has the best prob + if(tracklet_global < tracklet_best_prob) tracklet_best_prob = tracklet_global; + + ///Set vertex information - only applied when KF is enabled + ///TODO: maybe in the future add a Genfit-based equivalent here, for now leave as is + if(enable_KF && NOT_DISPLACED) + { + _timers["global_kalman"]->restart(); + SRecTrack recTrack = processOneTracklet(tracklet_global); + _timers["global_kalman"]->stop(); + tracklet_global.chisq_vtx = recTrack.getChisqVertex(); + + if(recTrack.isValid() && tracklet_global.chisq_vtx < tracklet_best_vtx.chisq_vtx) tracklet_best_vtx = tracklet_global; + } + +#ifdef _DEBUG_ON + LogInfo("New tracklet: "); + tracklet_global.print(); + + LogInfo("Current best by prob:"); + tracklet_best_prob.print(); + + LogInfo("Comparison I: " << (tracklet_global < tracklet_best_prob)); + LogInfo("Quality I : " << acceptTracklet(tracklet_global)); + + if(enable_KF && NOT_DISPLACED) + { + LogInfo("Current best by vtx:"); + tracklet_best_vtx.print(); + + LogInfo("Comparison II: " << (tracklet_global.chisq_vtx < tracklet_best_vtx.chisq_vtx)); + //LogInfo("Quality II : " << recTrack.isValid()); + } +#endif + } + _timers["global_link"]->stop(); + + //The selection logic is, prefer the tracks with best p-value, as long as it's not low-pz + if(enable_KF && NOT_DISPLACED && tracklet_best_prob.isValid() > 0 && 1./tracklet_best_prob.invP > 18.) + { + tracklet_best[i] = tracklet_best_prob; + } + else if(enable_KF && NOT_DISPLACED && tracklet_best_vtx.isValid() > 0) //otherwise select the one with best vertex chisq, TODO: maybe add a z-vtx constraint + { + tracklet_best[i] = tracklet_best_vtx; + } + else if(tracklet_best_prob.isValid() > 0) //then fall back to the default only choice + { + tracklet_best[i] = tracklet_best_prob; + } + } + + //Merge the tracklets from two stations if necessary + Tracklet tracklet_merge; + if(fabs(tracklet_best[0].getMomentum() - tracklet_best[1].getMomentum())/tracklet_best[0].getMomentum() < MERGE_THRES) + { + //Merge the track and re-fit + tracklet_merge = tracklet_best[0].merge(tracklet_best[1]); + fitTracklet(tracklet_merge); + +#ifdef _DEBUG_ON + LogInfo("Merging two track candidates with momentum: " << tracklet_best[0].getMomentum() << " " << tracklet_best[1].getMomentum()); + LogInfo("tracklet_best_1:"); tracklet_best[0].print(); + LogInfo("tracklet_best_2:"); tracklet_best[1].print(); + LogInfo("tracklet_merge:"); tracklet_merge.print(); +#endif + } + + if(tracklet_merge.isValid() > 0 && tracklet_merge < tracklet_best[0] && tracklet_merge < tracklet_best[1]) + { +#ifdef _DEBUG_ON + LogInfo("Choose merged tracklet"); +#endif + trackletsInSt[4].push_back(tracklet_merge); + } + else if(tracklet_best[0].isValid() > 0 && tracklet_best[0] < tracklet_best[1]) + { +#ifdef _DEBUG_ON + LogInfo("Choose tracklet with station-0"); +#endif + trackletsInSt[4].push_back(tracklet_best[0]); + } + else if(tracklet_best[1].isValid() > 0) + { +#ifdef _DEBUG_ON + LogInfo("Choose tracklet with station-1"); +#endif + trackletsInSt[4].push_back(tracklet_best[1]); + } + } + + trackletsInSt[4].sort(); +} + + +void KalmanFastTracking_NEW::buildGlobalTracksDisplaced() +{ + double pos_exp[3], window[3]; + for(std::list::iterator tracklet23 = trackletsInSt[3].begin(); tracklet23 != trackletsInSt[3].end(); ++tracklet23) + { + + Tracklet tracklet_best_prob, tracklet_best_vtx; + + //std::cout<<"I'm testing backwards extrapolation... z_plane thing is "<tx * ( z_plane[3] - tracklet23->st2Z ) + tracklet23->st2X; //WPM pick up here. do u and v extrapolations + //std::cout<<"test of u extrapo. st2Usl = "<st2Usl<<" ( z_plane[(i)*6 + 0] - tracklet23->st2UZ ) = "<<( z_plane[3] - tracklet23->st2UZ )<<" tracklet23->st2U = "<st2U<st2Usl * ( z_plane[1] - tracklet23->st2Z ) + tracklet23->st2U; //WPM + double posv = tracklet23->st2Vsl * ( z_plane[5] - tracklet23->st2Z ) + tracklet23->st2V; //WPM + double posy = tracklet23->ty * ( z_plane[3] - tracklet23->st2Z ) + tracklet23->st2Y; //WPM + //std::cout<<"checking V extrapolation. tracklet23->st2Vsl: "<st2Vsl<<", ( z_plane[5] - tracklet23->st2Z ): "<<( z_plane[5] - tracklet23->st2Z )<<", tracklet23->st2V: "<st2V<ty * ( z_plane[3] - tracklet23->st2Z ) + tracklet23->st2Y<getCostheta(1)<<", "<getCostheta(2)<<", "<getCostheta(3)<<", "<getCostheta(4)<<", "<getCostheta(5)<<", "<getCostheta(6)<getSintheta(1)<<", "<getSintheta(2)<<", "<getSintheta(3)<<", "<getSintheta(4)<<", "<getSintheta(5)<<", "<getSintheta(6)<print(); + for(int j = 0; j < 3; j++) LogInfo("Extrapo: " << pos_exp[j] << " " << window[j]); +#endif + + (*tracklet23).setCharge(charges[ch]); //WPM + double expXZSlope = ((*tracklet23).tx - 0.002 * charges[ch]*pxSlices[pxs]); + + _timers["global_st1"]->restart(); + if(!TRACK_DISPLACED){ + buildTrackletsInStation(i+1, 0, pos_exp, window); + } + if(TRACK_DISPLACED){ + //(*tracklet23).setCharge(charges[ch]); //WPM + //tracklet23->print(); + pos_exp[0] = posx+charges[ch]*pxSlices[pxs]; + pos_exp[1] = p_geomSvc->getCostheta(1) * pos_exp[0] + p_geomSvc->getSintheta(1) * posy; + pos_exp[2] = p_geomSvc->getCostheta(5) * pos_exp[0] + p_geomSvc->getSintheta(5) * posy; + //std::cout<<"The window I'm using is centered at "<getCostheta(1) * pos_exp[0] + p_geomSvc->getSintheta(1) * posy<<", "<getCostheta(5) * pos_exp[0] + p_geomSvc->getSintheta(5) * posy<print()<stop(); + + _timers["global_link"]->restart(); + int tracklet_counter = 0; //WPM + +#ifdef _DEBUG_PATRICK + LogInfo("the size of trackletsInSt[0] is "<::iterator tracklet1 = trackletsInSt[0].begin(); tracklet1 != trackletsInSt[0].end(); ++tracklet1) + { +#ifdef _DEBUG_ON + LogInfo("a new station 1 tracklet global tracks displaced. trackletCounter = "<print(); + trackletCounter++; +#endif + /* + std::cout<<"PRINT possible x slopes"< 4) continue; + + for(std::list::iterator hit1 = tracklet1->hits.begin(); hit1 != tracklet1->hits.end(); ++hit1) + { + if(hit1->hit.detectorID == 4){ + if(bestTrackletX == 0){ + hit1->sign = 1; + } + if(bestTrackletX == 1){ + hit1->sign = 1; + } + if(bestTrackletX == 2){ + hit1->sign = -1; + } + if(bestTrackletX == 3){ + hit1->sign = -1; + } + } + if(hit1->hit.detectorID == 3){ + if(bestTrackletX == 0){ + hit1->sign = 1; + } + if(bestTrackletX == 1){ + hit1->sign = -1; + } + if(bestTrackletX == 2){ + hit1->sign = 1; + } + if(bestTrackletX == 3){ + hit1->sign = -1; + } + } + if(nValidUSlopes == 1){ + if(hit1->hit.detectorID == 1){ + if(bestTrackletU == 0){ + hit1->sign = 1; + } + if(bestTrackletU == 1){ + hit1->sign = 1; + } + if(bestTrackletU == 2){ + hit1->sign = -1; + } + if(bestTrackletU == 3){ + hit1->sign = -1; + } + } + if(hit1->hit.detectorID == 2){ + if(bestTrackletU == 0){ + hit1->sign = 1; + } + if(bestTrackletU == 1){ + hit1->sign = -1; + } + if(bestTrackletU == 2){ + hit1->sign = 1; + } + if(bestTrackletU == 3){ + hit1->sign = -1; + } + } + } + if(nValidVSlopes == 1){ + if(hit1->hit.detectorID == 5){ + if(bestTrackletV == 0){ + hit1->sign = 1; + } + if(bestTrackletV == 1){ + hit1->sign = 1; + } + if(bestTrackletV == 2){ + hit1->sign = -1; + } + if(bestTrackletV == 3){ + hit1->sign = -1; + } + } + if(hit1->hit.detectorID == 6){ + if(bestTrackletV == 0){ + hit1->sign = 1; + } + if(bestTrackletV == 1){ + hit1->sign = -1; + } + if(bestTrackletV == 2){ + hit1->sign = 1; + } + if(bestTrackletV == 3){ + hit1->sign = -1; + } + } + } + }*/ + + //tracklet1->tx = expXZSlope; + //tracklet1->ty = tracklet23->ty; + //tracklet1->x0 = tracklet23->x0; + //tracklet1->y0 = tracklet23->y0; + //tracklet1->setCharge(charges[ch]); //WPM + + //std::cout<<"I GOT A GOOD TRACKLETX"<print(); + //fitTracklet((*tracklet1)); + + //resolveLeftRight((*tracklet1), 75.); + //resolveLeftRight((*tracklet1), 150.); + + + tracklet_counter++; //WPM + //std::cout<<"try tracklet number "<print(); +#endif + + int unsignedHits = 0; + for(std::list::iterator hit1 = tracklet1->hits.begin(); hit1 != tracklet1->hits.end(); ++hit1) + { + if(hit1->sign == 0) unsignedHits++; + } + //if(unsignedHits>0){ + // for(std::list::iterator hit1 = tracklet1->hits.begin(); hit1 != tracklet1->hits.end(); ++hit1) + // { + // hit1->sign = 0; + // } + // tracklet1->tx = expXZSlope; + // tracklet1->ty = tracklet23->ty; + // tracklet1->x0 = tracklet23->x0; + // tracklet1->y0 = tracklet23->y0; + // tracklet1->setCharge(charges[ch]); //WPM + // fitTracklet((*tracklet1)); + //} + + //std::vector signs = {0,0,0,0,0,0}; + //for(std::list::iterator hit1 = tracklet1->hits.begin(); hit1 != tracklet1->hits.end(); ++hit1) + // { + // signs.at(hit1->hit.detectorID - 1) = hit1->sign; + // hit1->sign=0; + // } + + Tracklet tracklet_global = (*tracklet23) * (*tracklet1); + tracklet_global.setCharge(charges[ch]); //WPM + //std::cout<<"Prior to fitting my supposedly good station 7 tracklet, let's print it out:"<::iterator hit1 = tracklet_global.hits.begin(); hit1 != tracklet_global.hits.end(); ++hit1) + { + if(hit1->hit.detectorID == 3 || hit1->hit.detectorID == 4){ + hit1->sign = signs.at(hit1->hit.detectorID - 1); + } + }*/ + resolveLeftRight(tracklet_global, 75.); + resolveLeftRight(tracklet_global, 150.); + resolveSingleLeftRight(tracklet_global); + } + /*if(TRACK_DISPLACED){ + double firstChiSq = tracklet_global.calcChisq(); + Tracklet tracklet_global2 = (*tracklet23) * (*tracklet1); + tracklet_global2.setCharge(-1*tracklet_global2.getCharge()); //By default, the value returned by getCharge is based on the x0 of the tracklet. For a particle produced at the target, this is a valid way to extract charge. However, for a displaced particle, the x0 does not tell you anything useful about the charge of the particle, which is why we need to check both possible charge values. getCharge is used later on when extracting certain track quality values, so using the wrong charge leads to tracks getting rejected due to poor quality values + if(!COARSE_MODE) + { + resolveLeftRight(tracklet_global2, 75.); + resolveLeftRight(tracklet_global2, 150.); + resolveSingleLeftRight(tracklet_global2); + } + double secondChiSq = tracklet_global2.calcChisq(); + if(secondChiSq < firstChiSq){ + tracklet_global = tracklet_global2; + } + }*/ + + ///Remove bad hits if needed + removeBadHits(tracklet_global); + +#ifdef _DEBUG_ON + LogInfo("removed bad hits in global tracks displaced"); +#endif + + //Most basic cuts + if(!acceptTracklet(tracklet_global)) continue; + +#ifdef _DEBUG_ON + LogInfo("accepted tracklet global tracks displaced"); +#endif + + //Get the tracklets that has the best prob + if(tracklet_global < tracklet_best_prob) tracklet_best_prob = tracklet_global; + + ///Set vertex information - only applied when KF is enabled + ///TODO: maybe in the future add a Genfit-based equivalent here, for now leave as is + if(enable_KF && NOT_DISPLACED) + { + _timers["global_kalman"]->restart(); + SRecTrack recTrack = processOneTracklet(tracklet_global); + _timers["global_kalman"]->stop(); + tracklet_global.chisq_vtx = recTrack.getChisqVertex(); + + if(recTrack.isValid() && tracklet_global.chisq_vtx < tracklet_best_vtx.chisq_vtx) tracklet_best_vtx = tracklet_global; + } + +#ifdef _DEBUG_ON + LogInfo("New tracklet: "); + tracklet_global.print(); + + LogInfo("Current best by prob:"); + tracklet_best_prob.print(); + + LogInfo("Comparison I: " << (tracklet_global < tracklet_best_prob)); + LogInfo("Quality I : " << acceptTracklet(tracklet_global)); + + if(enable_KF && NOT_DISPLACED) + { + LogInfo("Current best by vtx:"); + tracklet_best_vtx.print(); + + LogInfo("Comparison II: " << (tracklet_global.chisq_vtx < tracklet_best_vtx.chisq_vtx)); + //LogInfo("Quality II : " << recTrack.isValid()); + } +#endif + } + //fitTracklet(tracklet_best_prob); + //std::cout<<"after refit"<stop(); + + //The selection logic is, prefer the tracks with best p-value, as long as it's not low-pz + if(enable_KF && NOT_DISPLACED && tracklet_best_prob.isValid() > 0 && 1./tracklet_best_prob.invP > 18.) + { + tracklet_best[i] = tracklet_best_prob; + //if(tracklet_best_prob.hits.size()==6) validTrackFound = true; + } + else if(enable_KF && NOT_DISPLACED && tracklet_best_vtx.isValid() > 0) //otherwise select the one with best vertex chisq, TODO: maybe add a z-vtx constraint + { + tracklet_best[i] = tracklet_best_vtx; + //if(tracklet_best_vtx.hits.size()==6) validTrackFound = true; + } + else if(tracklet_best_prob.isValid() > 0) //then fall back to the default only choice + { + tracklet_best[i] = tracklet_best_prob; + //if(tracklet_best_prob.hits.size()==6) validTrackFound = true; + } + } + if(tracklet_best_prob.chisq < 1.) break; + } + if(tracklet_best_prob.chisq < 1.) break; + } + + //Merge the tracklets from two stations if necessary + Tracklet tracklet_merge; + if(fabs(tracklet_best[0].getMomentum() - tracklet_best[1].getMomentum())/tracklet_best[0].getMomentum() < MERGE_THRES) + { + //Merge the track and re-fit + tracklet_merge = tracklet_best[0].merge(tracklet_best[1]); + fitTracklet(tracklet_merge); + +#ifdef _DEBUG_ON + LogInfo("Merging two track candidates with momentum: " << tracklet_best[0].getMomentum() << " " << tracklet_best[1].getMomentum()); + LogInfo("tracklet_best_1:"); tracklet_best[0].print(); + LogInfo("tracklet_best_2:"); tracklet_best[1].print(); + LogInfo("tracklet_merge:"); tracklet_merge.print(); +#endif + } + + if(tracklet_merge.isValid() > 0 && tracklet_merge < tracklet_best[0] && tracklet_merge < tracklet_best[1]) + { +#ifdef _DEBUG_ON + LogInfo("Choose merged tracklet"); +#endif + //tracklet_merge.tx = -0.022337; + //tracklet_merge.ty = -0.018866; + //tracklet_merge.x0 = 34.68; + //tracklet_merge.y0 = 19.815; + //tracklet_merge.invP = 0.06275; + //std::cout<<"I forced the tracklet to behave. Now chisq = "< 0 && tracklet_best[0] < tracklet_best[1]) + { +#ifdef _DEBUG_ON + LogInfo("Choose tracklet with station-0"); +#endif + //tracklet_best[0].tx = -0.022337; + //tracklet_best[0].ty = -0.018866; + //tracklet_best[0].x0 = 34.68; + //tracklet_best[0].y0 = 19.815; + //tracklet_best[0].invP = 0.06275; + //std::cout<<"I forced the tracklet to behave. Now chisq = "< 0) + { +#ifdef _DEBUG_ON + LogInfo("Choose tracklet with station-1"); +#endif + //tracklet_best[1].tx = -0.022337; + //tracklet_best[1].ty = -0.018866; + //tracklet_best[1].x0 = 34.68; + //tracklet_best[1].y0 = 19.815; + //tracklet_best[1].invP = 0.06275; + //std::cout<<"I forced the tracklet to behave. Now chisq = "<::iterator hit1 = tracklet.hits.begin(); + std::list::iterator hit2 = tracklet.hits.begin(); + ++hit2; + while(true) + { +#ifdef _DEBUG_ON + LogInfo(hit1->hit.index << " " << hit2->sign << " === " << hit2->hit.index << " " << hit2->sign); + int detectorID1 = hit1->hit.detectorID; + int detectorID2 = hit2->hit.detectorID; + LogInfo("Hit1: " << tracklet.getExpPositionX(z_plane[detectorID1])*costheta_plane[detectorID1] + tracklet.getExpPositionY(z_plane[detectorID1])*sintheta_plane[detectorID1] << " " << hit1->hit.pos + hit1->hit.driftDistance << " " << hit1->hit.pos - hit1->hit.driftDistance); + LogInfo("Hit2: " << tracklet.getExpPositionX(z_plane[detectorID2])*costheta_plane[detectorID2] + tracklet.getExpPositionY(z_plane[detectorID2])*sintheta_plane[detectorID2] << " " << hit2->hit.pos + hit2->hit.driftDistance << " " << hit2->hit.pos - hit2->hit.driftDistance); +#endif + + if(hit1->hit.index > 0 && hit2->hit.index > 0 && hit1->sign*hit2->sign == 0) + { + int index_min = -1; + double pull_min = 1E6; + for(int i = 0; i < 4; i++) + { + double slope_local = (hit1->pos(possibility[i][0]) - hit2->pos(possibility[i][1]))/(z_plane[hit1->hit.detectorID] - z_plane[hit2->hit.detectorID]); + double inter_local = hit1->pos(possibility[i][0]) - slope_local*z_plane[hit1->hit.detectorID]; + + if(fabs(slope_local) > slope_max[hit1->hit.detectorID] || fabs(inter_local) > intersection_max[hit1->hit.detectorID]) continue; + + double tx, ty, x0, y0; + double err_tx, err_ty, err_x0, err_y0; + if(tracklet.stationID == 7 && hit1->hit.detectorID <= 6) + { + tracklet.getXZInfoInSt1(tx, x0); + tracklet.getXZErrorInSt1(err_tx, err_x0); + } + else + { + tx = tracklet.tx; + x0 = tracklet.x0; + err_tx = tracklet.err_tx; + err_x0 = tracklet.err_x0; + } + ty = tracklet.ty; + y0 = tracklet.y0; + err_ty = tracklet.err_ty; + err_y0 = tracklet.err_y0; + + double slope_exp = costheta_plane[hit1->hit.detectorID]*tx + sintheta_plane[hit1->hit.detectorID]*ty; + double err_slope = fabs(costheta_plane[hit1->hit.detectorID]*err_tx) + fabs(sintheta_plane[hit2->hit.detectorID]*err_ty); + double inter_exp = costheta_plane[hit1->hit.detectorID]*x0 + sintheta_plane[hit1->hit.detectorID]*y0; + double err_inter = fabs(costheta_plane[hit1->hit.detectorID]*err_x0) + fabs(sintheta_plane[hit2->hit.detectorID]*err_y0); + + double pull = sqrt((slope_exp - slope_local)*(slope_exp - slope_local)/err_slope/err_slope + (inter_exp - inter_local)*(inter_exp - inter_local)/err_inter/err_inter); + if(pull < pull_min) + { + index_min = i; + pull_min = pull; + } + +#ifdef _DEBUG_ON + LogInfo(hit1->hit.detectorID << ": " << i << " " << possibility[i][0] << " " << possibility[i][1]); + LogInfo(tx << " " << x0 << " " << ty << " " << y0); + LogInfo("Slope: " << slope_local << " " << slope_exp << " " << err_slope); + LogInfo("Intersection: " << inter_local << " " << inter_exp << " " << err_inter); + LogInfo("Current: " << pull << " " << index_min << " " << pull_min); +#endif + } + + //LogInfo("Final: " << index_min << " " << pull_min); + if(index_min >= 0 && pull_min < threshold)//((tracklet.stationID == 5 && pull_min < 25.) || (tracklet.stationID == 6 && pull_min < 100.))) + { + hit1->sign = possibility[index_min][0]; + hit2->sign = possibility[index_min][1]; + isUpdated = true; + } + } + + ++nResolved; + if(nResolved >= nPairs) break; + + ++hit1; + ++hit1; + ++hit2; + ++hit2; + } + + if(isUpdated) fitTracklet(tracklet); +} + +void KalmanFastTracking_NEW::resolveSingleLeftRight(Tracklet& tracklet) +{ +#ifdef _DEBUG_ON + LogInfo("Single left right for this track.."); + tracklet.print(); +#endif + + //Check if the track has been updated + bool isUpdated = false; + for(std::list::iterator hit_sign = tracklet.hits.begin(); hit_sign != tracklet.hits.end(); ++hit_sign) + { + if(hit_sign->hit.index < 0 || hit_sign->sign != 0) continue; + + int detectorID = hit_sign->hit.detectorID; + double pos_exp = tracklet.getExpPositionX(z_plane[detectorID])*costheta_plane[detectorID] + tracklet.getExpPositionY(z_plane[detectorID])*sintheta_plane[detectorID]; + hit_sign->sign = pos_exp > hit_sign->hit.pos ? 1 : -1; + + isUpdated = true; + } + + if(isUpdated) fitTracklet(tracklet); +} + +void KalmanFastTracking_NEW::removeBadHits(Tracklet& tracklet) +{ +#ifdef _DEBUG_ON + LogInfo("Removing hits for this track.."); + tracklet.calcChisq(); + tracklet.print(); +#endif + + //Check if the track has beed updated + int signflipflag[nChamberPlanes]; + for(int i = 0; i < nChamberPlanes; ++i) signflipflag[i] = 0; + + bool isUpdated = true; + while(isUpdated) + { + isUpdated = false; + tracklet.calcChisq(); + + SignedHit* hit_remove = nullptr; + SignedHit* hit_neighbour = nullptr; + double res_remove1 = -1.; + double res_remove2 = -1.; + for(std::list::iterator hit_sign = tracklet.hits.begin(); hit_sign != tracklet.hits.end(); ++hit_sign) + { + if(hit_sign->hit.index < 0) continue; + + int detectorID = hit_sign->hit.detectorID; + double res_curr = fabs(tracklet.residual[detectorID-1]); + if(res_remove1 < res_curr) + { + res_remove1 = res_curr; + res_remove2 = fabs(tracklet.residual[detectorID-1] - 2.*hit_sign->sign*hit_sign->hit.driftDistance); + hit_remove = &(*hit_sign); + + std::list::iterator iter = hit_sign; + hit_neighbour = detectorID % 2 == 0 ? &(*(--iter)) : &(*(++iter)); + } + } + if(hit_remove == nullptr) continue; + if(hit_remove->sign == 0 && tracklet.isValid() > 0) continue; //if sign is undecided, and chisq is OKay, then pass + + double cut = hit_remove->sign == 0 ? hit_remove->hit.driftDistance + resol_plane[hit_remove->hit.detectorID] : resol_plane[hit_remove->hit.detectorID]; + if(res_remove1 > cut) + { +#ifdef _DEBUG_ON + LogInfo("Dropping this hit: " << res_remove1 << " " << res_remove2 << " " << signflipflag[hit_remove->hit.detectorID-1] << " " << cut); + hit_remove->hit.print(); + hit_neighbour->hit.print(); +#endif + + //can only be changed less than twice + if(res_remove2 < cut && signflipflag[hit_remove->hit.detectorID-1] < 2) + { + hit_remove->sign = -hit_remove->sign; + hit_neighbour->sign = 0; + ++signflipflag[hit_remove->hit.detectorID-1]; +#ifdef _DEBUG_ON + LogInfo("Only changing the sign."); +#endif + } + else + { + //Set the index of the hit to be removed to -1 so it's not used anymore + //also set the sign assignment of the neighbour hit to 0 (i.e. undecided) + hit_remove->hit.index = -1; + hit_neighbour->sign = 0; + int planeType = p_geomSvc->getPlaneType(hit_remove->hit.detectorID); + if(planeType == 1) + { + --tracklet.nXHits; + } + else if(planeType == 2) + { + --tracklet.nUHits; + } + else + { + --tracklet.nVHits; + } + + //If both hit pairs are not included, the track can be rejected + if(hit_neighbour->hit.index < 0) + { +#ifdef _DEBUG_ON + LogInfo("Both hits in a view are missing! Will exit the bad hit removal..."); +#endif + return; + } + } + isUpdated = true; + } + + if(isUpdated) + { + fitTracklet(tracklet); + resolveSingleLeftRight(tracklet); + } + } +} + +void KalmanFastTracking_NEW::resolveLeftRight(SRawEvent::hit_pair hpair, int& LR1, int& LR2) +{ + LR1 = 0; + LR2 = 0; + + //If either hit is missing, no left-right can be assigned + if(hpair.first < 0 || hpair.second < 0) + { + return; + } + + int possibility[4][2] = {{1, 1}, {1, -1}, {-1, 1}, {-1, -1}}; + int nResolved = 0; + for(int i = 0; i < 4; i++) + { + if(nResolved > 1) break; + + int hitID1 = hpair.first; + int hitID2 = hpair.second; + double slope_local = (hitAll[hitID1].pos + possibility[i][0]*hitAll[hitID1].driftDistance - hitAll[hitID2].pos - possibility[i][1]*hitAll[hitID2].driftDistance)/(z_plane[hitAll[hitID1].detectorID] - z_plane[hitAll[hitID2].detectorID]); + double intersection_local = hitAll[hitID1].pos + possibility[i][0]*hitAll[hitID1].driftDistance - slope_local*z_plane[hitAll[hitID1].detectorID]; + + //LogInfo(i << " " << nResolved << " " << slope_local << " " << intersection_local); + if(fabs(slope_local) < slope_max[hitAll[hitID1].detectorID] && fabs(intersection_local) < intersection_max[hitAll[hitID1].detectorID]) + { + nResolved++; + LR1 = possibility[i][0]; + LR2 = possibility[i][1]; + } + } + + if(nResolved > 1) + { + LR1 = 0; + LR2 = 0; + } + + //LogInfo("Final: " << LR1 << " " << LR2); +} + +void KalmanFastTracking_NEW::buildTrackletsInStation(int stationID, int listID, double* pos_exp, double* window) +{ +#ifdef _DEBUG_ON + LogInfo("Building tracklets in station " << stationID); +#endif + + //actuall ID of the tracklet lists + int sID = stationID - 1; + + //Extract the X, U, V hit pairs + std::list pairs_X, pairs_U, pairs_V; + if(pos_exp == nullptr) + { + pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0]); + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1]); + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2]); + } + else + { + //Note that in pos_exp[], index 0 stands for X, index 1 stands for U, index 2 stands for V + pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0], pos_exp[0], window[0]); + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1], pos_exp[1], window[1]); + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2], pos_exp[2], window[2]); + } + +#ifdef _DEBUG_ON + LogInfo("Hit pairs in this event: "); + for(std::list::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_U.begin(); iter != pairs_U.end(); ++iter) LogInfo("U :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_V.begin(); iter != pairs_V.end(); ++iter) LogInfo("V :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif + + if(pairs_X.empty() || pairs_U.empty() || pairs_V.empty()) + { +#ifdef _DEBUG_ON + LogInfo("Not all view has hits in station " << stationID); +#endif + return; + } + + //X-U combination first, then add V pairs + for(std::list::iterator xiter = pairs_X.begin(); xiter != pairs_X.end(); ++xiter) + { + //U projections from X plane + double x_pos = xiter->second >= 0 ? 0.5*(hitAll[xiter->first].pos + hitAll[xiter->second].pos) : hitAll[xiter->first].pos; + double u_min = x_pos*u_costheta[sID] - u_win[sID]; + double u_max = u_min + 2.*u_win[sID]; + +#ifdef _DEBUG_ON + LogInfo("Trying X hits " << xiter->first << " " << xiter->second << " " << hitAll[xiter->first].elementID << " at " << x_pos); + LogInfo("U plane window:" << u_min << " " << u_max); +#endif + for(std::list::iterator uiter = pairs_U.begin(); uiter != pairs_U.end(); ++uiter) + { + double u_pos = uiter->second >= 0 ? 0.5*(hitAll[uiter->first].pos + hitAll[uiter->second].pos) : hitAll[uiter->first].pos; +#ifdef _DEBUG_ON + LogInfo("Trying U hits " << uiter->first << " " << uiter->second << " " << hitAll[uiter->first].elementID << " at " << u_pos); +#endif + if(u_pos < u_min || u_pos > u_max) continue; + + //V projections from X and U plane + double z_x = xiter->second >= 0 ? z_plane_x[sID] : z_plane[hitAll[xiter->first].detectorID]; + double z_u = uiter->second >= 0 ? z_plane_u[sID] : z_plane[hitAll[uiter->first].detectorID]; + double z_v = z_plane_v[sID]; + double v_win1 = spacing_plane[hitAll[uiter->first].detectorID]*2.*u_costheta[sID]; + double v_win2 = fabs((z_u + z_v - 2.*z_x)*u_costheta[sID]*TX_MAX); + double v_win3 = fabs((z_v - z_u)*u_sintheta[sID]*TY_MAX); + double v_win = v_win1 + v_win2 + v_win3 + 2.*spacing_plane[hitAll[uiter->first].detectorID]; + double v_min = 2*x_pos*u_costheta[sID] - u_pos - v_win; + double v_max = v_min + 2.*v_win; + +#ifdef _DEBUG_ON + LogInfo("V plane window:" << v_min << " " << v_max); +#endif + for(std::list::iterator viter = pairs_V.begin(); viter != pairs_V.end(); ++viter) + { + double v_pos = viter->second >= 0 ? 0.5*(hitAll[viter->first].pos + hitAll[viter->second].pos) : hitAll[viter->first].pos; +#ifdef _DEBUG_ON + LogInfo("Trying V hits " << viter->first << " " << viter->second << " " << hitAll[viter->first].elementID << " at " << v_pos); +#endif + if(v_pos < v_min || v_pos > v_max) continue; + + //Now add the tracklet + int LR1 = 0; + int LR2 = 0; + Tracklet tracklet_new; + tracklet_new.stationID = stationID; + + //resolveLeftRight(*xiter, LR1, LR2); + if(xiter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->first], LR1)); + tracklet_new.nXHits++; + } + if(xiter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->second], LR2)); + tracklet_new.nXHits++; + } + if(!OLD_TRACKING){ + tracklet_new.getSlopesX(hitAll[xiter->first], hitAll[xiter->second]); //Here, we find the four possible X-Z lines + } + //resolveLeftRight(*uiter, LR1, LR2); + if(uiter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[uiter->first], LR1)); + tracklet_new.nUHits++; + } + if(uiter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[uiter->second], LR2)); + tracklet_new.nUHits++; + } + if(!OLD_TRACKING){ + tracklet_new.getSlopesU(hitAll[uiter->first], hitAll[uiter->second]); //find the four possible U-Z lines + } + + //resolveLeftRight(*viter, LR1, LR2); + if(viter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[viter->first], LR1)); + tracklet_new.nVHits++; + } + if(viter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[viter->second], LR2)); + tracklet_new.nVHits++; + } + if(!OLD_TRACKING){ + tracklet_new.getSlopesV(hitAll[viter->first], hitAll[viter->second]); //find the four possible V-Z lines + } + + tracklet_new.sortHits(); + if(tracklet_new.isValid() == 0) //TODO: What IS THIS? + { + fitTracklet(tracklet_new); //This is where the original DCA minimization is performed + } + else + { + continue; + } + +#ifdef _DEBUG_ON + tracklet_new.print(); +#endif + if(acceptTracklet(tracklet_new)) + { + trackletsInSt[listID].push_back(tracklet_new); + } +#ifdef _DEBUG_ON + else + { + LogInfo("Rejected!!!"); + } +#endif + } + } + } + + //Reduce the tracklet list and add dummy hits + //reduceTrackletList(trackletsInSt[listID]); + for(std::list::iterator iter = trackletsInSt[listID].begin(); iter != trackletsInSt[listID].end(); ++iter) + { + iter->addDummyHits(); + } + + //Only retain the best 200 tracklets if exceeded + //std::cout<<"NUMBER of tracklets before resize = "< 1000) + { + trackletsInSt[listID].sort(); + trackletsInSt[listID].resize(1000); + } +} + + + +bool KalmanFastTracking_NEW::buildTrackletsInStation1(int stationID, int listID, double expXZSlope, double expYSlope, double y0, double* pos_exp, double* window) +{ +#ifdef _DEBUG_ON + LogInfo("Building tracklets in station " << stationID); +#endif + +#ifdef _DEBUG_PATRICK + std::cout<<"test sines and cosines"<getSintheta(1)<getSintheta(5)<::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif +#ifdef _DEBUG_PATRICK + LogInfo("Hit pairs in this event: "); + for(std::list::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif + + //if(pairs_X.empty() || pairs_U.empty() || pairs_V.empty()) + if(pairs_X.empty()) + { +#ifdef _DEBUG_ON + LogInfo("Not all view has hits in station " << stationID); +#endif + return st1TrackletFound; + } + + //X-U combination first, then add V pairs + for(std::list::iterator xiter = pairs_X.begin(); xiter != pairs_X.end(); ++xiter) + { + + if(!(xiter->first >= 0) || !(xiter->second >= 0)) continue; + + //make a tracklet + int LR1 = 0; + int LR2 = 0; + Tracklet tracklet_new; + tracklet_new.stationID = stationID; + + //resolveLeftRight(*xiter, LR1, LR2); + if(xiter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->first], LR1)); + tracklet_new.nXHits++; + } + if(xiter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->second], LR2)); + tracklet_new.nXHits++; + } + if(!OLD_TRACKING){ + tracklet_new.getSlopesX(hitAll[xiter->first], hitAll[xiter->second]); //Here, we find the four possible X-Z lines + } + + double bestSlopeDiffX = 1.0; + double slopeDiffX = 1.0; + int bestTrackletX = 5; + double trackletXslope = 1.0; + int nValidXSlopes = 0; + for(int t3 = 0; t3 < tracklet_new.possibleXLines.size(); t3++){ + //std::cout< 4) continue; + + if(pos_exp == nullptr) + { + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1]); + } + else + { + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1], pos_exp[1], window[1]); + } + +#ifdef _DEBUG_ON + LogInfo("Hit pairs in this event: "); + for(std::list::iterator iter = pairs_U.begin(); iter != pairs_U.end(); ++iter) LogInfo("U :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif +#ifdef _DEBUG_PATRICK + LogInfo("Hit pairs in this event: "); + for(std::list::iterator iter = pairs_U.begin(); iter != pairs_U.end(); ++iter) LogInfo("U :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif + + //U projections from X plane + double x_pos = xiter->second >= 0 ? 0.5*(hitAll[xiter->first].pos + hitAll[xiter->second].pos) : hitAll[xiter->first].pos; + double u_min = x_pos*u_costheta[sID] - u_win[sID]; + double u_max = u_min + 2.*u_win[sID]; + +#ifdef _DEBUG_ON + LogInfo("Trying X hits " << xiter->first << " " << xiter->second << " " << hitAll[xiter->first].elementID << " at " << x_pos); + LogInfo("U plane window:" << u_min << " " << u_max); +#endif + for(std::list::iterator uiter = pairs_U.begin(); uiter != pairs_U.end(); ++uiter) + { + + if(!(uiter->first >= 0) || !(uiter->second >= 0)) continue; + + double u_pos = uiter->second >= 0 ? 0.5*(hitAll[uiter->first].pos + hitAll[uiter->second].pos) : hitAll[uiter->first].pos; +#ifdef _DEBUG_ON + LogInfo("Trying U hits " << uiter->first << " " << uiter->second << " " << hitAll[uiter->first].elementID << " at " << u_pos); +#endif + if(u_pos < u_min || u_pos > u_max) continue; + + + Tracklet tracklet_newU; + tracklet_newU = tracklet_new; + if(uiter->first >= 0) + { + tracklet_newU.hits.push_back(SignedHit(hitAll[uiter->first], LR1)); + tracklet_newU.nUHits++; + } + if(uiter->second >= 0) + { + tracklet_newU.hits.push_back(SignedHit(hitAll[uiter->second], LR2)); + tracklet_newU.nUHits++; + } + if(!OLD_TRACKING){ + tracklet_newU.getSlopesU(hitAll[uiter->first], hitAll[uiter->second]); //find the four possible U-Z lines + } + + + double bestSlopeDiffU = 1.0; + double slopeDiffU = 1.0; + int bestTrackletU = 5; + double trackletUslope = 1.0; + int nValidUSlopes = 0; + for(int t3 = 0; t3 < tracklet_newU.possibleULines.size(); t3++){ + slopeDiffU = tracklet_newU.possibleULines.at(t3).slopeU - testTU; + if(std::abs(slopeDiffU)<0.01) nValidUSlopes++; + if(std::abs(slopeDiffU)<0.01 && std::abs(slopeDiffU) 4) continue; + + + /*int nValidUSlopes = 0; + int bestTrackletU = 5; + for(int t3 = 0; t3 < tracklet_newU.possibleULines.size(); t3++){ + std::cout<<"here is a u test. testtu is "<getPartialHitPairsInSuperDetector(superIDs[sID][2]); + } + else + { + //Note that in pos_exp[], index 0 stands for X, index 1 stands for U, index 2 stands for V + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2], pos_exp[2], window[2]); + } + +#ifdef _DEBUG_ON + LogInfo("Hit pairs in this event: "); + for(std::list::iterator iter = pairs_V.begin(); iter != pairs_V.end(); ++iter) LogInfo("V :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif +#ifdef _DEBUG_PATRICK + LogInfo("Hit pairs in this event: "); + for(std::list::iterator iter = pairs_V.begin(); iter != pairs_V.end(); ++iter) LogInfo("V :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif + + + + //V projections from X and U plane + double z_x = xiter->second >= 0 ? z_plane_x[sID] : z_plane[hitAll[xiter->first].detectorID]; + double z_u = uiter->second >= 0 ? z_plane_u[sID] : z_plane[hitAll[uiter->first].detectorID]; + double z_v = z_plane_v[sID]; + double v_win1 = spacing_plane[hitAll[uiter->first].detectorID]*2.*u_costheta[sID]; + double v_win2 = fabs((z_u + z_v - 2.*z_x)*u_costheta[sID]*TX_MAX); + double v_win3 = fabs((z_v - z_u)*u_sintheta[sID]*TY_MAX); + double v_win = v_win1 + v_win2 + v_win3 + 2.*spacing_plane[hitAll[uiter->first].detectorID]; + double v_min = 2*x_pos*u_costheta[sID] - u_pos - v_win; + double v_max = v_min + 2.*v_win; + +#ifdef _DEBUG_ON + LogInfo("V plane window:" << v_min << " " << v_max); +#endif + for(std::list::iterator viter = pairs_V.begin(); viter != pairs_V.end(); ++viter) + { + + if(!(viter->first >= 0) || !(viter->second >= 0)) continue; + + double v_pos = viter->second >= 0 ? 0.5*(hitAll[viter->first].pos + hitAll[viter->second].pos) : hitAll[viter->first].pos; +#ifdef _DEBUG_ON + LogInfo("Trying V hits " << viter->first << " " << viter->second << " " << hitAll[viter->first].elementID << " at " << v_pos); +#endif + if(v_pos < v_min || v_pos > v_max) continue; + + + Tracklet tracklet_newV; + tracklet_newV = tracklet_newU; + //tracklet_newV.stationID = stationID; + + + //resolveLeftRight(*viter, LR1, LR2); + if(viter->first >= 0) + { + tracklet_newV.hits.push_back(SignedHit(hitAll[viter->first], LR1)); + tracklet_newV.nVHits++; + } + if(viter->second >= 0) + { + tracklet_newV.hits.push_back(SignedHit(hitAll[viter->second], LR2)); + tracklet_newV.nVHits++; + } + if(!OLD_TRACKING){ + tracklet_newV.getSlopesV(hitAll[viter->first], hitAll[viter->second]); //find the four possible V-Z lines + } + + + double bestSlopeDiffV = 1.0; + double slopeDiffV = 1.0; + int bestTrackletV = 5; + double trackletVslope = 1.0; + int nValidVSlopes = 0; + for(int t3 = 0; t3 < tracklet_newV.possibleVLines.size(); t3++){ + slopeDiffV = tracklet_newV.possibleVLines.at(t3).slopeV - testTV; + if(std::abs(slopeDiffV)<0.01) nValidVSlopes++; + if(std::abs(slopeDiffV)<0.01 && std::abs(slopeDiffV) 4) continue; + + + + /*int nValidVSlopes = 0; + int bestTrackletV = 5; + for(int t3 = 0; t3 < tracklet_newV.possibleVLines.size(); t3++){ + std::cout<<"here is a v test. testtv is "<::iterator hit1 = tracklet_newV.hits.begin(); hit1 != tracklet_newV.hits.end(); ++hit1) + { + if(nValidXSlopes == 1){ + if(hit1->hit.detectorID == 4){ + if(bestTrackletX == 0){ + hit1->sign = 1; + } + if(bestTrackletX == 1){ + hit1->sign = -1; + } + if(bestTrackletX == 2){ + hit1->sign = 1; + } + if(bestTrackletX == 3){ + hit1->sign = -1; + } + } + if(hit1->hit.detectorID == 3){ + if(bestTrackletX == 0){ + hit1->sign = 1; + } + if(bestTrackletX == 1){ + hit1->sign = 1; + } + if(bestTrackletX == 2){ + hit1->sign = -1; + } + if(bestTrackletX == 3){ + hit1->sign = -1; + } + } + } + if(nValidUSlopes == 1){ + if(hit1->hit.detectorID == 1){ + if(bestTrackletU == 0){ + hit1->sign = 1; + } + if(bestTrackletU == 1){ + hit1->sign = -1; + } + if(bestTrackletU == 2){ + hit1->sign = 1; + } + if(bestTrackletU == 3){ + hit1->sign = -1; + } + } + if(hit1->hit.detectorID == 2){ + if(bestTrackletU == 0){ + hit1->sign = 1; + } + if(bestTrackletU == 1){ + hit1->sign = 1; + } + if(bestTrackletU == 2){ + hit1->sign = -1; + } + if(bestTrackletU == 3){ + hit1->sign = -1; + } + } + } + if(nValidVSlopes == 1){ + if(hit1->hit.detectorID == 5){ + if(bestTrackletV == 0){ + hit1->sign = 1; + } + if(bestTrackletV == 1){ + hit1->sign = -1; + } + if(bestTrackletV == 2){ + hit1->sign = 1; + } + if(bestTrackletV == 3){ + hit1->sign = -1; + } + } + if(hit1->hit.detectorID == 6){ + if(bestTrackletV == 0){ + hit1->sign = 1; + } + if(bestTrackletV == 1){ + hit1->sign = 1; + } + if(bestTrackletV == 2){ + hit1->sign = -1; + } + if(bestTrackletV == 3){ + hit1->sign = -1; + } + } + } + } + + trackletsInSt[listID].push_back(tracklet_newV); + + } + } + } + + //Reduce the tracklet list and add dummy hits + //reduceTrackletList(trackletsInSt[listID]); + for(std::list::iterator iter = trackletsInSt[listID].begin(); iter != trackletsInSt[listID].end(); ++iter) + { + iter->addDummyHits(); + } + + //std::cout<<"NUMBER of tracklets before resize = "<getSintheta(1)<getSintheta(5)<possibleXLines.at(t3).slopeX - expXZSlope<possibleXLines.at(t3).slopeX - expXZSlope; + if(std::abs(slopeDiffX)<0.0095) nValidXSlopes++; + if(std::abs(slopeDiffX)<0.0095 && std::abs(slopeDiffX)possibleXLines.at(t3).slopeX; + } + } + + if(bestTrackletX > 4){ + continue; + } else{ + for(std::list::iterator hit1 = trackletX->hits.begin(); hit1 != trackletX->hits.end(); ++ hit1) + { + if(hit1->hit.detectorID == 4){ + if(bestTrackletX == 0){ + hit1->sign = 1; + } + if(bestTrackletX == 1){ + hit1->sign = -1; + } + if(bestTrackletX == 2){ + hit1->sign = 1; + } + if(bestTrackletX == 3){ + hit1->sign = -1; + } + } + if(hit1->hit.detectorID == 3){ + if(bestTrackletX == 0){ + hit1->sign = 1; + } + if(bestTrackletX == 1){ + hit1->sign = 1; + } + if(bestTrackletX == 2){ + hit1->sign = -1; + } + if(bestTrackletX == 3){ + hit1->sign = -1; + } + } + } + } + } + + for(std::list::iterator trackletU = trackletsInStSlimU[0].begin(); trackletU != trackletsInStSlimU[0].end(); ++trackletU){ + //Tracklet tracklet_best_UX; + + if(trackletU->hits.size() == 2){ + double bestSlopeDiffU = 1.0; + double slopeDiffU = 1.0; + int bestTrackletU = 5; + double trackletUslope = 1.0; + int nValidUSlopes = 0; + for(int t3 = 0; t3 < trackletU->possibleULines.size(); t3++){ + slopeDiffU = trackletU->possibleULines.at(t3).slopeU - testTU; + if(std::abs(slopeDiffU)<0.01) nValidUSlopes++; + if(std::abs(slopeDiffU)<0.01 && std::abs(slopeDiffU)possibleULines.at(t3).slopeU; + } + } + + if(bestTrackletU > 4){ + continue; + } else{ + for(std::list::iterator hit1 = trackletU->hits.begin(); hit1 != trackletU->hits.end(); ++hit1) + { + if(hit1->hit.detectorID == 1){ + if(bestTrackletU == 0){ + hit1->sign = 1; + } + if(bestTrackletU == 1){ + hit1->sign = -1; + } + if(bestTrackletU == 2){ + hit1->sign = 1; + } + if(bestTrackletU == 3){ + hit1->sign = -1; + } + } + if(hit1->hit.detectorID == 2){ + if(bestTrackletU == 0){ + hit1->sign = 1; + } + if(bestTrackletU == 1){ + hit1->sign = 1; + } + if(bestTrackletU == 2){ + hit1->sign = -1; + } + if(bestTrackletU == 3){ + hit1->sign = -1; + } + } + } + } + } + + + for(std::list::iterator trackletV = trackletsInStSlimV[0].begin(); trackletV != trackletsInStSlimV[0].end(); ++trackletV){ + + if(trackletV->hits.size() == 2){ + double bestSlopeDiffV = 1.0; + double slopeDiffV = 1.0; + int bestTrackletV = 5; + double trackletVslope = 1.0; + int nValidVSlopes = 0; + for(int t3 = 0; t3 < trackletV->possibleVLines.size(); t3++){ + slopeDiffV = trackletV->possibleVLines.at(t3).slopeV - testTV; + if(std::abs(slopeDiffV)<0.01) nValidVSlopes++; + if(std::abs(slopeDiffV)<0.01 && std::abs(slopeDiffV)possibleVLines.at(t3).slopeV; + } + } + + if(bestTrackletV > 4){ + continue; + } else{ + for(std::list::iterator hit1 = trackletV->hits.begin(); hit1 != trackletV->hits.end(); ++ hit1) + { + if(hit1->hit.detectorID == 5){ + if(bestTrackletV == 0){ + hit1->sign = 1; + } + if(bestTrackletV == 1){ + hit1->sign = -1; + } + if(bestTrackletV == 2){ + hit1->sign = 1; + } + if(bestTrackletV == 3){ + hit1->sign = -1; + } + } + if(hit1->hit.detectorID == 6){ + if(bestTrackletV == 0){ + hit1->sign = 1; + } + if(bestTrackletV == 1){ + hit1->sign = 1; + } + if(bestTrackletV == 2){ + hit1->sign = -1; + } + if(bestTrackletV == 3){ + hit1->sign = -1; + } + } + } + } + } + + if( trackletV->hits.size() < 2 && trackletU->hits.size() < 2 && trackletX->hits.size() < 2 ) return false; + + Tracklet tracklet_new_Station1; + tracklet_new_Station1.stationID = stationID; + + tracklet_new_Station1 = (*trackletX) + (*trackletU) + (*trackletV); + + tracklet_new_Station1.y0 = y0; + tracklet_new_Station1.x0 = expX0; + tracklet_new_Station1.tx = expXZSlope; + tracklet_new_Station1.ty = expYSlope; + + tracklet_new_Station1.sortHits(); + + std::vector candidateSigns; + for(std::list::iterator hit1 = tracklet_new_Station1.hits.begin(); hit1 != tracklet_new_Station1.hits.end(); ++hit1){ + candidateSigns.push_back(hit1->sign); + hit1->sign = 0; + } + tracklet_new_Station1.calcChisq(); +#ifdef _DEBUG_PATRICK + std::cout<<"hello there from build tracklets in station 1"< 300) continue; + + int hitCounter = 0; + for(std::list::iterator hit1 = tracklet_new_Station1.hits.begin(); hit1 != tracklet_new_Station1.hits.end(); ++hit1){ + hit1->sign = candidateSigns.at(hitCounter); + hitCounter++; + } + tracklet_new_Station1.calcChisq(); +#ifdef _DEBUG_PATRICK + std::cout<<"just put the hit signs back on station 1 tracklet"<::iterator hit1 = tracklet_new_Station1.hits.begin(); hit1 != tracklet_new_Station1.hits.end(); ++hit1){ + if(hit1->sign == 0){ + hit1->sign = 1; + double dcaPlus = p_geomSvc->getDCA(hit1->hit.detectorID, hit1->hit.elementID, tracklet_new_Station1.tx, tracklet_new_Station1.ty, tracklet_new_Station1.x0, tracklet_new_Station1.y0); + hit1->sign = -1; + double dcaMinus = p_geomSvc->getDCA(hit1->hit.detectorID, hit1->hit.elementID, tracklet_new_Station1.tx, tracklet_new_Station1.ty, tracklet_new_Station1.x0, tracklet_new_Station1.y0); + if(std::abs(dcaPlus) < std::abs(dcaMinus)){ + hit1->sign = 1; + } else{ + hit1->sign = -1; + } + } + } + + fitTracklet(tracklet_new_Station1); + + if(tracklet_new_Station1.chisq < 20.){ + trackletsInSt[listID].push_back(tracklet_new_Station1); + } + + } + } + } + + //Reduce the tracklet list and add dummy hits + //reduceTrackletList(trackletsInSt[listID]); + for(std::list::iterator iter = trackletsInSt[listID].begin(); iter != trackletsInSt[listID].end(); ++iter) + { + iter->addDummyHits(); + } + + if(trackletsInSt[listID].size() > 0) return true; +} + + + +void KalmanFastTracking_NEW::buildTrackletsInStationSlim(int stationID, int listID, double* pos_exp, double* window) +{ +#ifdef _DEBUG_ON + LogInfo("Building tracklets in station (slim version) " << stationID); +#endif + + //actuall ID of the tracklet lists + int sID = stationID - 1; + + //Extract the X, U, V hit pairs + std::list pairs_X, pairs_U, pairs_V; + if(pos_exp == nullptr) + { + pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0]); + //pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1]); + //pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2]); + } + else + { + //Note that in pos_exp[], index 0 stands for X, index 1 stands for U, index 2 stands for V + pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0], pos_exp[0], window[0]); + //pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1], pos_exp[1], window[1]); + //pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2], pos_exp[2], window[2]); + } + +#ifdef _DEBUG_ON + LogInfo("Hit pairs in this event: "); + for(std::list::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + //for(std::list::iterator iter = pairs_U.begin(); iter != pairs_U.end(); ++iter) LogInfo("U :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + //for(std::list::iterator iter = pairs_V.begin(); iter != pairs_V.end(); ++iter) LogInfo("V :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif +#ifdef _DEBUG_PATRICK + LogInfo("Hit pairs in this event: "); + for(std::list::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif + + //if(pairs_X.empty() || pairs_U.empty() || pairs_V.empty()) + if(pairs_X.empty()) + { +#ifdef _DEBUG_ON + LogInfo("Not all view has hits in station " << stationID); +#endif + return; + } + + //X-U combination first, then add V pairs + for(std::list::iterator xiter = pairs_X.begin(); xiter != pairs_X.end(); ++xiter) + { + + int LR1 = 0; + int LR2 = 0; + Tracklet tracklet_new; + tracklet_new.stationID = stationID; + + //resolveLeftRight(*xiter, LR1, LR2); + if(xiter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->first], LR1)); + tracklet_new.nXHits++; + } + if(xiter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->second], LR2)); + tracklet_new.nXHits++; + } + if(!OLD_TRACKING){ + tracklet_new.getSlopesX(hitAll[xiter->first], hitAll[xiter->second]); //Here, we find the four possible X-Z lines + } + + tracklet_new.sortHits(); +#ifdef _DEBUG_ON + //std::cout<<"About to print new tracklet"< pairs_X, pairs_U, pairs_V; + if(pos_exp == nullptr) + { + if(stationID == 4 || stationID == 5){ + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2]); + } + else{ + //pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0]); + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1]); + //pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2]); + } + } + else + { + if(stationID == 4 || stationID == 5){ + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2], pos_exp[2], window[2]); + } + else{ + //Note that in pos_exp[], index 0 stands for X, index 1 stands for U, index 2 stands for V + //pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0], pos_exp[0], window[0]); + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1], pos_exp[1], window[1]); + //pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2], pos_exp[2], window[2]); + } + } + +#ifdef _DEBUG_ON + LogInfo("Hit pairs in this event: "); + //for(std::list::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_U.begin(); iter != pairs_U.end(); ++iter) LogInfo("U :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + //for(std::list::iterator iter = pairs_V.begin(); iter != pairs_V.end(); ++iter) LogInfo("V :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif +#ifdef _DEBUG_PATRICK + LogInfo("Hit pairs in this event: "); + for(std::list::iterator iter = pairs_U.begin(); iter != pairs_U.end(); ++iter) LogInfo("U :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif + + //if(pairs_X.empty() || pairs_U.empty() || pairs_V.empty()) + if(pairs_U.empty()) + { +#ifdef _DEBUG_ON + LogInfo("Not all view has hits in station " << stationID); +#endif + return; + } + + //X-U combination first, then add V pairs + for(std::list::iterator xiter = pairs_U.begin(); xiter != pairs_U.end(); ++xiter) + { + + int LR1 = 0; + int LR2 = 0; + Tracklet tracklet_new; + tracklet_new.stationID = stationID; + + //resolveLeftRight(*xiter, LR1, LR2); + if(xiter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->first], LR1)); + tracklet_new.nUHits++; + } + if(xiter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->second], LR2)); + tracklet_new.nUHits++; + } + if(!OLD_TRACKING){ + tracklet_new.getSlopesU(hitAll[xiter->first], hitAll[xiter->second]); //Here, we find the four possible X-Z lines + } + + tracklet_new.sortHits(); +#ifdef _DEBUG_ON + //std::cout<<"About to print new U tracklet"< pairs_X, pairs_U, pairs_V; + if(pos_exp == nullptr) + { + if(stationID == 4 || stationID == 5){ + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1]); + } + else{ + //pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0]); + //pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1]); + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2]); + } + } + else + { + if(stationID == 4 || stationID == 5){ + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1], pos_exp[1], window[1]); + } + else{ + //Note that in pos_exp[], index 0 stands for X, index 1 stands for U, index 2 stands for V + //pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0], pos_exp[0], window[0]); + //pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1], pos_exp[1], window[1]); + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2], pos_exp[2], window[2]); + } + } + +#ifdef _DEBUG_ON + LogInfo("Hit pairs in this event: "); + //for(std::list::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + //for(std::list::iterator iter = pairs_U.begin(); iter != pairs_U.end(); ++iter) LogInfo("U :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_V.begin(); iter != pairs_V.end(); ++iter) LogInfo("V :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif +#ifdef _DEBUG_PATRICK + LogInfo("Hit pairs in this event: "); + for(std::list::iterator iter = pairs_V.begin(); iter != pairs_V.end(); ++iter) LogInfo("V :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif + + //if(pairs_X.empty() || pairs_U.empty() || pairs_V.empty()) + if(pairs_V.empty()) + { +#ifdef _DEBUG_ON + LogInfo("Not all view has hits in station " << stationID); +#endif + return; + } + + //X-V combination first, then add V pairs + for(std::list::iterator xiter = pairs_V.begin(); xiter != pairs_V.end(); ++xiter) + { + + int LR1 = 0; + int LR2 = 0; + Tracklet tracklet_new; + tracklet_new.stationID = stationID; + + //resolveLeftRight(*xiter, LR1, LR2); + if(xiter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->first], LR1)); + tracklet_new.nVHits++; + } + if(xiter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->second], LR2)); + tracklet_new.nVHits++; + } + if(!OLD_TRACKING){ + tracklet_new.getSlopesV(hitAll[xiter->first], hitAll[xiter->second]); //Here, we find the four possible X-Z lines + } + + tracklet_new.sortHits(); +#ifdef _DEBUG_ON + //std::cout<<"About to print new V tracklet"<::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_U2.begin(); iter != pairs_U2.end(); ++iter) LogInfo("U2 :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_V2.begin(); iter != pairs_V2.end(); ++iter) LogInfo("V2 :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_U3.begin(); iter != pairs_U3.end(); ++iter) LogInfo("U3 :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_V3.begin(); iter != pairs_V3.end(); ++iter) LogInfo("V3 :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif + + if(pairs_U2.empty() || pairs_V2.empty() || pairs_U3.empty() || pairs_V3.empty()) + { +#ifdef _DEBUG_ON + LogInfo("Not all view has hits in station " << stationID); +#endif + return; + } + + //X-U combination first, then add V pairs + //U projections from X plane + double x_pos2 = 0.5*(tracklet23.getHit(0).hit.pos + tracklet23.getHit(1).hit.pos); + double x_pos3 = 0.5*(tracklet23.getHit(2).hit.pos + tracklet23.getHit(3).hit.pos); + //double x_pos = xiter->second >= 0 ? 0.5*(hitAll[xiter->first].pos + hitAll[xiter->second].pos) : hitAll[xiter->first].pos; + double u_min2 = x_pos2*u_costheta[sID2] - u_win[sID2]; + double u_max2 = u_min2 + 2.*u_win[sID2]; + +#ifdef _DEBUG_ON + //LogInfo("Trying X hits " << xiter->first << " " << xiter->second << " " << hitAll[xiter->first].elementID << " at " << x_pos); + LogInfo("U2 plane window:" << u_min2 << " " << u_max2); +#endif + for(std::list::iterator uiter2 = pairs_U2.begin(); uiter2 != pairs_U2.end(); ++uiter2) + { + double u_pos2 = uiter2->second >= 0 ? 0.5*(hitAll[uiter2->first].pos + hitAll[uiter2->second].pos) : hitAll[uiter2->first].pos; +#ifdef _DEBUG_ON + LogInfo("Trying U2 hits " << uiter2->first << " " << uiter2->second << " " << hitAll[uiter2->first].elementID << " at " << u_pos2); +#endif + if(u_pos2 < u_min2 || u_pos2 > u_max2) continue; + + //V projections from X and U plane + //double z_x2 = xiter->second >= 0 ? z_plane_x[sID] : z_plane[hitAll[xiter->first].detectorID]; + double z_x2 = z_plane_x[sID2]; + double z_u2 = uiter2->second >= 0 ? z_plane_u[sID2] : z_plane[hitAll[uiter2->first].detectorID]; + double z_v2 = z_plane_v[sID2]; + double v_win1_2 = spacing_plane[hitAll[uiter2->first].detectorID]*2.*u_costheta[sID2]; + double v_win2_2 = fabs((z_u2 + z_v2 - 2.*z_x2)*u_costheta[sID2]*TX_MAX); + double v_win3_2 = fabs((z_v2 - z_u2)*u_sintheta[sID2]*TY_MAX); + double v_win_2 = v_win1_2 + v_win2_2 + v_win3_2 + 2.*spacing_plane[hitAll[uiter2->first].detectorID]; + double v_min_2 = 2*x_pos2*u_costheta[sID2] - u_pos2 - v_win_2; + double v_max_2 = v_min_2 + 2.*v_win_2; + +#ifdef _DEBUG_ON + LogInfo("V2 plane window:" << v_min_2 << " " << v_max_2); +#endif + for(std::list::iterator viter2 = pairs_V2.begin(); viter2 != pairs_V2.end(); ++viter2) + { + double v_pos2 = viter2->second >= 0 ? 0.5*(hitAll[viter2->first].pos + hitAll[viter2->second].pos) : hitAll[viter2->first].pos; +#ifdef _DEBUG_ON + LogInfo("Trying V2 hits " << viter2->first << " " << viter2->second << " " << hitAll[viter2->first].elementID << " at " << v_pos2); +#endif + if(v_pos2 < v_min_2 || v_pos2 > v_max_2) continue; + + //Now add the tracklet + int LR1 = 0; + int LR2 = 0; + Tracklet tracklet_new2; + tracklet_new2.stationID = sID2+1; + + //resolveLeftRight(*xiter, LR1, LR2); + tracklet_new2.hits.push_back(SignedHit(tracklet23.getHit(0).hit, LR1)); + tracklet_new2.hits.push_back(SignedHit(tracklet23.getHit(1).hit, LR2)); + if(!OLD_TRACKING){ + tracklet_new2.getSlopesX(tracklet23.getHit(0).hit, tracklet23.getHit(1).hit); //Here, we find the four possible X-Z lines + } + //resolveLeftRight(*uiter, LR1, LR2); + if(uiter2->first >= 0) + { + tracklet_new2.hits.push_back(SignedHit(hitAll[uiter2->first], LR1)); + tracklet_new2.nUHits++; + } + if(uiter2->second >= 0) + { + tracklet_new2.hits.push_back(SignedHit(hitAll[uiter2->second], LR2)); + tracklet_new2.nUHits++; + } + if(!OLD_TRACKING){ + tracklet_new2.getSlopesU(hitAll[uiter2->first], hitAll[uiter2->second]); //find the four possible U-Z lines + } + + //resolveLeftRight(*viter, LR1, LR2); + if(viter2->first >= 0) + { + tracklet_new2.hits.push_back(SignedHit(hitAll[viter2->first], LR1)); + tracklet_new2.nVHits++; + } + if(viter2->second >= 0) + { + tracklet_new2.hits.push_back(SignedHit(hitAll[viter2->second], LR2)); + tracklet_new2.nVHits++; + } + if(!OLD_TRACKING){ + tracklet_new2.getSlopesV(hitAll[viter2->first], hitAll[viter2->second]); //find the four possible V-Z lines + } + + tracklet_new2.sortHits(); + //if(!(tracklet_new2.isValid() == 0)) //TODO: What IS THIS? + //{ + // continue; + //} + /* + { + //fitTracklet(tracklet_new); //This is where the original DCA minimization is performed + } + else + { + continue; + }*/ + +#ifdef _DEBUG_ON + //std::cout<<"OK HERE'S A STATION 2 TRACKLET:"<first << " " << xiter->second << " " << hitAll[xiter->first].elementID << " at " << x_pos); + LogInfo("U3 plane window:" << u_min3 << " " << u_max3); +#endif + for(std::list::iterator uiter3 = pairs_U3.begin(); uiter3 != pairs_U3.end(); ++uiter3) + { + double u_pos3 = uiter3->second >= 0 ? 0.5*(hitAll[uiter3->first].pos + hitAll[uiter3->second].pos) : hitAll[uiter3->first].pos; +#ifdef _DEBUG_ON + LogInfo("Trying U3 hits " << uiter3->first << " " << uiter3->second << " " << hitAll[uiter3->first].elementID << " at " << u_pos3); +#endif + if(u_pos3 < u_min3 || u_pos3 > u_max3) continue; + + //V projections from X and U plane + //double z_x3 = xiter->second >= 0 ? z_plane_x[sID] : z_plane[hitAll[xiter->first].detectorID]; + double z_x3 = z_plane_x[sID3]; + double z_u3 = uiter3->second >= 0 ? z_plane_u[sID3] : z_plane[hitAll[uiter3->first].detectorID]; + double z_v3 = z_plane_v[sID3]; + double v_win1_3 = spacing_plane[hitAll[uiter3->first].detectorID]*2.*u_costheta[sID3]; + double v_win2_3 = fabs((z_u3 + z_v3 - 2.*z_x3)*u_costheta[sID3]*TX_MAX); + double v_win3_3 = fabs((z_v3 - z_u3)*u_sintheta[sID3]*TY_MAX); + double v_win_3 = v_win1_3 + v_win2_3 + v_win3_3 + 2.*spacing_plane[hitAll[uiter3->first].detectorID]; + double v_min_3 = 2*x_pos3*u_costheta[sID3] - u_pos3 - v_win_3; + double v_max_3 = v_min_3 + 2.*v_win_3; + +#ifdef _DEBUG_ON + LogInfo("V3 plane window:" << v_min_3 << " " << v_max_3); +#endif + for(std::list::iterator viter3 = pairs_V3.begin(); viter3 != pairs_V3.end(); ++viter3) + { + double v_pos3 = viter3->second >= 0 ? 0.5*(hitAll[viter3->first].pos + hitAll[viter3->second].pos) : hitAll[viter3->first].pos; +#ifdef _DEBUG_ON + LogInfo("Trying V3 hits " << viter3->first << " " << viter3->second << " " << hitAll[viter3->first].elementID << " at " << v_pos3); +#endif + if(v_pos3 < v_min_3 || v_pos3 > v_max_3) continue; + + //Now add the tracklet + //int LR1 = 0; + //int LR2 = 0; + Tracklet tracklet_new3; + tracklet_new3.stationID = sID3+1; + + //resolveLeftRight(*xiter, LR1, LR2); + tracklet_new3.hits.push_back(SignedHit(tracklet23.getHit(2).hit,LR1)); + tracklet_new3.hits.push_back(SignedHit(tracklet23.getHit(3).hit,LR2)); + if(!OLD_TRACKING){ + tracklet_new3.getSlopesX(tracklet23.getHit(2).hit, tracklet23.getHit(3).hit); //Here, we find the four possible X-Z lines + } + //resolveLeftRight(*uiter, LR1, LR2); + if(uiter3->first >= 0) + { + tracklet_new3.hits.push_back(SignedHit(hitAll[uiter3->first], LR1)); + tracklet_new3.nUHits++; + } + if(uiter3->second >= 0) + { + tracklet_new3.hits.push_back(SignedHit(hitAll[uiter3->second], LR2)); + tracklet_new3.nUHits++; + } + if(!OLD_TRACKING){ + tracklet_new3.getSlopesU(hitAll[uiter3->first], hitAll[uiter3->second]); //find the four possible U-Z lines + } + + //resolveLeftRight(*viter, LR1, LR2); + if(viter3->first >= 0) + { + tracklet_new3.hits.push_back(SignedHit(hitAll[viter3->first], LR1)); + tracklet_new3.nVHits++; + } + if(viter3->second >= 0) + { + tracklet_new3.hits.push_back(SignedHit(hitAll[viter3->second], LR2)); + tracklet_new3.nVHits++; + } + if(!OLD_TRACKING){ + tracklet_new3.getSlopesV(hitAll[viter3->first], hitAll[viter3->second]); //find the four possible V-Z lines + } + + tracklet_new3.sortHits(); + //if(!(tracklet_new3.isValid() == 0)) //TODO: What IS THIS? + //{ + // continue; + //} + +#ifdef _DEBUG_ON + //std::cout<<"OK HERE'S A STATION 3 TRACKLET:"< 9000.) + { +#ifdef _DEBUG_ON + tracklet_new_23.print(); + LogInfo("Impossible combination!"); +#endif + continue; + } + + + if(acceptTracklet(tracklet_new_23)) + { + if(tracklet_new_23 < tracklet_best){ + tracklet_best = tracklet_new_23; + } + //trackletsInSt[listID].push_back(tracklet_new_23); + } +#ifdef _DEBUG_ON + else + { + LogInfo("Rejected!!!"); + } +#endif + } + } + } + } + + if(acceptTracklet(tracklet_best)){ + trackletsInSt[listID].push_back(tracklet_best); + } + //Reduce the tracklet list and add dummy hits + //reduceTrackletList(trackletsInSt[listID]); + for(std::list::iterator iter = trackletsInSt[listID].begin(); iter != trackletsInSt[listID].end(); ++iter) + { + iter->addDummyHits(); + } + + //Only retain the best 200 tracklets if exceeded + //std::cout<<"NUMBER of tracklets before resize = "< 1000) + { + trackletsInSt[listID].sort(); + trackletsInSt[listID].resize(1000); + } +} + + +bool KalmanFastTracking_NEW::acceptTracklet(Tracklet& tracklet) +{ + //Tracklet itself is okay with enough hits (4-out-of-6) and small chi square + if(tracklet.isValid() == 0) + { +#ifdef _DEBUG_ON + LogInfo("Failed in quality check!"); +#endif + return false; + } + + if(COARSE_MODE) return true; + /* + //Hodoscope masking requirement + if(!hodoMask(tracklet)) return false; + + //For back partials, require projection inside KMAG, and muon id in prop. tubes + if(tracklet.stationID > nStations-2) + { + if(!COSMIC_MODE && !p_geomSvc->isInKMAG(tracklet.getExpPositionX(Z_KMAG_BEND), tracklet.getExpPositionY(Z_KMAG_BEND))) return false; + if(!TRACK_ELECTRONS && !(muonID_comp(tracklet) || muonID_search(tracklet))) return false; //Muon check for 2-3 connected tracklets. This needs to be off for electron tracks + if(TRACK_ELECTRONS && !(muonID_comp(tracklet) || muonID_search(tracklet) || tracklet.stationID > 5)){ + return false; + } + }*/ //WPM + +#ifdef _DEBUG_ON + LogInfo("Made it through various checks"); +#endif + + //If everything is fine ... +#ifdef _DEBUG_ON + LogInfo("AcceptTracklet!!!"); +#endif + return true; +} + +bool KalmanFastTracking_NEW::hodoMask(Tracklet& tracklet) +{ + //LogInfo(tracklet.stationID); + if(TRACK_ELECTRONS && (tracklet.stationID == 4 || tracklet.stationID == 5)) return true; //Patrick's skip of hodoscope checks for station 3 tracks in the electron-tracking setup. I could actually probably extrapolate backwards the station 2 hodoscope, now that I get an accurate X-Z slope in station 3 + int nHodoHits = 0; + if(!OLD_TRACKING){ + //Performing a valid extrapolation in X-Z for station 2 tracklets. This should be improved. Currently carries around the old fudge factor + if(tracklet.stationID == 3){ + for(std::vector::iterator stationID = stationIDs_mask[tracklet.stationID-1].begin(); stationID != stationIDs_mask[tracklet.stationID-1].end(); ++stationID){ + bool masked = false; + for(std::list::iterator iter = hitIDs_mask[*stationID-1].begin(); iter != hitIDs_mask[*stationID-1].end(); ++iter){ + int detectorID = hitAll[*iter].detectorID; + int elementID = hitAll[*iter].elementID; + + int idx1 = detectorID - nChamberPlanes - 1; + int idx2 = elementID - 1; + + double factor = tracklet.stationID == nChamberPlanes/6-2 ? 5. : 3.; //special for station-2, based on real data tuning + double xfudge = tracklet.stationID < nStations-1 ? 0.5*(x_mask_max[idx1][idx2] - x_mask_min[idx1][idx2]) : 0.15*(x_mask_max[idx1][idx2] - x_mask_min[idx1][idx2]); + double z_hodo = z_mask[idx1]; + + for(unsigned int pl = 0; pl < tracklet.possibleXLines.size(); pl++){ + double extrapolation = tracklet.possibleXLines.at(pl).slopeX*(z_hodo - tracklet.possibleXLines.at(pl).initialZ) + tracklet.possibleXLines.at(pl).initialX; + double err_x = std::abs(factor*extrapolation + xfudge); + double x_min = x_mask_min[idx1][idx2] - err_x; + double x_max = x_mask_max[idx1][idx2] + err_x; + if(extrapolation > x_min && extrapolation < x_max){ + masked = true; + break; + } + } + } + if(!masked) return false; + } + } + } + + if(tracklet.stationID > 5){ + for(std::vector::iterator stationID = stationIDs_mask[tracklet.stationID-1].begin(); stationID != stationIDs_mask[tracklet.stationID-1].end(); ++stationID) + { + bool masked = false; + for(std::list::iterator iter = hitIDs_mask[*stationID-1].begin(); iter != hitIDs_mask[*stationID-1].end(); ++iter) + { + int detectorID = hitAll[*iter].detectorID; + int elementID = hitAll[*iter].elementID; + + int idx1 = detectorID - nChamberPlanes - 1; + int idx2 = elementID - 1; + + double factor = tracklet.stationID == nChamberPlanes/6-2 ? 5. : 3.; //special for station-2, based on real data tuning + double xfudge = tracklet.stationID < nStations-1 ? 0.5*(x_mask_max[idx1][idx2] - x_mask_min[idx1][idx2]) : 0.15*(x_mask_max[idx1][idx2] - x_mask_min[idx1][idx2]); + double z_hodo = z_mask[idx1]; + double x_hodo = tracklet.getExpPositionX(z_hodo); + double y_hodo = tracklet.getExpPositionY(z_hodo); + double err_x = factor*tracklet.getExpPosErrorX(z_hodo) + xfudge; + double err_y = factor*tracklet.getExpPosErrorY(z_hodo); + + double x_min = x_mask_min[idx1][idx2] - err_x; + double x_max = x_mask_max[idx1][idx2] + err_x; + double y_min = y_mask_min[idx1][idx2] - err_y; + double y_max = y_mask_max[idx1][idx2] + err_y; + +#ifdef _DEBUG_ON + LogInfo(*iter); + hitAll[*iter].print(); + LogInfo(nHodoHits << "/" << stationIDs_mask[tracklet.stationID-1].size() << ": " << z_hodo << " " << x_hodo << " +/- " << err_x << " " << y_hodo << " +/-" << err_y << " : " << x_min << " " << x_max << " " << y_min << " " << y_max); +#endif + if(x_hodo > x_min && x_hodo < x_max && y_hodo > y_min && y_hodo < y_max) + { + nHodoHits++; + masked = true; + + if(TRACK_ELECTRONS && tracklet.stationID > 5) return true; //Once the first hodoscope hit is found (at z=1420cm), the combined tracklet passes for electron tracks + + break; + } + } + + if(!masked) return false; + } + } + +#ifdef _DEBUG_ON + LogInfo(tracklet.stationID << " " << nHodoHits << " " << stationIDs_mask[tracklet.stationID-1].size()); +#endif + return true; +} + +bool KalmanFastTracking_NEW::muonID_search(Tracklet& tracklet) +{ + //Set the cut value on multiple scattering + //multiple scattering: sigma = 0.0136*sqrt(L/L0)*(1. + 0.038*ln(L/L0))/P, L = 1m, L0 = 1.76cm + double cut = 0.03; + if(tracklet.stationID == nStations) + { + double cut_the = MUID_THE_P0*tracklet.invP; + double cut_emp = MUID_EMP_P0 + MUID_EMP_P1/tracklet.invP + MUID_EMP_P2/tracklet.invP/tracklet.invP; + cut = MUID_REJECTION*(cut_the > cut_emp ? cut_the : cut_emp); + } + + double slope[2] = {tracklet.tx, tracklet.ty}; + double pos_absorb[2] = {tracklet.getExpPositionX(MUID_Z_REF), tracklet.getExpPositionY(MUID_Z_REF)}; + PropSegment* segs[2] = {&(tracklet.seg_x), &(tracklet.seg_y)}; + for(int i = 0; i < 2; ++i) + { + //this shorting circuting can only be done to X-Z, Y-Z needs more complicated thing + //if(i == 0 && segs[i]->getNHits() > 2 && segs[i]->isValid() > 0 && fabs(slope[i] - segs[i]->a) < cut) continue; + + segs[i]->init(); + for(int j = 0; j < 4; ++j) + { + int index = detectorIDs_muid[i][j] - nChamberPlanes - 1; + double pos_ref = j < 2 ? pos_absorb[i] : segs[i]->getPosRef(pos_absorb[i] + slope[i]*(z_ref_muid[i][j] - MUID_Z_REF)); + double pos_exp = slope[i]*(z_mask[index] - z_ref_muid[i][j]) + pos_ref; + + if(!p_geomSvc->isInPlane(detectorIDs_muid[i][j], tracklet.getExpPositionX(z_mask[index]), tracklet.getExpPositionY(z_mask[index]))) continue; + + double win_tight = cut*(z_mask[index] - z_ref_muid[i][j]); + win_tight = win_tight > 2.54 ? win_tight : 2.54; + double win_loose = win_tight*2; + double dist_min = 1E6; + for(std::list::iterator iter = hitIDs_muid[i][j].begin(); iter != hitIDs_muid[i][j].end(); ++iter) + { + double pos = hitAll[*iter].pos; + double dist = pos - pos_exp; + if(dist < -win_loose) continue; + if(dist > win_loose) break; + + double dist_l = fabs(pos - hitAll[*iter].driftDistance - pos_exp); + double dist_r = fabs(pos + hitAll[*iter].driftDistance - pos_exp); + dist = dist_l < dist_r ? dist_l : dist_r; + if(dist < dist_min) + { + dist_min = dist; + if(dist < win_tight) + { + segs[i]->hits[j].hit = hitAll[*iter]; + segs[i]->hits[j].sign = fabs(pos - hitAll[*iter].driftDistance - pos_exp) < fabs(pos + hitAll[*iter].driftDistance - pos_exp) ? -1 : 1; + } + } + } + } + segs[i]->fit(); + + //this shorting circuting can only be done to X-Z, Y-Z needs more complicated thing + //if(i == 0 && !(segs[i]->isValid() > 0 && fabs(slope[i] - segs[i]->a) < cut)) return false; + } + + muonID_hodoAid(tracklet); + if(segs[0]->getNHits() + segs[1]->getNHits() >= MUID_MINHITS) + { + return true; + } + else if(segs[1]->getNHits() == 1 || segs[1]->getNPlanes() == 1) + { + return segs[1]->nHodoHits >= 2; + } + return false; +} + +bool KalmanFastTracking_NEW::muonID_comp(Tracklet& tracklet) +{ + //Set the cut value on multiple scattering + //multiple scattering: sigma = 0.0136*sqrt(L/L0)*(1. + 0.038*ln(L/L0))/P, L = 1m, L0 = 1.76cm + double cut = 0.03; + if(tracklet.stationID == nStations) + { + double cut_the = MUID_THE_P0*tracklet.invP; + double cut_emp = MUID_EMP_P0 + MUID_EMP_P1/tracklet.invP + MUID_EMP_P2/tracklet.invP/tracklet.invP; + cut = MUID_REJECTION*(cut_the > cut_emp ? cut_the : cut_emp); + } +#ifdef _DEBUG_ON + LogInfo("Muon ID cut is: " << cut << " rad."); +#endif + + double slope[2] = {tracklet.tx, tracklet.ty}; + PropSegment* segs[2] = {&(tracklet.seg_x), &(tracklet.seg_y)}; + + for(int i = 0; i < 2; ++i) + { +#ifdef _DEBUG_ON + if(i == 0) LogInfo("Working in X-Z:"); + if(i == 1) LogInfo("Working in Y-Z:"); +#endif + + double pos_ref = i == 0 ? tracklet.getExpPositionX(MUID_Z_REF) : tracklet.getExpPositionY(MUID_Z_REF); + if(segs[i]->getNHits() > 2 && segs[i]->isValid() > 0 && fabs(slope[i] - segs[i]->a) < cut && fabs(segs[i]->getExpPosition(MUID_Z_REF) - pos_ref) < MUID_R_CUT) + { +#ifdef _DEBUG_ON + LogInfo("Muon ID are already avaiable!"); +#endif + continue; + } + + for(std::list::iterator iter = propSegs[i].begin(); iter != propSegs[i].end(); ++iter) + { +#ifdef _DEBUG_ON + LogInfo("Testing this prop segment, with ref pos = " << pos_ref << ", slope_ref = " << slope[i]); + iter->print(); +#endif + if(fabs(iter->a - slope[i]) < cut && fabs(iter->getExpPosition(MUID_Z_REF) - pos_ref) < MUID_R_CUT) + { + *(segs[i]) = *iter; +#ifdef _DEBUG_ON + LogInfo("Accepted!"); +#endif + break; + } + } + + if(segs[i]->isValid() == 0) return false; + } + + if(segs[0]->getNHits() + segs[1]->getNHits() < MUID_MINHITS) return false; + return true; +} + +bool KalmanFastTracking_NEW::muonID_hodoAid(Tracklet& tracklet) +{ + double win = 0.03; + double factor = 5.; + if(tracklet.stationID == nStations) + { + double win_the = MUID_THE_P0*tracklet.invP; + double win_emp = MUID_EMP_P0 + MUID_EMP_P1/tracklet.invP + MUID_EMP_P2/tracklet.invP/tracklet.invP; + win = MUID_REJECTION*(win_the > win_emp ? win_the : win_emp); + factor = 3.; + } + + PropSegment* segs[2] = {&(tracklet.seg_x), &(tracklet.seg_y)}; + for(int i = 0; i < 2; ++i) + { + segs[i]->nHodoHits = 0; + for(std::list::iterator iter = hitIDs_muidHodoAid[i].begin(); iter != hitIDs_muidHodoAid[i].end(); ++iter) + { + int detectorID = hitAll[*iter].detectorID; + int elementID = hitAll[*iter].elementID; + + int idx1 = detectorID - nChamberPlanes - 1; + int idx2 = elementID - 1; + + double z_hodo = z_mask[idx1]; + double x_hodo = tracklet.getExpPositionX(z_hodo); + double y_hodo = tracklet.getExpPositionY(z_hodo); + double err_x = factor*tracklet.getExpPosErrorX(z_hodo) + win*(z_hodo - MUID_Z_REF); + double err_y = factor*tracklet.getExpPosErrorY(z_hodo) + win*(z_hodo - MUID_Z_REF); + + err_x = err_x/(x_mask_max[idx1][idx2] - x_mask_min[idx1][idx2]) > 0.25 ? 0.25*err_x/(x_mask_max[idx1][idx2] - x_mask_min[idx1][idx2]) : err_x; + err_y = err_y/(y_mask_max[idx1][idx2] - y_mask_min[idx1][idx2]) > 0.25 ? 0.25*err_y/(y_mask_max[idx1][idx2] - y_mask_min[idx1][idx2]) : err_y; + + double x_min = x_mask_min[idx1][idx2] - err_x; + double x_max = x_mask_max[idx1][idx2] + err_x; + double y_min = y_mask_min[idx1][idx2] - err_y; + double y_max = y_mask_max[idx1][idx2] + err_y; + + if(x_hodo > x_min && x_hodo < x_max && y_hodo > y_min && y_hodo < y_max) + { + segs[i]->hodoHits[segs[i]->nHodoHits++] = hitAll[*iter]; + if(segs[i]->nHodoHits > 4) break; + } + } + } + + return true; +} + +void KalmanFastTracking_NEW::buildPropSegments() +{ +#ifdef _DEBUG_ON + LogInfo("Building prop. tube segments"); +#endif + + for(int i = 0; i < 2; ++i) + { + propSegs[i].clear(); + + //note for prop tubes superID index starts from 4 + std::list pairs_forward = rawEvent->getPartialHitPairsInSuperDetector(superIDs[i+5][0]); + std::list pairs_backward = rawEvent->getPartialHitPairsInSuperDetector(superIDs[i+5][1]); + +#ifdef _DEBUG_ON + //std::cout << "superID: " << superIDs[i+5][0] << ", " << superIDs[i+5][1] << std::endl; + for(std::list::iterator iter = pairs_forward.begin(); iter != pairs_forward.end(); ++iter) + LogInfo("Forward: " << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_backward.begin(); iter != pairs_backward.end(); ++iter) + LogInfo("Backward: " << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif + + for(std::list::iterator fiter = pairs_forward.begin(); fiter != pairs_forward.end(); ++fiter) + { +#ifdef _DEBUG_ON + LogInfo("Trying forward pair " << fiter->first << " " << fiter->second); +#endif + for(std::list::iterator biter = pairs_backward.begin(); biter != pairs_backward.end(); ++biter) + { +#ifdef _DEBUG_ON + LogInfo("Trying backward pair " << biter->first << " " << biter->second); +#endif + + PropSegment seg; + + //Note that the backward plane comes as the first in pair + if(fiter->first >= 0) seg.hits[1] = SignedHit(hitAll[fiter->first], 0); + if(fiter->second >= 0) seg.hits[0] = SignedHit(hitAll[fiter->second], 0); + if(biter->first >= 0) seg.hits[3] = SignedHit(hitAll[biter->first], 0); + if(biter->second >= 0) seg.hits[2] = SignedHit(hitAll[biter->second], 0); + +#ifdef _DEBUG_ON + seg.print(); +#endif + seg.fit(); +#ifdef _DEBUG_ON + seg.print(); +#endif + + if(seg.isValid() > 0) + { + propSegs[i].push_back(seg); + } +#ifdef _DEBUG_ON + else + { + LogInfo("Rejected!"); + } +#endif + } + } + } +} + + +int KalmanFastTracking_NEW::fitTracklet(Tracklet& tracklet) +{ + tracklet_curr = tracklet; + + //idx = 0, using simplex; idx = 1 using migrad + int idx = 1; +#ifdef _ENABLE_MULTI_MINI + if(tracklet.stationID < nStations-1) idx = 0; +#endif + + //std::cout<<"in fitTracklet :(. invP = "<SetLimitedVariable(0, "tx", tracklet.tx, 0.001, -TX_MAX, TX_MAX); + minimizer[idx]->SetLimitedVariable(1, "ty", tracklet.ty, 0.001, -TY_MAX, TY_MAX); + minimizer[idx]->SetLimitedVariable(2, "x0", tracklet.x0, 0.1, -X0_MAX, X0_MAX); + minimizer[idx]->SetLimitedVariable(3, "y0", tracklet.y0, 0.1, -Y0_MAX, Y0_MAX); + if(KMAG_ON) + { + //std::cout<<"hello now invp = "<Minimize(); + + tracklet.tx = minimizer[idx]->X()[0]; + tracklet.ty = minimizer[idx]->X()[1]; + tracklet.x0 = minimizer[idx]->X()[2]; + tracklet.y0 = minimizer[idx]->X()[3]; + + tracklet.err_tx = minimizer[idx]->Errors()[0]; + tracklet.err_ty = minimizer[idx]->Errors()[1]; + tracklet.err_x0 = minimizer[idx]->Errors()[2]; + tracklet.err_y0 = minimizer[idx]->Errors()[3]; + + //std::cout<<"in fitTracklet :(. KMAG_ON = "<::iterator iter = tracklets.begin(); iter != tracklets.end(); ) + { + if(iter->similarity(targetList.back())) + { +#ifdef _DEBUG_ON_LEVEL_2 + LogInfo("Removing this tracklet: "); + iter->print(); +#endif + iter = tracklets.erase(iter); + continue; + } + else + { + ++iter; + } + } + } + + tracklets.assign(targetList.begin(), targetList.end()); + return 0; +} + +void KalmanFastTracking_NEW::getExtrapoWindowsInSt1(Tracklet& tracklet, double* pos_exp, double* window, int st1ID) +{ + if(tracklet.stationID != nStations-1) + { + for(int i = 0; i < 3; i++) + { + pos_exp[i] = 9999.; + window[i] = 0.; + } + return; + } + + for(int i = 0; i < 3; i++) + { + int detectorID = (st1ID-1)*6 + 2*i + 2; + int idx = p_geomSvc->getPlaneType(detectorID) - 1; + + double z_st1 = z_plane[detectorID]; + double x_st1 = tracklet.getExpPositionX(z_st1); + double y_st1 = tracklet.getExpPositionY(z_st1); + double err_x = tracklet.getExpPosErrorX(z_st1); + double err_y = tracklet.getExpPosErrorY(z_st1); + + pos_exp[idx] = p_geomSvc->getUinStereoPlane(detectorID, x_st1, y_st1); + window[idx] = 5.*(fabs(costheta_plane[detectorID]*err_x) + fabs(sintheta_plane[detectorID]*err_y)); + } +} + +void KalmanFastTracking_NEW::getSagittaWindowsInSt1(Tracklet& tracklet, double* pos_exp, double* window, int st1ID) +{ + if(tracklet.stationID != nStations-1) + { + for(int i = 0; i < 3; i++) + { + pos_exp[i] = 9999.; + window[i] = 0.; + } + return; + } + + double z_st3 = z_plane[tracklet.hits.back().hit.detectorID]; + double x_st3 = tracklet.getExpPositionX(z_st3); + double y_st3 = tracklet.getExpPositionY(z_st3); + + //For U, X, and V planes + for(int i = 0; i < 3; i++) + { + int detectorID = (st1ID-1)*6 + 2*i + 2; + int idx = p_geomSvc->getPlaneType(detectorID) - 1; + + if(!(idx >= 0 && idx <3)) continue; + + double pos_st3 = p_geomSvc->getUinStereoPlane(s_detectorID[idx], x_st3, y_st3); + + double z_st1 = z_plane[detectorID]; + double z_st2 = z_plane[s_detectorID[idx]]; + double x_st2 = tracklet.getExpPositionX(z_st2); + double y_st2 = tracklet.getExpPositionY(z_st2); + double pos_st2 = p_geomSvc->getUinStereoPlane(s_detectorID[idx], x_st2, y_st2); + + double s2_target = pos_st2 - pos_st3*(z_st2 - Z_TARGET)/(z_st3 - Z_TARGET); + double s2_dump = pos_st2 - pos_st3*(z_st2 - Z_DUMP)/(z_st3 - Z_DUMP); + + double pos_exp_target = SAGITTA_TARGET_CENTER*s2_target + pos_st3*(z_st1 - Z_TARGET)/(z_st3 - Z_TARGET); + double pos_exp_dump = SAGITTA_DUMP_CENTER*s2_dump + pos_st3*(z_st1 - Z_DUMP)/(z_st3 - Z_DUMP); + double win_target = fabs(s2_target*SAGITTA_TARGET_WIDTH); + double win_dump = fabs(s2_dump*SAGITTA_DUMP_WIDTH); + + double p_min = std::min(pos_exp_target - win_target, pos_exp_dump - win_dump); + double p_max = std::max(pos_exp_target + win_target, pos_exp_dump + win_dump); + + //std::cout<<"Test sagitta window thing. The detectorID is "<::iterator iter = tracklet.hits.begin(); iter != tracklet.hits.end(); ++iter) + { + if(iter->hit.index < 0) continue; + + Node node_add(*iter); + kmtrk.getNodeList().push_back(node_add); + kmtrk.getHitIndexList().push_back(iter->sign*iter->hit.index); + } + + //Set initial state + TrkPar trkpar_curr; + trkpar_curr._z = p_geomSvc->getPlanePosition(kmtrk.getNodeList().back().getHit().detectorID); + //FIXME Debug Testing: sign reverse + //TODO seems to be fixed + trkpar_curr._state_kf[0][0] = tracklet.getCharge()*tracklet.invP/sqrt(1. + tracklet.tx*tracklet.tx + tracklet.ty*tracklet.ty); + trkpar_curr._state_kf[1][0] = tracklet.tx; + trkpar_curr._state_kf[2][0] = tracklet.ty; + trkpar_curr._state_kf[3][0] = tracklet.getExpPositionX(trkpar_curr._z); + trkpar_curr._state_kf[4][0] = tracklet.getExpPositionY(trkpar_curr._z); + + trkpar_curr._covar_kf.Zero(); + trkpar_curr._covar_kf[0][0] = 0.001;//1E6*tracklet.err_invP*tracklet.err_invP; + trkpar_curr._covar_kf[1][1] = 0.01;//1E6*tracklet.err_tx*tracklet.err_tx; + trkpar_curr._covar_kf[2][2] = 0.01;//1E6*tracklet.err_ty*tracklet.err_ty; + trkpar_curr._covar_kf[3][3] = 100;//1E6*tracklet.getExpPosErrorX(trkpar_curr._z)*tracklet.getExpPosErrorX(trkpar_curr._z); + trkpar_curr._covar_kf[4][4] = 100;//1E6*tracklet.getExpPosErrorY(trkpar_curr._z)*tracklet.getExpPosErrorY(trkpar_curr._z); + + kmtrk.setCurrTrkpar(trkpar_curr); + kmtrk.getNodeList().back().getPredicted() = trkpar_curr; + */ + + /* + //Fit the track first with possibily a few nodes unresolved + if(!fitTrack(kmtrk)) + { +#ifdef _DEBUG_ON + LogInfo("!fitTrack(kmtrk) - try flip charge"); +#endif + trkpar_curr._state_kf[0][0] *= -1.; + kmtrk.setCurrTrkpar(trkpar_curr); + kmtrk.getNodeList().back().getPredicted() = trkpar_curr; + if(!fitTrack(kmtrk)) + { +#ifdef _DEBUG_ON + LogInfo("!fitTrack(kmtrk) - failed flip charge also"); +#endif + SRecTrack strack = tracklet.getSRecTrack(); + strack.setKalmanStatus(-1); + return strack; + } + } + + if(!kmtrk.isValid()) + { +#ifdef _DEBUG_ON + LogInfo("!kmtrk.isValid() Chi2 = " << kmtrk.getChisq() << " - try flip charge"); +#endif + trkpar_curr._state_kf[0][0] *= -1.; + kmtrk.setCurrTrkpar(trkpar_curr); + kmtrk.getNodeList().back().getPredicted() = trkpar_curr; + if(!fitTrack(kmtrk)) + { +#ifdef _DEBUG_ON + LogInfo("!fitTrack(kmtrk) - failed flip charge also"); +#endif + SRecTrack strack = tracklet.getSRecTrack(); + strack.setKalmanStatus(-1); + return strack; + } + +#ifdef _DEBUG_ON + LogInfo("Chi2 after flip charge: " << kmtrk.getChisq()); + if(kmtrk.isValid()) + { + LogInfo("flip charge worked!"); + } +#endif + } + +#ifdef _DEBUG_ON + LogInfo("kmtrk.print()"); + kmtrk.print(); + LogInfo("kmtrk.printNodes()"); + kmtrk.printNodes(); +#endif + */ + + //Resolve left-right based on the current solution, re-fit if anything changed + //resolveLeftRight(kmtrk); + if(fitTrack(kmtrk) && kmtrk.isValid()) + { + SRecTrack strack = kmtrk.getSRecTrack(); + + //Set trigger road ID + TriggerRoad road(tracklet); + strack.setTriggerRoad(road.getRoadID()); + + //Set prop tube slopes + strack.setNHitsInPT(tracklet.seg_x.getNHits(), tracklet.seg_y.getNHits()); + strack.setPTSlope(tracklet.seg_x.a, tracklet.seg_y.a); + + strack.setKalmanStatus(1); + + return strack; + } + else + { +#ifdef _DEBUG_ON + LogInfo("!kmtrk.isValid()"); +#endif + SRecTrack strack = tracklet.getSRecTrack(); + strack.setKalmanStatus(-1); + + return strack; + } +} + +bool KalmanFastTracking_NEW::fitTrack(KalmanTrack& kmtrk) +{ + if(kmtrk.getNodeList().empty()) return false; + + if(kmfitter->processOneTrack(kmtrk) == 0) + { + return false; + } + kmfitter->updateTrack(kmtrk); + + return true; +} + +void KalmanFastTracking_NEW::resolveLeftRight(KalmanTrack& kmtrk) +{ + bool isUpdated = false; + + std::list::iterator hitID = kmtrk.getHitIndexList().begin(); + for(std::list::iterator node = kmtrk.getNodeList().begin(); node != kmtrk.getNodeList().end(); ) + { + if(*hitID == 0) + { + double x_hit = node->getSmoothed().get_x(); + double y_hit = node->getSmoothed().get_y(); + double pos_hit = p_geomSvc->getUinStereoPlane(node->getHit().detectorID, x_hit, y_hit); + + int sign = 0; + if(pos_hit > node->getHit().pos) + { + sign = 1; + } + else + { + sign = -1; + } + + //update the node list + TMatrixD m(1, 1), dm(1, 1); + m[0][0] = node->getHit().pos + sign*node->getHit().driftDistance; + dm[0][0] = p_geomSvc->getPlaneResolution(node->getHit().detectorID)*p_geomSvc->getPlaneResolution(node->getHit().detectorID); + node->setMeasurement(m, dm); + *hitID = sign*node->getHit().index; + + isUpdated = true; + } + + ++node; + ++hitID; + } + + if(isUpdated) fitTrack(kmtrk); +} + +void KalmanFastTracking_NEW::printTimers() { + std::cout <<"KalmanFastTracking_NEW::printTimers: " << std::endl; + std::cout <<"================================================================" << std::endl; + std::cout << "Tracklet St2 "<<_timers["st2"]->get_accumulated_time()/1000. << " sec" <get_accumulated_time()/1000. << " sec" <get_accumulated_time()/1000. << " sec" <get_accumulated_time()/1000. << " sec" <get_accumulated_time()/1000. << " sec" <get_accumulated_time()/1000. << " sec" <get_accumulated_time()/1000. << " sec" <get_accumulated_time()/1000. << " sec" < 0.007) return false; //This has not been optimized at all. I just chose a random value (previous slope comparison allowed for a difference of 0.1) + double extrapolation = line2X.slopeX*(line3X.initialZ - line2X.initialZ) + line2X.initialX; + + if(std::abs(extrapolation - line3X.initialX) > 5. ){ //allow for a 5 cm difference of the tracklet in station 3 from the station 2 extrapolation. This also should be optimized + if(secondSlope > 0.007) return false; //If both the closest and second closest slopes don't match, then this is not a good combination + double extrapolation_v2 = line2X_v2.slopeX*(line3X_v2.initialZ - line2X_v2.initialZ) + line2X_v2.initialX; //Perform the extrapolation in the rare case that the closest slope combination did not yield a valid extrapolation. Rare, but necessary + if(std::abs(extrapolation_v2 - line3X_v2.initialX) > 5. ){ //Same window size! Could be optimized + return false; + } else{ + line2X = line2X_v2; //These are the possible X-Z lines that we actually want, if the closest combination wasn't valid based on the extrapolation + line3X = line3X_v2; + } + } + + + //Here we will compare the possible X-Z slopes within the station 2 and station 3 tracklets + Tracklet::linedef line2U; + Tracklet::linedef line3U; + Tracklet::linedef line2U_v2; + Tracklet::linedef line3U_v2; + + //It is rare, but sometimes, you will have slopes that match coincidentally. Therefore, I keep track of best two combinations. This seems to be sufficienct + double slopeCompU = 1.0; + double secondSlopeU = 1.1; + for(unsigned int t2 = 0; t2 < tracklet2.possibleULines.size(); t2++){ + for(unsigned int t3 = 0; t3 < tracklet3.possibleULines.size(); t3++){ + if(std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU) < slopeCompU){ + + //if the new combination is the closest so far, then the previous closest becomes the second closest... + secondSlopeU = slopeCompU; + line2U_v2 = line2U; + line3U_v2 = line3U; + + slopeCompU = std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU); + line2U = tracklet2.possibleULines.at(t2); + line3U = tracklet3.possibleULines.at(t3); + } + else if(std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU) < secondSlopeU){ + //not as close as the closest combination, but closer than the previously existing second combination + secondSlopeU = std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU); + line2U_v2 = tracklet2.possibleULines.at(t2); + line3U_v2 = tracklet3.possibleULines.at(t3); + } + } + } + + if(slopeCompU > 0.007) return false; //This has not been optimized at all. I just chose a random value (previous slope comparison allowed for a difference of 0.1) + double extrapolationU = line2U.slopeU*(line3U.initialZ - line2U.initialZ) + line2U.initialU; + + if(std::abs(extrapolationU - line3U.initialU) > 5. ){ //allow for a 5 cm difference of the tracklet in station 3 from the station 2 extrapolation. This also should be optimized + if(secondSlopeU > 0.007) return false; //If both the closest and second closest slopes don't match, then this is not a good combination + double extrapolationU_v2 = line2U_v2.slopeU*(line3U_v2.initialZ - line2U_v2.initialZ) + line2U_v2.initialU; //Perform the extrapolation in the rare case that the closest slope combination did not yield a valid extrapolation. Rare, but necessary + if(std::abs(extrapolationU_v2 - line3U_v2.initialU) > 5. ){ //Same window size! Could be optimized + return false; + } else{ + line2U = line2U_v2; //These are the possible X-Z lines that we actually want, if the closest combination wasn't valid based on the extrapolation + line3U = line3U_v2; + } + } + + + + //Here we will compare the possible X-Z slopes within the station 2 and station 3 tracklets + Tracklet::linedef line2V; + Tracklet::linedef line3V; + Tracklet::linedef line2V_v2; + Tracklet::linedef line3V_v2; + + //It is rare, but sometimes, you will have slopes that match coincidentally. Therefore, I keep track of best two combinations. This seems to be sufficienct + double slopeCompV = 1.0; + double secondSlopeV = 1.1; + for(unsigned int t2 = 0; t2 < tracklet2.possibleVLines.size(); t2++){ + for(unsigned int t3 = 0; t3 < tracklet3.possibleVLines.size(); t3++){ + if(std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV) < slopeCompV){ + + //if the new combination is the closest so far, then the previous closest becomes the second closest... + secondSlopeV = slopeCompV; + line2V_v2 = line2V; + line3V_v2 = line3V; + + slopeCompV = std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV); + line2V = tracklet2.possibleVLines.at(t2); + line3V = tracklet3.possibleVLines.at(t3); + } + else if(std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV) < secondSlopeV){ + //not as close as the closest combination, but closer than the previously existing second combination + secondSlopeV = std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV); + line2V_v2 = tracklet2.possibleVLines.at(t2); + line3V_v2 = tracklet3.possibleVLines.at(t3); + } + } + } + + if(slopeCompV > 0.007) return false; //This has not been optimized at all. I just chose a random value (previous slope comparison allowed for a difference of 0.1) + double extrapolationV = line2V.slopeV*(line3V.initialZ - line2V.initialZ) + line2V.initialV; + + if(std::abs(extrapolationV - line3V.initialV) > 5. ){ //allow for a 5 cm difference of the tracklet in station 3 from the station 2 extrapolation. This also should be optimized + if(secondSlopeV > 0.007) return false; //If both the closest and second closest slopes don't match, then this is not a good combination + double extrapolationV_v2 = line2V_v2.slopeV*(line3V_v2.initialZ - line2V_v2.initialZ) + line2V_v2.initialV; //Perform the extrapolation in the rare case that the closest slope combination did not yield a valid extrapolation. Rare, but necessary + if(std::abs(extrapolationV_v2 - line3V_v2.initialV) > 5. ){ //Same window size! Could be optimized + return false; + } else{ + line2V = line2V_v2; //These are the possible X-Z lines that we actually want, if the closest combination wasn't valid based on the extrapolation + line3V = line3V_v2; + } + } + + /* + Tracklet::linedef line2U; + Tracklet::linedef line3U; + double slopeCompU = 1.0; + for(unsigned int t2 = 0; t2 < tracklet2.possibleULines.size(); t2++){ + for(unsigned int t3 = 0; t3 < tracklet3.possibleULines.size(); t3++){ + if(std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU) < slopeCompU){ + slopeCompU = std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU); + line2U = tracklet2.possibleULines.at(t2); + line3U = tracklet3.possibleULines.at(t3); + } + } + } //As of now, I don't keep track of the second-closest combination for the U and V layers + + if(slopeCompU > 0.005) return false; //Larger window here. From what I can tell, the resolution is worse in this plane, or maybe my slope calculations are somewhat incorrect + + Tracklet::linedef line2V; + Tracklet::linedef line3V; + double slopeCompV = 1.0; + for(unsigned int t2 = 0; t2 < tracklet2.possibleVLines.size(); t2++){ + for(unsigned int t3 = 0; t3 < tracklet3.possibleVLines.size(); t3++){ + if(std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV) < slopeCompV){ + slopeCompV = std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV); + line2V = tracklet2.possibleVLines.at(t2); + line3V = tracklet3.possibleVLines.at(t3); + } + } + } + + if(slopeCompV > 0.005) return false; //same comment about resolution as for the U layer +*/ + //Now we find the Y-values of the hits in the U and V planes + double tracklet2Ys_D = 0.; //This is the sum of the Y-values of the hits in the U and V planes of the two tracklets. The sum is taken to be used in an average. The _D here stands for driftDistance. I originally did this part of the code without taking the drift distance in the slanted layers into account + double tracklet3Ys_D = 0.; + tracklet2Ys_D += line2V.wire1Slope * (line2X.slopeX*(line2V.wireHit1PosZ - line2X.initialZ) + line2X.initialX) + line2V.wireIntercept1; + tracklet2Ys_D += line2V.wire2Slope * (line2X.slopeX*(line2V.wireHit2PosZ - line2X.initialZ) + line2X.initialX) + line2V.wireIntercept2; + tracklet2Ys_D += line2U.wire1Slope * (line2X.slopeX*(line2U.wireHit1PosZ - line2X.initialZ) + line2X.initialX) + line2U.wireIntercept1; + tracklet2Ys_D += line2U.wire2Slope * (line2X.slopeX*(line2U.wireHit2PosZ - line2X.initialZ) + line2X.initialX) + line2U.wireIntercept2; + + //std::cout<<"In COMPARETRACKLETS. st2 v wire y's are "< 0.007) return false; //This has not been optimized at all. I just chose a random value (previous slope comparison allowed for a difference of 0.1) + double extrapolation = line2X.slopeX*(line3X.initialZ - line2X.initialZ) + line2X.initialX; + + if(std::abs(extrapolation - line3X.initialX) > 7. ){ //allow for a 5 cm difference of the tracklet in station 3 from the station 2 extrapolation. This also should be optimized + if(secondSlope > 0.007) return false; //If both the closest and second closest slopes don't match, then this is not a good combination + double extrapolation_v2 = line2X_v2.slopeX*(line3X_v2.initialZ - line2X_v2.initialZ) + line2X_v2.initialX; //Perform the extrapolation in the rare case that the closest slope combination did not yield a valid extrapolation. Rare, but necessary + if(std::abs(extrapolation_v2 - line3X_v2.initialX) > 7. ){ //Same window size! Could be optimized + return false; + } else{ + line2X = line2X_v2; //These are the possible X-Z lines that we actually want, if the closest combination wasn't valid based on the extrapolation + line3X = line3X_v2; + } + } + + + //Here we will compare the possible X-Z slopes within the station 2 and station 3 tracklets + Tracklet::linedef line2U; + Tracklet::linedef line3U; + Tracklet::linedef line2U_v2; + Tracklet::linedef line3U_v2; + + //It is rare, but sometimes, you will have slopes that match coincidentally. Therefore, I keep track of best two combinations. This seems to be sufficienct + double slopeCompU = 1.0; + double secondSlopeU = 1.1; + for(unsigned int t2 = 0; t2 < tracklet2.possibleULines.size(); t2++){ + for(unsigned int t3 = 0; t3 < tracklet3.possibleULines.size(); t3++){ + if(std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU) < slopeCompU){ + + //if the new combination is the closest so far, then the previous closest becomes the second closest... + secondSlopeU = slopeCompU; + line2U_v2 = line2U; + line3U_v2 = line3U; + + slopeCompU = std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU); + line2U = tracklet2.possibleULines.at(t2); + line3U = tracklet3.possibleULines.at(t3); + } + else if(std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU) < secondSlopeU){ + //not as close as the closest combination, but closer than the previously existing second combination + secondSlopeU = std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU); + line2U_v2 = tracklet2.possibleULines.at(t2); + line3U_v2 = tracklet3.possibleULines.at(t3); + } + } + } + + if(slopeCompU > 0.005) return false; //This has not been optimized at all. I just chose a random value (previous slope comparison allowed for a difference of 0.1) + double extrapolationU = line2U.slopeU*(line3U.initialZ - line2U.initialZ) + line2U.initialU; + + if(std::abs(extrapolationU - line3U.initialU) > 7. ){ //allow for a 5 cm difference of the tracklet in station 3 from the station 2 extrapolation. This also should be optimized + if(secondSlopeU > 0.005) return false; //If both the closest and second closest slopes don't match, then this is not a good combination + double extrapolationU_v2 = line2U_v2.slopeU*(line3U_v2.initialZ - line2U_v2.initialZ) + line2U_v2.initialU; //Perform the extrapolation in the rare case that the closest slope combination did not yield a valid extrapolation. Rare, but necessary + if(std::abs(extrapolationU_v2 - line3U_v2.initialU) > 7. ){ //Same window size! Could be optimized + return false; + } else{ + line2U = line2U_v2; //These are the possible X-Z lines that we actually want, if the closest combination wasn't valid based on the extrapolation + line3U = line3U_v2; + } + } + + + + //Here we will compare the possible X-Z slopes within the station 2 and station 3 tracklets + Tracklet::linedef line2V; + Tracklet::linedef line3V; + Tracklet::linedef line2V_v2; + Tracklet::linedef line3V_v2; + + //It is rare, but sometimes, you will have slopes that match coincidentally. Therefore, I keep track of best two combinations. This seems to be sufficienct + double slopeCompV = 1.0; + double secondSlopeV = 1.1; + for(unsigned int t2 = 0; t2 < tracklet2.possibleVLines.size(); t2++){ + for(unsigned int t3 = 0; t3 < tracklet3.possibleVLines.size(); t3++){ + if(std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV) < slopeCompV){ + + //if the new combination is the closest so far, then the previous closest becomes the second closest... + secondSlopeV = slopeCompV; + line2V_v2 = line2V; + line3V_v2 = line3V; + + slopeCompV = std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV); + line2V = tracklet2.possibleVLines.at(t2); + line3V = tracklet3.possibleVLines.at(t3); + } + else if(std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV) < secondSlopeV){ + //not as close as the closest combination, but closer than the previously existing second combination + secondSlopeV = std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV); + line2V_v2 = tracklet2.possibleVLines.at(t2); + line3V_v2 = tracklet3.possibleVLines.at(t3); + } + } + } + + if(slopeCompV > 0.005) return false; //This has not been optimized at all. I just chose a random value (previous slope comparison allowed for a difference of 0.1) + double extrapolationV = line2V.slopeV*(line3V.initialZ - line2V.initialZ) + line2V.initialV; + + if(std::abs(extrapolationV - line3V.initialV) > 5. ){ //allow for a 5 cm difference of the tracklet in station 3 from the station 2 extrapolation. This also should be optimized + if(secondSlopeV > 0.005) return false; //If both the closest and second closest slopes don't match, then this is not a good combination + double extrapolationV_v2 = line2V_v2.slopeV*(line3V_v2.initialZ - line2V_v2.initialZ) + line2V_v2.initialV; //Perform the extrapolation in the rare case that the closest slope combination did not yield a valid extrapolation. Rare, but necessary + if(std::abs(extrapolationV_v2 - line3V_v2.initialV) > 5. ){ //Same window size! Could be optimized + return false; + } else{ + line2V = line2V_v2; //These are the possible X-Z lines that we actually want, if the closest combination wasn't valid based on the extrapolation + line3V = line3V_v2; + } + } + + /* + Tracklet::linedef line2U; + Tracklet::linedef line3U; + double slopeCompU = 1.0; + for(unsigned int t2 = 0; t2 < tracklet2.possibleULines.size(); t2++){ + for(unsigned int t3 = 0; t3 < tracklet3.possibleULines.size(); t3++){ + if(std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU) < slopeCompU){ + slopeCompU = std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU); + line2U = tracklet2.possibleULines.at(t2); + line3U = tracklet3.possibleULines.at(t3); + } + } + } //As of now, I don't keep track of the second-closest combination for the U and V layers + + if(slopeCompU > 0.005) return false; //Larger window here. From what I can tell, the resolution is worse in this plane, or maybe my slope calculations are somewhat incorrect + + Tracklet::linedef line2V; + Tracklet::linedef line3V; + double slopeCompV = 1.0; + for(unsigned int t2 = 0; t2 < tracklet2.possibleVLines.size(); t2++){ + for(unsigned int t3 = 0; t3 < tracklet3.possibleVLines.size(); t3++){ + if(std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV) < slopeCompV){ + slopeCompV = std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV); + line2V = tracklet2.possibleVLines.at(t2); + line3V = tracklet3.possibleVLines.at(t3); + } + } + } + + if(slopeCompV > 0.005) return false; //same comment about resolution as for the U layer +*/ + //Now we find the Y-values of the hits in the U and V planes + double tracklet2Ys_D = 0.; //This is the sum of the Y-values of the hits in the U and V planes of the two tracklets. The sum is taken to be used in an average. The _D here stands for driftDistance. I originally did this part of the code without taking the drift distance in the slanted layers into account + double tracklet3Ys_D = 0.; + tracklet2Ys_D += line2V.wire1Slope * (line2X.slopeX*(line2V.wireHit1PosZ - line2X.initialZ) + line2X.initialX) + line2V.wireIntercept1; + tracklet2Ys_D += line2V.wire2Slope * (line2X.slopeX*(line2V.wireHit2PosZ - line2X.initialZ) + line2X.initialX) + line2V.wireIntercept2; + tracklet2Ys_D += line2U.wire1Slope * (line2X.slopeX*(line2U.wireHit1PosZ - line2X.initialZ) + line2X.initialX) + line2U.wireIntercept1; + tracklet2Ys_D += line2U.wire2Slope * (line2X.slopeX*(line2U.wireHit2PosZ - line2X.initialZ) + line2X.initialX) + line2U.wireIntercept2; + + //std::cout<<"In COMPARETRACKLETS. st2 v wire y's are "< 0.005 ) return false; + if( std::abs(st2VWireCos*tracklet2.tx - st2VWireSin*tracklet2.ty - line2V.slopeV) > 0.005 ) return false; + if( std::abs(st3UWireCos*tracklet3.tx - st3UWireSin*tracklet3.ty - line3U.slopeU) > 0.005 ) return false; + if( std::abs(st3VWireCos*tracklet3.tx - st3VWireSin*tracklet3.ty - line3V.slopeV) > 0.005 ) return false; + + //std::cout<<"pass serious comparison"< slopeWindow) return false; //This has not been optimized at all. I just chose a random value (previous slope comparison allowed for a difference of 0.1) + double extrapolation = line2X.slopeX*(line3X.initialZ - line2X.initialZ) + line2X.initialX; + double extrapolation_toSt1 = line2X.slopeX*(z_plane[3] - line2X.initialZ) + line2X.initialX; + //std::cout<<"extrapolation is "< extrapoWindow || std::abs(extrapolation_toSt1) > 100. ){ //allow for a 5 cm difference of the tracklet in station 3 from the station 2 extrapolation. This also should be optimized + if(secondSlope > slopeWindow) return false; //If both the closest and second closest slopes don't match, then this is not a good combination + double extrapolation_v2 = line2X_v2.slopeX*(line3X_v2.initialZ - line2X_v2.initialZ) + line2X_v2.initialX; //Perform the extrapolation in the rare case that the closest slope combination did not yield a valid extrapolation. Rare, but necessary + double extrapolation_toSt1_v2 = line2X_v2.slopeX*(z_plane[3] - line2X_v2.initialZ) + line2X_v2.initialX; + //std::cout<<"V2 extrapolation is "< extrapoWindow || std::abs(extrapolation_toSt1_v2) > 100. ){ //Same window size! Could be optimized + return false; + } else{ + line2X = line2X_v2; //These are the possible X-Z lines that we actually want, if the closest combination wasn't valid based on the extrapolation + line3X = line3X_v2; + choiceOfT2 = choiceOfT2_v2; + choiceOfT3 = choiceOfT3_v2; + } + } + + tracklet2.acceptedXLine2 = line2X; + tracklet3.acceptedXLine3 = line3X; + //Give the station 2 and station 3 tracklets the same tx and ty value. I could get an X0 and Y0 extrapolation, but that doesn't seem to be strictly necessary. The X0 and Y0 values are found in the fittracklet function for the combined station 2 + station 3 tracklet + tracklet2.tx = (line2X.slopeX + line3X.slopeX)/2; + //tracklet2.ty = (tracklet3Ys_D/4. - tracklet2Ys_D/4.)/(line3U.wireHit1PosZ - line2V.wireHit1PosZ); //The y slope is found by taking the average Y position in the station3 and subtracting the average Y position in station2. This is then divided by the z difference, of course + tracklet3.tx = (line2X.slopeX + line3X.slopeX)/2; + //tracklet3.ty = (tracklet3Ys_D/4. - tracklet2Ys_D/4.)/(line3U.wireHit1PosZ - line2V.wireHit1PosZ); + + tracklet2.st2Z = line2X.initialZ; + tracklet2.st2X = line2X.initialX; + tracklet3.st2Z = line3X.initialZ; + tracklet3.st2X = line3X.initialX; + + tracklet2.st2Xsl = line2X.slopeX; + tracklet3.st2Xsl = line3X.slopeX; + + //std::cout<<"THERE WAS A TRACKLET MATCH!"< slopeWindow) return false; //This has not been optimized at all. I just chose a random value (previous slope comparison allowed for a difference of 0.1) + + if(std::abs(extrapolation - line3U.initialU) > extrapoWindow || std::abs(extrapolation_toSt1) > 100. || std::abs(line3U.slopeU) > 0.15 || std::abs(line2U.slopeU) > 0.15 ){ //allow for a 5 cm difference of the tracklet in station 3 from the station 2 extrapolation. This also should be optimized + if(secondSlope > slopeWindow) return false; //If both the closest and second closest slopes don't match, then this is not a good combination + + if(std::abs(extrapolation_v2 - line3U_v2.initialU) > extrapoWindow || std::abs(extrapolation_toSt1_v2) > 100. || std::abs(line3U_v2.slopeU) > 0.15 || std::abs(line2U_v2.slopeU) > 0.15 ){ //Same window size! Could be optimized + return false; + } else{ + line2U = line2U_v2; //These are the possible U-Z lines that we actually want, if the closest combination wasn't valid based on the extrapolation + line3U = line3U_v2; + choiceOfT2 = choiceOfT2_v2; + choiceOfT3 = choiceOfT3_v2; + } + } + + tracklet2.acceptedULine2 = line2U; + tracklet3.acceptedULine3 = line3U; + + //Give the station 2 and station 3 tracklets the same tx and ty value. I could get an X0 and Y0 extrapolation, but that doesn't seem to be strictly necessary. The X0 and Y0 values are found in the fittracklet function for the combined station 2 + station 3 tracklet + //tracklet2.tx = (line2X.slopeX + line3X.slopeX)/2; + //tracklet2.ty = (tracklet3Ys_D/4. - tracklet2Ys_D/4.)/(line3U.wireHit1PosZ - line2V.wireHit1PosZ); //The y slope is found by taking the average Y position in the station3 and subtracting the average Y position in station2. This is then divided by the z difference, of course + //tracklet3.tx = (line2X.slopeX + line3X.slopeX)/2; + //tracklet3.ty = (tracklet3Ys_D/4. - tracklet2Ys_D/4.)/(line3U.wireHit1PosZ - line2V.wireHit1PosZ); + + tracklet2.st2Z = line2U.initialZ; + tracklet2.st2U = line2U.initialU; + tracklet3.st2Z = line3U.initialZ; + tracklet3.st2U = line3U.initialU; + + tracklet2.st2Usl = line2U.slopeU; + tracklet3.st2Usl = line3U.slopeU; + + //std::cout<<"THERE WAS A U TRACKLET MATCH!"< slopeWindow) return false; //This has not been optimized at all. I just chose a random value (previous slope comparison allowed for a difference of 0.1) + + if(std::abs(extrapolation - line3V.initialV) > extrapoWindow || std::abs(extrapolation_toSt1) > 100. || std::abs(line3V.slopeV) > 0.15 || std::abs(line2V.slopeV) > 0.15 ){ //allow for a 5 cm difference of the tracklet in station 3 from the station 2 extrapolation. This also should be optimized + if(secondSlope > slopeWindow) return false; //If both the closest and second closest slopes don't match, then this is not a good combination + + if(std::abs(extrapolation_v2 - line3V_v2.initialV) > extrapoWindow || std::abs(extrapolation_toSt1_v2) > 100. || std::abs(line3V_v2.slopeV) > 0.15 || std::abs(line2V_v2.slopeV) > 0.15 ){ //Same window size! Could be optimized + return false; + } else{ + line2V = line2V_v2; //These are the possible V-Z lines that we actually want, if the closest combination wasn't valid based on the extrapolation + line3V = line3V_v2; + choiceOfT2 = choiceOfT2_v2; + choiceOfT3 = choiceOfT3_v2; + } + } + + tracklet2.acceptedVLine2 = line2V; + //std::cout<<"TEST OF LINE2 "<::iterator iter = tracklet2.hits.begin(); iter != tracklet2.hits.end(); ++iter) + { + if(iter->sign > 0) std::cout << "L: "; + if(iter->sign < 0) std::cout << "R: "; + if(iter->sign == 0) std::cout << "U: "; + + std::cout << iter->hit.index << " " << p_geomSvc->getDetectorName(iter->hit.detectorID) << "(" << iter->hit.detectorID << ") " << iter->hit.elementID << " = "; + } + std::cout<::iterator iter = tracklet3.hits.begin(); iter != tracklet3.hits.end(); ++iter) + { + if(iter->sign > 0) std::cout << "L: "; + if(iter->sign < 0) std::cout << "R: "; + if(iter->sign == 0) std::cout << "U: "; + + std::cout << iter->hit.index << " " << p_geomSvc->getDetectorName(iter->hit.detectorID) << "(" << iter->hit.detectorID << ") " << iter->hit.elementID << " = "; + } + std::cout<::iterator iter2 = tracklet2.hits.begin(); iter2 != tracklet2.hits.end(); ++iter2){ + for(std::list::iterator iter3 = tracklet3.hits.begin(); iter3 != tracklet3.hits.end(); ++iter3){ + if( iter2->hit.index != iter3->hit.index || iter2->hit.detectorID != iter3->hit.detectorID || iter2->hit.elementID != iter3->hit.elementID ){ + sameTracklet = false; + break; + } + } + if(!sameTracklet) break; + } + + if(sameTracklet){ + std::cout<<"these are the same tracklet"<tx * ( z_plane[3] - tracklet23->st2Z ) + tracklet23->st2X; //WPM pick up here. do u and v extrapolations + //double posu = tracklet23->st2Usl * ( z_plane[1] - tracklet23->st2Z ) + tracklet23->st2U; //WPM + //double posv = tracklet23->st2Vsl * ( z_plane[5] - tracklet23->st2Z ) + tracklet23->st2V; //WPM + //double posy = tracklet23->ty * ( z_plane[3] - tracklet23->st2Z ) + tracklet23->st2Y; //WPM + + pos_exp[0] = posx+charges[ch]*pxSlices[pxs]; + pos_exp[1] = p_geomSvc->getCostheta(1) * pos_exp[0] + p_geomSvc->getSintheta(1) * posy; + pos_exp[2] = p_geomSvc->getCostheta(5) * pos_exp[0] + p_geomSvc->getSintheta(5) * posy; + */ + std::vector u_layers = {17, 18, 23, 24, 29, 30}; + std::vector v_layers = {13, 14, 19, 20, 25, 26}; + + double posx; + double posy; + double expU; + for(int l = 0; lgetCostheta(1) * posx + p_geomSvc->getSintheta(u_layers.at(l)) * posy; + for(unsigned int h = 0; h < tracklet23.hits.size(); h++){ + if(tracklet23.getHit(h).hit.detectorID == u_layers.at(l)){ + if( std::abs(expU - tracklet23.getHit(h).hit.pos) > 3.1 ){ + acceptableTracklet = false; + return false; + } + } + } + } + + double expV; + for(int l = 0; lgetCostheta(1) * posx + p_geomSvc->getSintheta(v_layers.at(l)) * posy; + for(unsigned int h = 0; h < tracklet23.hits.size(); h++){ + if(tracklet23.getHit(h).hit.detectorID == v_layers.at(l)){ + if( std::abs(expV - tracklet23.getHit(h).hit.pos) > 3.1 ){ + acceptableTracklet = false; + return false; + } + } + } + } + + + return acceptableTracklet; +} + +/* +double KalmanFastTracking_NEW::YSlopes(Tracklet& trackletU, Tracklet& trackletV) +{ + + double differentYSlope = 100.; + + if( trackletU.hits.size() == 4 && trackletV.hits.size() == 4 ){ + + double tracklet2Ys_D = 0.; //This is the sum of the Y-values of the hits in the U and V planes of the two tracklets. The sum is taken to be used in an average. The _D here stands for driftDistance. I originally did this part of the code without taking the drift distance in the slanted layers into account + double tracklet3Ys_D = 0.; + + for(unsigned int h = 0; h < trackletU->hits.size(); h++){ + double posx = trackletX->st2Xsl * (z_plane[(*trackletU).getHit(h).hit.detectorID] - trackletX->st2Z) + trackletX->st2X; + if((*trackletU).getHit(h).hit.detectorID == 17){ + tracklet2Ys_D += trackletU->acceptedULine2.wire1Slope * posx + trackletU->acceptedULine2.wireIntercept1; + } + if((*trackletU).getHit(h).hit.detectorID == 18){ + tracklet2Ys_D += trackletU->acceptedULine2.wire2Slope * posx + trackletU->acceptedULine2.wireIntercept2; + } + if((*trackletU).getHit(h).hit.detectorID == 19 || (*trackletU).getHit(h).hit.detectorID == 25){ + tracklet3Ys_D += trackletU->acceptedULine3.wire1Slope * posx + trackletU->acceptedULine3.wireIntercept1; + } + if((*trackletU).getHit(h).hit.detectorID == 20 || (*trackletU).getHit(h).hit.detectorID == 26){ + tracklet3Ys_D += trackletU->acceptedULine3.wire2Slope * posx + trackletU->acceptedULine3.wireIntercept2; + } + } + + for(unsigned int h = 0; h < trackletV->hits.size(); h++){ + double posx = trackletX->st2Xsl * (z_plane[(*trackletV).getHit(h).hit.detectorID] - trackletX->st2Z) + trackletX->st2X; + if((*trackletV).getHit(h).hit.detectorID == 13){ + tracklet2Ys_D += trackletV->acceptedVLine2.wire1Slope * posx + trackletV->acceptedVLine2.wireIntercept1; + } + if((*trackletV).getHit(h).hit.detectorID == 14){ + tracklet2Ys_D += trackletV->acceptedVLine2.wire2Slope * posx + trackletV->acceptedVLine2.wireIntercept2; + } + if((*trackletV).getHit(h).hit.detectorID == 23 || (*trackletV).getHit(h).hit.detectorID == 29){ + tracklet3Ys_D += trackletV->acceptedVLine3.wire1Slope * posx + trackletV->acceptedVLine3.wireIntercept1; + } + if((*trackletV).getHit(h).hit.detectorID == 24 || (*trackletV).getHit(h).hit.detectorID == 30){ + tracklet3Ys_D += trackletV->acceptedVLine3.wire2Slope * posx + trackletV->acceptedVLine3.wireIntercept2; + } + } + + differentYSlope = (tracklet3Ys_D/4. - tracklet2Ys_D/4.)/(trackletX->st3Z - trackletX->st2Z); + } + + if( trackletU.hits.size() == 4 && trackletV.hits.size() == 3 ){ + + double tracklet2Ys_D = 0.; //This is the sum of the Y-values of the hits in the U and V planes of the two tracklets. The sum is taken to be used in an average. The _D here stands for driftDistance. I originally did this part of the code without taking the drift distance in the slanted layers into account + double tracklet3Ys_D = 0.; + + for(unsigned int h = 0; h < trackletU->hits.size(); h++){ + double posx = trackletX->st2Xsl * (z_plane[(*trackletU).getHit(h).hit.detectorID] - trackletX->st2Z) + trackletX->st2X; + if((*trackletU).getHit(h).hit.detectorID == 17){ + tracklet2Ys_D += trackletU->acceptedULine2.wire1Slope * posx + trackletU->acceptedULine2.wireIntercept1; + } + if((*trackletU).getHit(h).hit.detectorID == 18){ + tracklet2Ys_D += trackletU->acceptedULine2.wire2Slope * posx + trackletU->acceptedULine2.wireIntercept2; + } + if((*trackletU).getHit(h).hit.detectorID == 19 || (*trackletU).getHit(h).hit.detectorID == 25){ + tracklet3Ys_D += trackletU->acceptedULine3.wire1Slope * posx + trackletU->acceptedULine3.wireIntercept1; + } + if((*trackletU).getHit(h).hit.detectorID == 20 || (*trackletU).getHit(h).hit.detectorID == 26){ + tracklet3Ys_D += trackletU->acceptedULine3.wire2Slope * posx + trackletU->acceptedULine3.wireIntercept2; + } + } + + for(unsigned int h = 0; h < trackletV->hits.size(); h++){ + double posx = trackletX->st2Xsl * (z_plane[(*trackletV).getHit(h).hit.detectorID] - trackletX->st2Z) + trackletX->st2X; + if((*trackletV).getHit(h).hit.detectorID == 13){ + tracklet2Ys_D += trackletV->acceptedVLine2.wire1Slope * posx + trackletV->acceptedVLine2.wireIntercept1; + } + if((*trackletV).getHit(h).hit.detectorID == 14){ + tracklet2Ys_D += trackletV->acceptedVLine2.wire2Slope * posx + trackletV->acceptedVLine2.wireIntercept2; + } + if((*trackletV).getHit(h).hit.detectorID == 23 || (*trackletV).getHit(h).hit.detectorID == 29){ + tracklet3Ys_D += trackletV->acceptedVLine3.wire1Slope * posx + trackletV->acceptedVLine3.wireIntercept1; + } + if((*trackletV).getHit(h).hit.detectorID == 24 || (*trackletV).getHit(h).hit.detectorID == 30){ + tracklet3Ys_D += trackletV->acceptedVLine3.wire2Slope * posx + trackletV->acceptedVLine3.wireIntercept2; + } + } + + differentYSlope = (tracklet3Ys_D/3. - tracklet2Ys_D/4.)/(trackletX->st3Z - trackletX->st2Z); + } + + + return differentYSlope; + +} +*/ diff --git a/packages/reco/ktracker/KalmanFastTracking_NEW.h b/packages/reco/ktracker/KalmanFastTracking_NEW.h new file mode 100644 index 00000000..7490b542 --- /dev/null +++ b/packages/reco/ktracker/KalmanFastTracking_NEW.h @@ -0,0 +1,259 @@ +/* +KalmanFastTracking_NEW.h + +Fast tracking utility of Kalman filter track, used to improve the tracking speed and also for online monitoring + +Author: Kun Liu, liuk@fnal.gov +Created: 05-24-2013 +*/ + +#ifndef _KALMANFASTTRACKING_NEW_H +#define _KALMANFASTTRACKING_NEW_H + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "TMathBase.h" + +#include "SRawEvent.h" +#include "KalmanTrack.h" +#include "KalmanFitter.h" +#include "FastTracklet.h" + +class TGeoManager; + +class PHField; +class PHTimer; + +class KalmanFastTracking_NEW +{ +public: + explicit KalmanFastTracking_NEW(const PHField* field, const TGeoManager *geom, bool flag = true); + ~KalmanFastTracking_NEW(); + + //set/get verbosity + void Verbosity(const int a) {verbosity = a;} + int Verbosity() const {return verbosity;} + void printTimers(); + + //Set the input event + int setRawEvent(SRawEvent* event_input); + void setRawEventDebug(SRawEvent* event_input); + + //Event quality cut + bool acceptEvent(SRawEvent* rawEvent); + + ///Tracklet finding stuff + //Build tracklets in a station + void buildTrackletsInStation(int stationID, int listID, double* pos_exp = nullptr, double* window = nullptr); + void buildTrackletsInStationSlim(int stationID, int listID, double* pos_exp = nullptr, double* window = nullptr); + void buildTrackletsInStationSlimU(int stationID, int listID, double* pos_exp = nullptr, double* window = nullptr); + void buildTrackletsInStationSlimV(int stationID, int listID, double* pos_exp = nullptr, double* window = nullptr); + + bool buildTrackletsInStation1(int stationID, int listID, double expXZSlope, double expYSlope, double y0, double* pos_exp = nullptr, double* window = nullptr); + bool buildTrackletsInStation1_NEW(int stationID, int listID, double expXZSlope, double expYSlope, double y0, double* pos_exp = nullptr, double* window = nullptr); + bool buildTrackletsInStation1_UFirst(int stationID, int listID, double expXZSlope, double expYSlope, double y0, double* pos_exp = nullptr, double* window = nullptr); + + void buildTrackletsInStation1X(int stationID, int listID, double* pos_exp = nullptr, double* window = nullptr); + void buildTrackletsInStationWithUV(int stationID, int listID, Tracklet& tracklet23, double* pos_exp = nullptr, double* window = nullptr); + + //Build back partial tracks using tracklets in station 2 & 3 + void buildBackPartialTracks(); + void buildBackPartialTracksSlim(); + void buildBackPartialTracksSlim_v2(); + void buildBackPartialTracksSlimX(int pass); + void buildBackPartialTracksSlimU(int pass); + void buildBackPartialTracksSlimV(int pass); + + //Build global tracks by connecting station 23 tracklets and station 1 tracklets + void buildGlobalTracks(); + + //Build global tracks by connecting station 23 tracklets and station 1 tracklets + void buildGlobalTracksDisplaced(); + + //Fit tracklets + int fitTracklet(Tracklet& tracklet); + + //Check the quality of tracklet, number of hits + bool acceptTracklet(Tracklet& tracklet); + bool hodoMask(Tracklet& tracklet); + bool muonID_comp(Tracklet& tracklet); + bool muonID_search(Tracklet& tracklet); + bool muonID_hodoAid(Tracklet& tracklet); + + bool compareTracklets(Tracklet& tracklet1, Tracklet& tracklet2); + + bool compareTrackletsSlim(Tracklet& tracklet1, Tracklet& tracklet2, int pass); + bool compareTrackletsSlim_3hits(Tracklet& tracklet1, Tracklet& tracklet2, int pass); + + bool compareTrackletsSlimU(Tracklet& tracklet1, Tracklet& tracklet2, int pass); + bool compareTrackletsSlimU_3hits(Tracklet& tracklet1, Tracklet& tracklet2, int pass); + + bool compareTrackletsSlimV(Tracklet& tracklet1, Tracklet& tracklet2, int pass); + bool compareTrackletsSlimV_3hits(Tracklet& tracklet1, Tracklet& tracklet2, int pass); + + bool compareTrackletsSerious(Tracklet& tracklet1, Tracklet& tracklet2); + + bool compareTracklets_v2(Tracklet& tracklet1, Tracklet& tracklet2); + bool compareTrackletsSlim_v2(Tracklet& tracklet1, Tracklet& tracklet2, int pass); + bool compareTrackletsSlimU_v2(Tracklet& tracklet1, Tracklet& tracklet2, int pass); + bool compareTrackletsSlimV_v2(Tracklet& tracklet1, Tracklet& tracklet2, int pass); + + double YSlopes(Tracklet& tracklet1, Tracklet& tracklet2); + + bool checkTwoTracklets(Tracklet& tracklet1, Tracklet& tracklet2); + bool checkSingleTracklet(Tracklet& tracklet1); + + void buildPropSegments(); + + //Resolve left-right when possible + void resolveLeftRight(SRawEvent::hit_pair hpair, int& LR1, int& LR2); + void resolveLeftRight(Tracklet& tracklet, double threshold); + void resolveSingleLeftRight(Tracklet& tracklet); + + //Remove bad hit if needed + void removeBadHits(Tracklet& tracklet); + + //Reduce the list of tracklets, returns the number of elements reduced + int reduceTrackletList(std::list& tracklets); + + //Get exp postion and window using sagitta method in station 1 + void getSagittaWindowsInSt1(Tracklet& tracklet, double* pos_exp, double* window, int st1ID); + void getExtrapoWindowsInSt1(Tracklet& tracklet, double* pos_exp, double* window, int st1ID); + + //Print the distribution of tracklets at detector back/front + void printAtDetectorBack(int stationID, std::string outputFileName); + + ///Track fitting stuff + //Convert Tracklet to KalmanTrack and solve left-right problem, and eventually to a SRecTrack + SRecTrack processOneTracklet(Tracklet& tracklet); + + //Use Kalman fitter to fit a track + bool fitTrack(KalmanTrack& kmtrk); + + //Resolve left right by Kalman fitting results + void resolveLeftRight(KalmanTrack& kmtrk); + + ///Final output + std::list& getFinalTracklets() { return trackletsInSt[outputListIdx]; } + std::list& getBackPartials() { return trackletsInSt[3]; } + std::list& getTrackletList(int i) { return trackletsInSt[i]; } + std::list& getSRecTracks() { return stracks; } + std::list& getPropSegments(int i) { return propSegs[i]; } + + ///Set the index of the final output tracklet list + void setOutputListID(unsigned int i) { outputListIdx = i; } + + ///Tool, a simple-minded chi square fit + void chi2fit(int n, double x[], double y[], double& a, double& b); + +private: + //verbosity following Fun4All convention + int verbosity; + + //Raw event input + SRawEvent* rawEvent; + std::vector hitAll; + + //Tracklets in one event, id = 0, 1, 2 for station 0/1, 2, 3+/-, id = 3 for station 2&3 combined, id = 4 for global tracks + //Likewise for the next part + std::list trackletsInSt[5]; + std::list trackletsInStSlimX[5]; + std::list trackletsInStSlimU[5]; + std::list trackletsInStSlimV[5]; + + //Final SRecTrack list + std::list stracks; + + //Index of the trackletlist designated as output + unsigned int outputListIdx; + + //Prop. tube segments for muon id purposes + // 0 for X-Z, 1 for Y-Z + std::list propSegs[2]; + + ///Configurations of tracklet finding + //Hodo. IDs for masking, 4 means we have 4 hodo stations + std::vector detectorIDs_mask[4]; + std::vector detectorIDs_maskX[4]; + std::vector detectorIDs_maskY[4]; + std::list hitIDs_mask[4]; //hits in T/B, L/R are combined + std::vector detectorIDs_muidHodoAid[2]; //Aux-hodoscope masking for muon ID + + //register difference hodo masking stations for different chamber detectors + std::vector stationIDs_mask[nStations]; + + //prop. tube IDs for MUID -- 0 for x-z, 1 for y-z + int detectorIDs_muid[2][4]; + double z_ref_muid[2][4]; + std::list hitIDs_muid[2][4]; + std::list hitIDs_muidHodoAid[2]; + + //Masking window sizes, index is the uniqueID defined by nElement*detectorID + elementID + double z_mask[nHodoPlanes+nPropPlanes]; + double x_mask_min[nHodoPlanes+nPropPlanes][72]; + double x_mask_max[nHodoPlanes+nPropPlanes][72]; + double y_mask_min[nHodoPlanes+nPropPlanes][72]; + double y_mask_max[nHodoPlanes+nPropPlanes][72]; + + ///For following part, id = 0, 1, 2, 3, 4, 5, 6 stand for station 0, 1, 2, 3+, 3-, and prop tubes X-Z and Y-Z + //Super plane IDs for DCs + std::vector superIDs[nChamberPlanes/6+2]; + + //Window sizes for X-U combination + double u_win[nChamberPlanes/6]; + double u_costheta[nChamberPlanes/6]; + double u_sintheta[nChamberPlanes/6]; + double z_plane_x[nChamberPlanes/6]; + double z_plane_u[nChamberPlanes/6]; + double z_plane_v[nChamberPlanes/6]; + + //Plane angles for all planes + double costheta_plane[nChamberPlanes+1]; + double sintheta_plane[nChamberPlanes+1]; + + //Z positions + double z_plane[nChamberPlanes+1]; + + //Maximum slope and intersection in each view + double slope_max[nChamberPlanes+1]; + double intersection_max[nChamberPlanes+1]; + + //Resolutions of all planes + double resol_plane[nChamberPlanes+1]; + + //Cell width of all planes + double spacing_plane[nChamberPlanes+1]; + + //Sagitta ratio in station 1, index 0, 1, 2 are for X/U/V + int s_detectorID[3]; + + //Current tracklets being processed + Tracklet tracklet_curr; + + //Least chi square fitter and functor + ROOT::Math::Minimizer* minimizer[2]; + ROOT::Math::Functor fcn; + + //Kalman fitter + KalmanFitter* kmfitter; + + //Geometry service + GeomSvc* p_geomSvc; + + //Flag for enable Kalman fitting + const bool enable_KF; + + //Timer + std::map _timers; +}; + +#endif diff --git a/packages/reco/ktracker/KalmanFastTracking_NEW_2.cxx b/packages/reco/ktracker/KalmanFastTracking_NEW_2.cxx new file mode 100644 index 00000000..c8b66170 --- /dev/null +++ b/packages/reco/ktracker/KalmanFastTracking_NEW_2.cxx @@ -0,0 +1,4262 @@ +/* +KalmanFastTracking_NEW_2.cxx + +Implementation of class Tracklet, KalmanFastTracking_NEW_2 + +Author: Kun Liu, liuk@fnal.gov +Created: 05-28-2013 +*/ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "KalmanFastTracking_NEW_2.h" +#include "TriggerRoad.h" + +//#define _DEBUG_ON +//#define _DEBUG_PATRICK +//#define _DEBUG_PATRICK_EXTRA + +//#define _DEBUG_RES +//#define _DEBUG_RES_EMBED + +//#define _DEBUG_FAST + +namespace +{ + //static flag to indicate the initialized has been done + static bool inited = false; + + //Event acceptance cut + static int MaxHitsDC0; + static int MaxHitsDC1; + static int MaxHitsDC2; + static int MaxHitsDC3p; + static int MaxHitsDC3m; + + //Sagitta ratio + static double SAGITTA_DUMP_CENTER; + static double SAGITTA_DUMP_WIDTH; + static double SAGITTA_TARGET_CENTER; + static double SAGITTA_TARGET_WIDTH; + static double Z_TARGET; + static double Z_DUMP; + + //Track quality cuts + static double TX_MAX; + static double TY_MAX; + static double X0_MAX; + static double Y0_MAX; + static double INVP_MAX; + static double INVP_MIN; + static double Z_KMAG_BEND; + + //MuID cuts + static double MUID_REJECTION; + static double MUID_Z_REF; + static double MUID_R_CUT; + static double MUID_THE_P0; + static double MUID_EMP_P0; + static double MUID_EMP_P1; + static double MUID_EMP_P2; + static int MUID_MINHITS; + + //Track merging threshold + static double MERGE_THRES; + + //static flag of kmag on/off + static bool KMAG_ON; + + //running mode + static bool MC_MODE; + static bool COSMIC_MODE; + static bool COARSE_MODE; + + //if displaced, skip fit to the target/vertex + static bool NOT_DISPLACED; + static bool TRACK_ELECTRONS; //please see comment in framework/phool/recoConsts.cc + static bool TRACK_DISPLACED; //please see comment in framework/phool/recoConsts.cc + static bool OLD_TRACKING; //please see comment in framework/phool/recoConsts.cc + + static double KMAGSTR; + static double PT_KICK_KMAG; + + //initialize global variables + void initGlobalVariables() + { + if(!inited) + { + inited = true; + + recoConsts* rc = recoConsts::instance(); + MC_MODE = rc->get_BoolFlag("MC_MODE"); + KMAG_ON = rc->get_BoolFlag("KMAG_ON"); + COSMIC_MODE = rc->get_BoolFlag("COSMIC_MODE"); + COARSE_MODE = rc->get_BoolFlag("COARSE_MODE"); + + NOT_DISPLACED = rc->get_BoolFlag("NOT_DISPLACED"); + TRACK_ELECTRONS = rc->get_BoolFlag("TRACK_ELECTRONS"); + TRACK_DISPLACED = rc->get_BoolFlag("TRACK_DISPLACED"); + OLD_TRACKING = rc->get_BoolFlag("OLD_TRACKING"); + + MaxHitsDC0 = rc->get_IntFlag("MaxHitsDC0"); + MaxHitsDC1 = rc->get_IntFlag("MaxHitsDC1"); + MaxHitsDC2 = rc->get_IntFlag("MaxHitsDC2"); + MaxHitsDC3p = rc->get_IntFlag("MaxHitsDC3p"); + MaxHitsDC3m = rc->get_IntFlag("MaxHitsDC3m"); + + TX_MAX = rc->get_DoubleFlag("TX_MAX"); + TY_MAX = rc->get_DoubleFlag("TY_MAX"); + X0_MAX = rc->get_DoubleFlag("X0_MAX"); + Y0_MAX = rc->get_DoubleFlag("Y0_MAX"); + INVP_MAX = rc->get_DoubleFlag("INVP_MAX"); + INVP_MIN = rc->get_DoubleFlag("INVP_MIN"); + Z_KMAG_BEND = rc->get_DoubleFlag("Z_KMAG_BEND"); + + SAGITTA_TARGET_CENTER = rc->get_DoubleFlag("SAGITTA_TARGET_CENTER"); + SAGITTA_TARGET_WIDTH = rc->get_DoubleFlag("SAGITTA_TARGET_WIDTH"); + SAGITTA_DUMP_CENTER = rc->get_DoubleFlag("SAGITTA_DUMP_CENTER"); + SAGITTA_DUMP_WIDTH = rc->get_DoubleFlag("SAGITTA_DUMP_WIDTH"); + Z_TARGET = rc->get_DoubleFlag("Z_TARGET"); + Z_DUMP = rc->get_DoubleFlag("Z_DUMP"); + + MUID_REJECTION = rc->get_DoubleFlag("MUID_REJECTION"); + MUID_Z_REF = rc->get_DoubleFlag("MUID_Z_REF"); + MUID_R_CUT = rc->get_DoubleFlag("MUID_R_CUT"); + MUID_THE_P0 = rc->get_DoubleFlag("MUID_THE_P0"); + MUID_EMP_P0 = rc->get_DoubleFlag("MUID_EMP_P0"); + MUID_EMP_P1 = rc->get_DoubleFlag("MUID_EMP_P1"); + MUID_EMP_P2 = rc->get_DoubleFlag("MUID_EMP_P2"); + MUID_MINHITS = rc->get_IntFlag("MUID_MINHITS"); + + KMAGSTR = rc->get_DoubleFlag("KMAGSTR"); + PT_KICK_KMAG = rc->get_DoubleFlag("PT_KICK_KMAG")*KMAGSTR; + } + } +} + +KalmanFastTracking_NEW_2::KalmanFastTracking_NEW_2(const PHField* field, const TGeoManager* geom, bool flag): verbosity(0), enable_KF(flag), outputListIdx(4) +{ + using namespace std; + initGlobalVariables(); + +#ifdef _DEBUG_ON + cout << "Initialization of KalmanFastTracking_NEW_2 ..." << endl; + cout << "========================================" << endl; +#endif + + _timers.insert(std::make_pair("st2", new PHTimer("st2"))); + _timers.insert(std::make_pair("st3", new PHTimer("st3"))); + _timers.insert(std::make_pair("st23", new PHTimer("st23"))); + _timers.insert(std::make_pair("global", new PHTimer("global"))); + _timers.insert(std::make_pair("global_st1", new PHTimer("global_st1"))); + _timers.insert(std::make_pair("global_link", new PHTimer("global_link"))); + _timers.insert(std::make_pair("global_kalman", new PHTimer("global_kalman"))); + _timers.insert(std::make_pair("kalman", new PHTimer("kalman"))); + + //Initialize Kalman fitter + if(enable_KF) + { + kmfitter = new KalmanFitter(field, geom); + kmfitter->setControlParameter(50, 0.001); + } + + //Initialize minuit minimizer + minimizer[0] = ROOT::Math::Factory::CreateMinimizer("Minuit2", "Simplex"); + minimizer[1] = ROOT::Math::Factory::CreateMinimizer("Minuit2", "Combined"); + fcn = ROOT::Math::Functor(&tracklet_curr, &Tracklet::Eval, KMAG_ON ? 5 : 4); + for(int i = 0; i < 2; ++i) + { + minimizer[i]->SetMaxFunctionCalls(1000000); + minimizer[i]->SetMaxIterations(100); + minimizer[i]->SetTolerance(1E-2); + minimizer[i]->SetFunction(fcn); + minimizer[i]->SetPrintLevel(0); + } + + //Minimize ROOT output + extern Int_t gErrorIgnoreLevel; + gErrorIgnoreLevel = 9999; + + //Initialize geometry service + p_geomSvc = GeomSvc::instance(); +#ifdef _DEBUG_ON + p_geomSvc->printTable(); + p_geomSvc->printWirePosition(); + p_geomSvc->printAlignPar(); +#endif + + //Initialize plane angles for all planes + for(int i = 1; i <= nChamberPlanes; ++i) + { + costheta_plane[i] = p_geomSvc->getCostheta(i); + sintheta_plane[i] = p_geomSvc->getSintheta(i); + } + + //Initialize hodoscope IDs + detectorIDs_mask[0] = p_geomSvc->getDetectorIDs("H1"); + detectorIDs_mask[1] = p_geomSvc->getDetectorIDs("H2"); + detectorIDs_mask[2] = p_geomSvc->getDetectorIDs("H3"); + detectorIDs_mask[3] = p_geomSvc->getDetectorIDs("H4"); + detectorIDs_maskX[0] = p_geomSvc->getDetectorIDs("H1[TB]"); + detectorIDs_maskX[1] = p_geomSvc->getDetectorIDs("H2[TB]"); + detectorIDs_maskX[2] = p_geomSvc->getDetectorIDs("H3[TB]"); + detectorIDs_maskX[3] = p_geomSvc->getDetectorIDs("H4[TB]"); + detectorIDs_maskY[0] = p_geomSvc->getDetectorIDs("H1[LR]"); + detectorIDs_maskY[1] = p_geomSvc->getDetectorIDs("H2[LR]"); + detectorIDs_maskY[2] = p_geomSvc->getDetectorIDs("H4Y1[LR]"); + detectorIDs_maskY[3] = p_geomSvc->getDetectorIDs("H4Y2[LR]"); + detectorIDs_muidHodoAid[0] = p_geomSvc->getDetectorIDs("H4[TB]"); + detectorIDs_muidHodoAid[1] = p_geomSvc->getDetectorIDs("H4Y"); + + //Register masking stations for tracklets in station-0/1, 2, 3+/- + stationIDs_mask[0].push_back(1); + stationIDs_mask[1].push_back(1); + stationIDs_mask[2].push_back(2); + stationIDs_mask[3].push_back(3); + stationIDs_mask[4].push_back(3); + + //Masking stations for back partial + stationIDs_mask[5].push_back(2); + stationIDs_mask[5].push_back(3); + stationIDs_mask[5].push_back(4); + + //Masking stations for global track + stationIDs_mask[6].push_back(1); + stationIDs_mask[6].push_back(2); + stationIDs_mask[6].push_back(3); + stationIDs_mask[6].push_back(4); + + //prop. tube IDs for mu id + detectorIDs_muid[0][0] = p_geomSvc->getDetectorID("P1X1"); + detectorIDs_muid[0][1] = p_geomSvc->getDetectorID("P1X2"); + detectorIDs_muid[0][2] = p_geomSvc->getDetectorID("P2X1"); + detectorIDs_muid[0][3] = p_geomSvc->getDetectorID("P2X2"); + detectorIDs_muid[1][0] = p_geomSvc->getDetectorID("P1Y1"); + detectorIDs_muid[1][1] = p_geomSvc->getDetectorID("P1Y2"); + detectorIDs_muid[1][2] = p_geomSvc->getDetectorID("P2Y1"); + detectorIDs_muid[1][3] = p_geomSvc->getDetectorID("P2Y2"); + + //Reference z_ref for mu id + z_ref_muid[0][0] = MUID_Z_REF; + z_ref_muid[0][1] = MUID_Z_REF; + z_ref_muid[0][2] = 0.5*(p_geomSvc->getPlanePosition(detectorIDs_muid[0][0]) + p_geomSvc->getPlanePosition(detectorIDs_muid[0][1])); + z_ref_muid[0][3] = z_ref_muid[0][2]; + + z_ref_muid[1][0] = MUID_Z_REF; + z_ref_muid[1][1] = MUID_Z_REF; + z_ref_muid[1][2] = 0.5*(p_geomSvc->getPlanePosition(detectorIDs_muid[1][0]) + p_geomSvc->getPlanePosition(detectorIDs_muid[1][1])); + z_ref_muid[1][3] = z_ref_muid[1][2]; + + //Initialize masking window sizes, with optimized contingency + for(int i = nChamberPlanes+1; i <= nChamberPlanes+nHodoPlanes+nPropPlanes; i++) + { + double factor = 0.; + if(i > nChamberPlanes && i <= nChamberPlanes+4) factor = 0.25; //for station-1 hodo + if(i > nChamberPlanes+4 && i <= nChamberPlanes+8) factor = 0.2; //for station-2 hodo + if(i > nChamberPlanes+8 && i <= nChamberPlanes+10) factor = 0.15; //for station-3 hodo + if(i > nChamberPlanes+10 && i <= nChamberPlanes+nHodoPlanes) factor = 0.; //for station-4 hodo + if(i > nChamberPlanes+nHodoPlanes) factor = 0.15; //for station-4 proptube + + z_mask[i-nChamberPlanes-1] = p_geomSvc->getPlanePosition(i); + for(int j = 1; j <= p_geomSvc->getPlaneNElements(i); j++) + { + double x_min, x_max, y_min, y_max; + p_geomSvc->get2DBoxSize(i, j, x_min, x_max, y_min, y_max); + + x_min -= (factor*(x_max - x_min)); + x_max += (factor*(x_max - x_min)); + y_min -= (factor*(y_max - y_min)); + y_max += (factor*(y_max - y_min)); + + x_mask_min[i-nChamberPlanes-1][j-1] = x_min; + x_mask_max[i-nChamberPlanes-1][j-1] = x_max; + y_mask_min[i-nChamberPlanes-1][j-1] = y_min; + y_mask_max[i-nChamberPlanes-1][j-1] = y_max; + } + } + +#ifdef _DEBUG_ON + cout << "========================" << endl; + cout << "Hodo. masking settings: " << endl; + for(int i = 0; i < 4; i++) + { + cout << "For station " << i+1 << endl; + for(std::vector::iterator iter = detectorIDs_mask[i].begin(); iter != detectorIDs_mask[i].end(); ++iter) cout << "All: " << *iter << endl; + for(std::vector::iterator iter = detectorIDs_maskX[i].begin(); iter != detectorIDs_maskX[i].end(); ++iter) cout << "X: " << *iter << endl; + for(std::vector::iterator iter = detectorIDs_maskY[i].begin(); iter != detectorIDs_maskY[i].end(); ++iter) cout << "Y: " << *iter << endl; + } + + for(int i = 0; i < nStations; ++i) + { + std::cout << "Masking stations for tracklets with stationID = " << i + 1 << ": " << std::endl; + for(std::vector::iterator iter = stationIDs_mask[i].begin(); iter != stationIDs_mask[i].end(); ++iter) + { + std::cout << *iter << " "; + } + std::cout << std::endl; + } +#endif + + //Initialize super stationIDs + for(int i = 0; i < nChamberPlanes/6+2; i++) superIDs[i].clear(); + superIDs[0].push_back((p_geomSvc->getDetectorIDs("D0X")[0] + 1)/2); + superIDs[0].push_back((p_geomSvc->getDetectorIDs("D0U")[0] + 1)/2); + superIDs[0].push_back((p_geomSvc->getDetectorIDs("D0V")[0] + 1)/2); + superIDs[1].push_back((p_geomSvc->getDetectorIDs("D1X")[0] + 1)/2); + superIDs[1].push_back((p_geomSvc->getDetectorIDs("D1U")[0] + 1)/2); + superIDs[1].push_back((p_geomSvc->getDetectorIDs("D1V")[0] + 1)/2); + superIDs[2].push_back((p_geomSvc->getDetectorIDs("D2X")[0] + 1)/2); + superIDs[2].push_back((p_geomSvc->getDetectorIDs("D2U")[0] + 1)/2); + superIDs[2].push_back((p_geomSvc->getDetectorIDs("D2V")[0] + 1)/2); + superIDs[3].push_back((p_geomSvc->getDetectorIDs("D3pX")[0] + 1)/2); + superIDs[3].push_back((p_geomSvc->getDetectorIDs("D3pU")[0] + 1)/2); + superIDs[3].push_back((p_geomSvc->getDetectorIDs("D3pV")[0] + 1)/2); + superIDs[4].push_back((p_geomSvc->getDetectorIDs("D3mX")[0] + 1)/2); + superIDs[4].push_back((p_geomSvc->getDetectorIDs("D3mU")[0] + 1)/2); + superIDs[4].push_back((p_geomSvc->getDetectorIDs("D3mV")[0] + 1)/2); + + superIDs[5].push_back((p_geomSvc->getDetectorIDs("P1X")[0] + 1)/2); + superIDs[5].push_back((p_geomSvc->getDetectorIDs("P2X")[0] + 1)/2); + superIDs[6].push_back((p_geomSvc->getDetectorIDs("P1Y")[0] + 1)/2); + superIDs[6].push_back((p_geomSvc->getDetectorIDs("P2Y")[0] + 1)/2); + +#ifdef _DEBUG_ON + cout << "=============" << endl; + cout << "Chamber IDs: " << endl; + TString stereoNames[3] = {"X", "U", "V"}; + for(int i = 0; i < nChamberPlanes/6; i++) + { + for(int j = 0; j < 3; j++) cout << i << " " << stereoNames[j].Data() << ": " << superIDs[i][j] << endl; + } + + cout << "Proptube IDs: " << endl; + for(int i = nChamberPlanes/6; i < nChamberPlanes/6+2; i++) + { + for(int j = 0; j < 2; j++) cout << i << " " << j << ": " << superIDs[i][j] << endl; + } + + //Initialize widow sizes for X-U matching and z positions of all chambers + cout << "======================" << endl; + cout << "U plane window sizes: " << endl; +#endif + + double u_factor[] = {5., 5., 5., 15., 15.}; + for(int i = 0; i < nChamberPlanes/6; i++) + { + int xID = 2*superIDs[i][0] - 1; + int uID = 2*superIDs[i][1] - 1; + int vID = 2*superIDs[i][2] - 1; + double spacing = p_geomSvc->getPlaneSpacing(uID); + double x_span = p_geomSvc->getPlaneScaleY(uID); + + z_plane_x[i] = 0.5*(p_geomSvc->getPlanePosition(xID) + p_geomSvc->getPlanePosition(xID+1)); + z_plane_u[i] = 0.5*(p_geomSvc->getPlanePosition(uID) + p_geomSvc->getPlanePosition(uID+1)); + z_plane_v[i] = 0.5*(p_geomSvc->getPlanePosition(vID) + p_geomSvc->getPlanePosition(vID+1)); + + u_costheta[i] = costheta_plane[uID]; + u_sintheta[i] = sintheta_plane[uID]; + + //u_win[i] = fabs(0.5*x_span/(spacing/sintheta_plane[uID])) + 2.*spacing + u_factor[i]; + u_win[i] = fabs(0.5*x_span*sintheta_plane[uID]) + TX_MAX*fabs((z_plane_u[i] - z_plane_x[i])*u_costheta[i]) + TY_MAX*fabs((z_plane_u[i] - z_plane_x[i])*u_sintheta[i]) + 2.*spacing + u_factor[i]; + +#ifdef _DEBUG_ON + cout << "Station " << i << ": " << xID << " " << uID << " " << vID << " " << u_win[i] << endl; +#endif + } + + //Initialize Z positions and maximum parameters of all planes + for(int i = 1; i <= nChamberPlanes; i++) + { + z_plane[i] = p_geomSvc->getPlanePosition(i); + slope_max[i] = costheta_plane[i]*TX_MAX + sintheta_plane[i]*TY_MAX; + intersection_max[i] = costheta_plane[i]*X0_MAX + sintheta_plane[i]*Y0_MAX; + +#ifdef COARSE_MODE + resol_plane[i] = 3.*p_geomSvc->getPlaneSpacing(i)/sqrt(12.); +#else + if(i <= 6) + { + resol_plane[i] = recoConsts::instance()->get_DoubleFlag("RejectWinDC0"); + } + else if(i <= 12) + { + resol_plane[i] = recoConsts::instance()->get_DoubleFlag("RejectWinDC1"); + } + else if(i <= 18) + { + resol_plane[i] = recoConsts::instance()->get_DoubleFlag("RejectWinDC2"); + } + else if(i <= 24) + { + resol_plane[i] = recoConsts::instance()->get_DoubleFlag("RejectWinDC3p"); + } + else + { + resol_plane[i] = recoConsts::instance()->get_DoubleFlag("RejectWinDC3m"); + } +#endif + spacing_plane[i] = p_geomSvc->getPlaneSpacing(i); + } + +#ifdef _DEBUG_ON + cout << "======================================" << endl; + cout << "Maximum local slope and intersection: " << endl; +#endif + for(int i = 1; i <= nChamberPlanes/2; i++) + { + double d_slope = (p_geomSvc->getPlaneResolution(2*i - 1) + p_geomSvc->getPlaneResolution(2*i))/(z_plane[2*i] - z_plane[2*i-1]); + double d_intersection = d_slope*z_plane[2*i]; + + slope_max[2*i-1] += d_slope; + intersection_max[2*i-1] += d_intersection; + slope_max[2*i] += d_slope; + intersection_max[2*i] += d_intersection; + +#ifdef _DEBUG_ON + cout << "Super plane " << i << ": " << slope_max[2*i-1] << " " << intersection_max[2*i-1] << endl; +#endif + } + + //Initialize sagitta ratios, index 0, 1, 2 are for X, U, V, this is the incrementing order of plane type + s_detectorID[0] = p_geomSvc->getDetectorID("D2X"); + s_detectorID[1] = p_geomSvc->getDetectorID("D2Up"); + s_detectorID[2] = p_geomSvc->getDetectorID("D2Vp"); +} + +KalmanFastTracking_NEW_2::~KalmanFastTracking_NEW_2() +{ + if(enable_KF) delete kmfitter; + delete minimizer[0]; + delete minimizer[1]; +} + +void KalmanFastTracking_NEW_2::setRawEventDebug(SRawEvent* event_input) +{ + rawEvent = event_input; + hitAll = event_input->getAllHits(); +} + +int KalmanFastTracking_NEW_2::setRawEvent(SRawEvent* event_input) +{ + //reset timer + for(auto iter=_timers.begin(); iter != _timers.end(); ++iter) + { + iter->second->reset(); + } + + //Initialize tracklet lists + for(int i = 0; i < 5; i++){ + trackletsInSt[i].clear(); + for(int b = 0; b < 200; b++){ + trackletsInStSlimX[i][b].clear(); + trackletsInStSlimU[i][b].clear(); + trackletsInStSlimV[i][b].clear(); + } + } + stracks.clear(); + + //pre-tracking cuts + rawEvent = event_input; + if(!acceptEvent(rawEvent)) return TFEXIT_FAIL_MULTIPLICITY; + hitAll = event_input->getAllHits(); +#ifdef _DEBUG_ON + for(std::vector::iterator iter = hitAll.begin(); iter != hitAll.end(); ++iter) iter->print(); +#endif + + //Initialize hodo and masking IDs + for(int i = 0; i < 4; i++) + { + //std::cout << "For station " << i << std::endl; + hitIDs_mask[i].clear(); + if(MC_MODE || COSMIC_MODE || rawEvent->isFPGATriggered()) + { + hitIDs_mask[i] = rawEvent->getHitsIndexInDetectors(detectorIDs_maskX[i]); + } + else + { + hitIDs_mask[i] = rawEvent->getHitsIndexInDetectors(detectorIDs_maskY[i]); + } + + //for(std::list::iterator iter = hitIDs_mask[i].begin(); iter != hitIDs_mask[i].end(); ++iter) std::cout << *iter << " " << hitAll[*iter].detectorID << " === "; + //std::cout << std::endl; + } + + //Initialize prop. tube IDs + for(int i = 0; i < 2; ++i) + { + for(int j = 0; j < 4; ++j) + { + hitIDs_muid[i][j].clear(); + hitIDs_muid[i][j] = rawEvent->getHitsIndexInDetector(detectorIDs_muid[i][j]); + } + hitIDs_muidHodoAid[i].clear(); + hitIDs_muidHodoAid[i] = rawEvent->getHitsIndexInDetectors(detectorIDs_muidHodoAid[i]); + } + + if(!COARSE_MODE) + { + buildPropSegments(); + if(propSegs[0].empty() || propSegs[1].empty()) + { +#ifdef _DEBUG_ON + LogInfo("Failed in prop tube segment building: " << propSegs[0].size() << ", " << propSegs[1].size()); +#endif + //return TFEXIT_FAIL_ROUGH_MUONID; + } + } + + //Get hit combinations in station 2 + _timers["st2"]->restart(); + buildTrackletsInStationSlim(3, 1); //3 for station-2, 1 for list position 1 + if(verbosity >= 2) std::cout<<"Station 2 x combos = "<= 2) std::cout<<"Station 2 u combos = "<= 2) std::cout<<"Station 2 v combos = "<stop(); + + + //Get hit combinations in station 3+ and 3- + _timers["st3"]->restart(); + buildTrackletsInStationSlim(4, 2); //4 for station-3+ + buildTrackletsInStationSlim(5, 2); //5 for station-3- + if(verbosity >= 2) std::cout<<"Station 3 x combos = "<= 2) std::cout<<"Station 3 u combos = "<= 2) std::cout<<"Station 3 v combos = "<stop(); + + + //Matching of station 2 and station 3 hits separately for the three wire tilts + _timers["st23"]->restart(); + buildBackPartialTracksSlimX(1, m_slopeComparison, m_windowSize); + buildBackPartialTracksSlimU(1, m_slopeComparison, m_windowSize); + buildBackPartialTracksSlimV(1, m_slopeComparison, m_windowSize); + + getNum23Combos(); + if(verbosity >= 2){ + std::cout<<"Station 2+3 x combos = "<stop(); + + if(verbosity >= 2) LogInfo("NTracklets St2+St3: " << trackletsInSt[3].size()); + + + if(outputListIdx > 3 && trackletsInSt[3].empty()) + { +#ifdef _DEBUG_ON + LogInfo("Failed in connecting station-2 and 3 tracks"); +#endif + return TFEXIT_FAIL_BACKPARTIAL; + } + + //Connect tracklets in station 2/3 and station 1 to form global tracks + _timers["global"]->restart(); + if(!TRACK_DISPLACED){ + buildGlobalTracks(); + } else{ + buildGlobalTracksDisplaced(); + } + _timers["global"]->stop(); + if(verbosity >= 2) LogInfo("NTracklets Global: " << trackletsInSt[4].size()); + +#ifdef _DEBUG_ON + for(int i = 0; i < 2; ++i) + { + std::cout << "=======================================================================================" << std::endl; + LogInfo("Prop tube segments in " << (i == 0 ? "X-Z" : "Y-Z")); + for(std::list::iterator seg = propSegs[i].begin(); seg != propSegs[i].end(); ++seg) + { + seg->print(); + } + std::cout << "=======================================================================================" << std::endl; + } + + for(int i = 0; i <= 4; i++) + { + std::cout << "=======================================================================================" << std::endl; + LogInfo("Final tracklets in station: " << i+1 << " is " << trackletsInSt[i].size()); + for(std::list::iterator tracklet = trackletsInSt[i].begin(); tracklet != trackletsInSt[i].end(); ++tracklet) + { + tracklet->print(); + } + std::cout << "=======================================================================================" << std::endl; + } +#endif + + if(outputListIdx == 4 && trackletsInSt[4].empty()) return TFEXIT_FAIL_GLOABL; + if(!enable_KF) return TFEXIT_SUCCESS; + + //Build kalman tracks + _timers["kalman"]->restart(); + for(std::list::iterator tracklet = trackletsInSt[outputListIdx].begin(); tracklet != trackletsInSt[outputListIdx].end(); ++tracklet) + { + SRecTrack strack = processOneTracklet(*tracklet); + stracks.push_back(strack); + } + _timers["kalman"]->stop(); + +#ifdef _DEBUG_ON + LogInfo(stracks.size() << " final tracks:"); + for(std::list::iterator strack = stracks.begin(); strack != stracks.end(); ++strack) + { + strack->print(); + } +#endif + + return TFEXIT_SUCCESS; +} + +bool KalmanFastTracking_NEW_2::acceptEvent(SRawEvent* rawEvent) +{ + if(Verbosity() >= Fun4AllBase::VERBOSITY_A_LOT) + { + LogInfo("D0: " << rawEvent->getNHitsInD0()); + LogInfo("D1: " << rawEvent->getNHitsInD1()); + LogInfo("D2: " << rawEvent->getNHitsInD2()); + LogInfo("D3p: " << rawEvent->getNHitsInD3p()); + LogInfo("D3m: " << rawEvent->getNHitsInD3m()); + LogInfo("H1: " << rawEvent->getNHitsInDetectors(detectorIDs_maskX[0])); + LogInfo("H2: " << rawEvent->getNHitsInDetectors(detectorIDs_maskX[1])); + LogInfo("H3: " << rawEvent->getNHitsInDetectors(detectorIDs_maskX[2])); + LogInfo("H4: " << rawEvent->getNHitsInDetectors(detectorIDs_maskX[3])); + LogInfo("Prop:" << rawEvent->getNPropHitsAll()); + LogInfo("NRoadsPos: " << rawEvent->getNRoadsPos()); + LogInfo("NRoadsNeg: " << rawEvent->getNRoadsNeg()); + } + + if(rawEvent->getNHitsInD0() > MaxHitsDC0) return false; + //if(rawEvent->getNHitsInD1() > MaxHitsDC1) return false; + if(rawEvent->getNHitsInD2() > MaxHitsDC2) return false; + if(rawEvent->getNHitsInD3p() > MaxHitsDC3p) return false; + if(rawEvent->getNHitsInD3m() > MaxHitsDC3m) return false; + + /* + if(rawEvent->getNHitsInDetectors(detectorIDs_maskX[0]) > 15) return false; + if(rawEvent->getNHitsInDetectors(detectorIDs_maskX[1]) > 10) return false; + if(rawEvent->getNHitsInDetectors(detectorIDs_maskX[2]) > 10) return false; + if(rawEvent->getNHitsInDetectors(detectorIDs_maskX[3]) > 10) return false; + if(rawEvent->getNPropHitsAll() > 300) return false; + + if(rawEvent->getNRoadsPos() > 5) return false; + if(rawEvent->getNRoadsNeg() > 5) return false; + */ + + return true; +} + + + + +void KalmanFastTracking_NEW_2::buildBackPartialTracksSlim_v3(int cut) +{ +#ifdef _DEBUG_PATRICK + LogInfo("In buildBackPartialTracksSlim_v3"); +#endif + + /**NOTE: THERE ARE SOME LOW-HANGING FRUITS HERE. FOR EXAMPLE, THIS IS EFFECTIVELY A TRIPLE LOOP OVER PLANES. WE COULD DO SOME STRAIGHFORWARD MATH TO FIGURE OUT THE LINE DEFINED BY THE INTERSECTIONS OF THE VARIOUS PLANES TO EXTRACT TRAJECTORY PARAMETERS AND CHECK COMPATIBILITY.**/ + + double chiSqCut = 300; //This can be dynamically decreased as a means of PU mitigation + //if( trackletsInStSlimX[3].size() > 150 || trackletsInStSlimU[3].size() > 150 || trackletsInStSlimV[3].size() > 150 ) chiSqCut = 100; //Example of cut decrease from old PU mitigation scheme + + int scanWidth = 142; //In the binned PU mitigation scheme, there are 200 bins that st2+st3 hit combinations fall into. The bins have width of 2cm, and are based on the st2 position information. + if(cut == 1) scanWidth = 30; //this will scan the innermost 60 cm of station 2 in x from -30 to +30 + + for(int binx = 2; binx < scanWidth; binx++){ //Rather than scanning just from left to right in the detector, I scan outwards from the center of station 2 (there's more PU at the edges typically). The outermost component of this triple loop is the vertical wire combinations + int bx = 100-(binx % 2 == 0 ? -1*floor((binx-1)/2) : floor(binx/2)); //Again, I'm scanning from the center, so the bin steps are 100, 99, 101, 98, 102, 97, 103, etc. + if(trackletsInStSlimX[3][bx].size()==0) continue; //Don't need to do anything if there aren't any hit combinations in this bin! + Tracklet tracklet_best_bin; //keep track of the best st2+st3 full combination per bin. + + for(std::list::iterator trackletX = trackletsInStSlimX[3][bx].begin(); trackletX != trackletsInStSlimX[3][bx].end(); ++trackletX){ //loop over the st2+st3 hit combinations for the vertical wires in this positional bin + Tracklet tracklet_best; + +#ifdef _DEBUG_FAST + std::cout<<"m_v3 try tracklet X:"<print(); +#endif + + for(int bu = std::max(0,bx-15); bu < std::min(200,bx+16); bu++){ //Rather than looking at all possible U combinations for each X combination, let's look at +/- 15 U bins. Relatively large set of bins because U is slanted relative to X, and we don't know the y position or y-slant of the particle! + if(trackletsInStSlimU[3][bu].size()==0) continue; + Tracklet tracklet_best_UX_bin; + + for(std::list::iterator trackletU = trackletsInStSlimU[3][bu].begin(); trackletU != trackletsInStSlimU[3][bu].end(); ++trackletU){ //loop over combinations in the U bin + Tracklet tracklet_best_UX; + +#ifdef _DEBUG_FAST + std::cout<<"m_v3 try tracklet U:"<print(); +#endif + + for(int bv = std::max(0, bx-1*(bu-bx)-2); bv < std::min(200,bx-1*(bu-bx)+3); bv++){ //For the bv bins, we combine our X and U position information. We scan a window of combinations on the opposite side of the st2 X position from the U combination in question. E.g., if the x bin was 55, and the U bin was 50, we would expect the correct V combination to be in the 60 bin. However, we still do a bit of a scan to allow for imprecision in those rough measurements + if(trackletsInStSlimV[3][bv].size()==0) continue; + Tracklet tracklet_best_UV_bin; + + for(std::list::iterator trackletV = trackletsInStSlimV[3][bv].begin(); trackletV != trackletsInStSlimV[3][bv].end(); ++trackletV){ + +#ifdef _DEBUG_FAST + std::cout<<"m_v3 try tracklet V:"<print(); +#endif + +#ifdef _DEBUG_FAST + //if(trackletsInStSlimX[3][bx].size() * trackletsInStSlimU[3][bu].size() * trackletsInStSlimV[3][bv].size() < 300){ + LogInfo("New combo"); + std::cout<<"trackletX->st2X = "<st2X<<"; trackletU->st2U = "<st2U<<"; trackletV->st2V = "<st2V<<";;; trackletX->st3X = "<st3X<<"; trackletU->st3U = "<st3U<<"; trackletV->st3V = "<st3V<st2Xsl = "<st2Xsl<<"; trackletU->st2Usl = "<st2Usl<<"; trackletV->st2Vsl = "<st2Vsl<<";;; trackletX->st3Xsl = "<st3Xsl<<"; trackletU->st3Usl = "<st3Usl<<"; trackletV->st3Vsl = "<st3Vsl<print(); + trackletU->print(); + trackletV->print(); + //} +#endif + + //quick checks on hit combination compatibility in the three wire slants + if( std::abs( (trackletX->st2Xsl - trackletU->st2Usl) - -1.*(trackletX->st2Xsl - trackletV->st2Vsl) ) > 0.04 ) continue; + if( std::abs( (trackletX->st2X - trackletU->st2U) - -1.*(trackletX->st2X - trackletV->st2V) ) > 7. ) continue; + if( std::abs( (trackletX->st3X - trackletU->st3U) - -1.*(trackletX->st3X - trackletV->st3V) ) > 7. ) continue; + +#ifdef _DEBUG_FAST + LogInfo("OK combo"); +#endif + + double st2UWireSin = TMath::Sin(TMath::ATan(1./trackletU->acceptedULine2.wire1Slope)); + double st2VWireSin = TMath::Sin(TMath::ATan(1./trackletV->acceptedVLine2.wire1Slope)); + double st3UWireSin = TMath::Sin(TMath::ATan(1./trackletU->acceptedULine3.wire1Slope)); + double st3VWireSin = TMath::Sin(TMath::ATan(1./trackletV->acceptedVLine3.wire1Slope)); + + double st2UWireCos = TMath::Cos(TMath::ATan(1./trackletU->acceptedULine2.wire1Slope)); + double st2VWireCos = TMath::Cos(TMath::ATan(1./trackletV->acceptedVLine2.wire1Slope)); + double st3UWireCos = TMath::Cos(TMath::ATan(1./trackletU->acceptedULine3.wire1Slope)); + double st3VWireCos = TMath::Cos(TMath::ATan(1./trackletV->acceptedVLine3.wire1Slope)); + + double testTY2 = ( trackletV->st2Vsl - (st2VWireCos/st2UWireCos)*trackletU->st2Usl )/( (st2VWireCos * st2UWireSin)/(st2UWireCos) - st2VWireSin ); + double testTY3 = ( trackletV->st3Vsl - (st3VWireCos/st3UWireCos)*trackletU->st3Usl )/( (st3VWireCos * st3UWireSin)/(st3UWireCos) - st3VWireSin ); + double testTX2 = ( trackletU->st2Usl - (st2UWireSin/st2VWireSin)*trackletV->st2Vsl )/( st2UWireCos - ( st2UWireSin * st2VWireCos )/st2VWireSin ); + double testTX3 = ( trackletU->st3Usl - (st3UWireSin/st3VWireSin)*trackletV->st3Vsl )/( st3UWireCos - ( st3UWireSin * st3VWireCos )/st3VWireSin ); + +#ifdef _DEBUG_FAST + std::cout<<"testTY2 = "<st2Xsl - testTX2) > 0.007 || std::abs(trackletX->st2Xsl - testTX3) > 0.007) continue; //The x-slopes extracted from the U and V wires should match the slope found from the X wires + +#ifdef _DEBUG_FAST + LogInfo("past cont 2"); +#endif + + + //Let's build a tracklet and assign the x0, tx, and ty parameters (and also the dummy invP parameter). What we don't know right now is y0. HOWEVER, IF WE DID SOME MATH TO FIND THE LINE DEFINED BY THE INTERSECTION OF THE PLANES, WE WOULD KNOW THE Y0 VALUE! + Tracklet tracklet_TEST_23 = (*trackletX) + (*trackletU) + (*trackletV); + tracklet_TEST_23.tx = trackletX->st2Xsl; + tracklet_TEST_23.ty = (testTY2 + testTY3)/2.; //take an average of the ty value extracted from the U and V values to hedge your bets + tracklet_TEST_23.invP = 1./50.; + tracklet_TEST_23.x0 = trackletX->st2Xsl * (0. - trackletX->st2Z) + trackletX->st2X; //simple exrapolation back to z = 0 + + tracklet_TEST_23.sortHits(); + + double testY0 = (-1.*p_geomSvc->getDCA((*trackletU).getHit(0).hit.detectorID, (*trackletU).getHit(0).hit.elementID, tracklet_TEST_23.tx, tracklet_TEST_23.ty, tracklet_TEST_23.x0, 0)/std::abs(st2UWireSin) + p_geomSvc->getDCA((*trackletV).getHit(0).hit.detectorID, (*trackletV).getHit(0).hit.elementID, tracklet_TEST_23.tx, tracklet_TEST_23.ty, tracklet_TEST_23.x0, 0)/std::abs(st2UWireSin))/2.; //This is a method to extract y0 based on what the distance of closest approach would be to the st2 U and V hits if the y0 was 0. A little hacky. Again, extracting this information from the line defined by the plane intersections would be much smarter and better + tracklet_TEST_23.y0 = testY0; + + + if( tracklet_TEST_23.calcChisq_noDrift() > chiSqCut || isnan(tracklet_TEST_23.calcChisq_noDrift()) ) continue; //check the chisq when drift distances are not accounted for. (When using drift distance, the expected precision changes, driving up the chisq given that we only have a "rough" extraction of the trajectory parameters at this point) +#ifdef _DEBUG_FAST + LogInfo("past cont 4"); +#endif + //Assign some parameters that get used later + tracklet_TEST_23.st2Z = trackletX->st2Z; + tracklet_TEST_23.st2X = trackletX->st2X; + tracklet_TEST_23.st2Y = tracklet_TEST_23.y0 + tracklet_TEST_23.ty * tracklet_TEST_23.st2Z; + tracklet_TEST_23.st3Y = tracklet_TEST_23.y0 + tracklet_TEST_23.ty * trackletX->st3Z; + tracklet_TEST_23.st2U = trackletU->st2U; + tracklet_TEST_23.st2V = trackletV->st2V; + tracklet_TEST_23.st2Usl = trackletU->st2Usl; + tracklet_TEST_23.st2Vsl = trackletV->st2Vsl; + + + fitTracklet(tracklet_TEST_23); + + //Assign hit sign for unknown hits + for(std::list::iterator hit1 = tracklet_TEST_23.hits.begin(); hit1 != tracklet_TEST_23.hits.end(); ++hit1){ + if(hit1->sign == 0){ + hit1->sign = 1; + fitTracklet(tracklet_TEST_23); + double dcaPlus = tracklet_TEST_23.chisq; + hit1->sign = -1; + fitTracklet(tracklet_TEST_23); + double dcaMinus = tracklet_TEST_23.chisq; + if(std::abs(dcaPlus) < std::abs(dcaMinus)){ + hit1->sign = 1; + } else{ + hit1->sign = -1; + } + } + } + + ///Remove bad hits if needed; Right now this doesn't play nicely with this algorithm + //removeBadHits(tracklet_TEST_23); + + fitTracklet(tracklet_TEST_23); //A final fit now that all hits have been assigned signs + + + if(tracklet_TEST_23.chisq > 9000.) + { +#ifdef _DEBUG_ON + tracklet_TEST_23.print(); + LogInfo("Impossible combination!"); +#endif + continue; + } + +#ifdef _DEBUG_PATRICK + LogInfo("New tracklet: "); + tracklet_TEST_23.print(); + + LogInfo("Current best:"); + tracklet_best_UV_bin.print(); + + LogInfo("Comparison: " << (tracklet_TEST_23 < tracklet_best_UV_bin)); + LogInfo("Candidate chisq: " << tracklet_TEST_23.chisq); + LogInfo("Quality: " << acceptTracklet(tracklet_TEST_23)); +#endif + + //If current tracklet is better than the best tracklet up-to-now + if(acceptTracklet(tracklet_TEST_23) && tracklet_TEST_23 < tracklet_best_UV_bin) + { + tracklet_best_UV_bin = tracklet_TEST_23; + } +#ifdef _DEBUG_ON + else + { + LogInfo("Rejected!!"); + } +#endif + + } + if(tracklet_best_UV_bin < tracklet_best_UX){ + tracklet_best_UX = tracklet_best_UV_bin; + } + } + if(tracklet_best_UX < tracklet_best_UX_bin){ + tracklet_best_UX_bin = tracklet_best_UX; + } + } + if(tracklet_best_UX_bin < tracklet_best){ + tracklet_best = tracklet_best_UX_bin; + } + } + if(tracklet_best < tracklet_best_bin){ + tracklet_best_bin = tracklet_best; + } + } + if(acceptTracklet(tracklet_best_bin)){ + if(tracklet_best_bin.isValid() > 0){ + if(tracklet_best_bin.chisq < 15.){ + trackletsInSt[3].push_back(tracklet_best_bin); +#ifdef _DEBUG_ON + tracklet_best_bin.print(); +#endif + + } + } + } + } +} + + + +void KalmanFastTracking_NEW_2::buildBackPartialTracksSlimX(int pass, double slopeComparison, double windowSize) +{ + + for(std::list::iterator tracklet3 = trackletsInStSlimX[2][0].begin(); tracklet3 != trackletsInStSlimX[2][0].end(); ++tracklet3) + { + + Tracklet tracklet_best; + for(std::list::iterator tracklet2 = trackletsInStSlimX[1][0].begin(); tracklet2 != trackletsInStSlimX[1][0].end(); ++tracklet2) + { +#ifdef _DEBUG_RES + if(trackletsInStSlimX[1][0].size() < 10 && trackletsInStSlimX[2][0].size() < 10){ + tracklet2->print(); + tracklet3->print(); + } +#endif + + Tracklet tracklet_23; + if(OLD_TRACKING){ + tracklet_23 = (*tracklet2) + (*tracklet3); + } + else{ + //check if the combination is valid. compareTrackletsSlim checks 2+2 hit combinations, and compareTrackletsSlim_3hits checks 2+1 combinations + if(compareTrackletsSlim(*tracklet2, *tracklet3, pass, slopeComparison, windowSize) || (pass == 1 && compareTrackletsSlim_3hits(*tracklet2, *tracklet3, pass, slopeComparison, windowSize)) ){ + tracklet_23 = (*tracklet2) + (*tracklet3); + tracklet_23.tx = tracklet2->tx; + tracklet_23.st2X = tracklet2->st2X; + tracklet_23.st2Z = tracklet2->st2Z; + tracklet_23.st3X = tracklet3->st3X; + tracklet_23.st3Z = tracklet3->st2Z; + tracklet_23.st2Xsl = tracklet2->st2Xsl; + tracklet_23.st3Xsl = tracklet3->st2Xsl; + tracklet_23.acceptedXLine2 = tracklet2->acceptedXLine2; + tracklet_23.acceptedXLine3 = tracklet3->acceptedXLine3; + +#ifdef _DEBUG_ON + LogInfo("We had a match using following two tracklets:"); + tracklet2->print(); + tracklet3->print(); + LogInfo("Yield this combination:"); + tracklet_23.print(); +#endif + + if(tracklet_23.st2X > -200. && tracklet_23.st2X < 200){ + int bin = floor( (tracklet_23.st2X + 200) / 2 ); //Put tracklet into a bin based on st2 position + trackletsInStSlimX[3][bin].push_back(tracklet_23); + } else{ + continue; + } + } + else{ + continue; + } + } + } + } +} + +void KalmanFastTracking_NEW_2::buildBackPartialTracksSlimU(int pass, double slopeComparison, double windowSize) +{ + + for(std::list::iterator tracklet3 = trackletsInStSlimU[2][0].begin(); tracklet3 != trackletsInStSlimU[2][0].end(); ++tracklet3) + { + Tracklet tracklet_best; + for(std::list::iterator tracklet2 = trackletsInStSlimU[1][0].begin(); tracklet2 != trackletsInStSlimU[1][0].end(); ++tracklet2) + { +#ifdef _DEBUG_RES + if(trackletsInStSlimU[1][0].size() < 10 && trackletsInStSlimU[2][0].size() < 10){ + tracklet2->print(); + tracklet3->print(); + } +#endif + + Tracklet tracklet_23; + if(OLD_TRACKING){ + tracklet_23 = (*tracklet2) + (*tracklet3); + } + else{ + if(compareTrackletsSlimU(*tracklet2, *tracklet3, pass, slopeComparison, windowSize) || (pass == 1 && compareTrackletsSlimU_3hits(*tracklet2, *tracklet3, pass, slopeComparison, windowSize)) ){ + tracklet_23 = (*tracklet2) + (*tracklet3); + tracklet_23.tx = tracklet2->tx; + tracklet_23.st2U = tracklet2->st2U; + tracklet_23.st2Z = tracklet2->st2Z; + tracklet_23.st3U = tracklet3->st3U; + tracklet_23.st3Z = tracklet3->st2Z; + tracklet_23.st2Usl = tracklet2->st2Usl; + tracklet_23.st3Usl = tracklet3->st2Usl; + tracklet_23.acceptedULine2 = tracklet2->acceptedULine2; + tracklet_23.acceptedULine3 = tracklet3->acceptedULine3; + +#ifdef _DEBUG_ON + LogInfo("We had a match using following two tracklets:"); + tracklet2->print(); + tracklet3->print(); + LogInfo("Yield this combination:"); + tracklet_23.print(); +#endif + + if(tracklet_23.st2U > -200. && tracklet_23.st2U < 200){ + int bin = floor( (tracklet_23.st2U + 200) / 2 ); + trackletsInStSlimU[3][bin].push_back(tracklet_23); + } else{ + continue; + } + } + else{ + continue; + } + } + } + } +} + + + +void KalmanFastTracking_NEW_2::buildBackPartialTracksSlimV(int pass, double slopeComparison, double windowSize) +{ + + for(std::list::iterator tracklet3 = trackletsInStSlimV[2][0].begin(); tracklet3 != trackletsInStSlimV[2][0].end(); ++tracklet3) + { + Tracklet tracklet_best; + for(std::list::iterator tracklet2 = trackletsInStSlimV[1][0].begin(); tracklet2 != trackletsInStSlimV[1][0].end(); ++tracklet2) + { +#ifdef _DEBUG_RES + if(trackletsInStSlimV[1][0].size() < 10 && trackletsInStSlimV[2][0].size() < 10){ + tracklet2->print(); + tracklet3->print(); + } +#endif + + Tracklet tracklet_23; + if(OLD_TRACKING){ + tracklet_23 = (*tracklet2) + (*tracklet3); + } + else{ + if(compareTrackletsSlimV(*tracklet2, *tracklet3, pass, slopeComparison, windowSize) || (pass == 1 && compareTrackletsSlimV_3hits(*tracklet2, *tracklet3, pass, slopeComparison, windowSize)) ){ + tracklet_23 = (*tracklet2) + (*tracklet3); + tracklet_23.tx = tracklet2->tx; + tracklet_23.st2V = tracklet2->st2V; + tracklet_23.st2Z = tracklet2->st2Z; + tracklet_23.st3V = tracklet3->st3V; + tracklet_23.st3Z = tracklet3->st2Z; + tracklet_23.st2Vsl = tracklet2->st2Vsl; + tracklet_23.st3Vsl = tracklet3->st2Vsl; + tracklet_23.acceptedVLine2 = tracklet2->acceptedVLine2; + tracklet_23.acceptedVLine3 = tracklet3->acceptedVLine3; + +#ifdef _DEBUG_ON + LogInfo("We had a match using following two tracklets:"); + tracklet2->print(); + tracklet3->print(); + LogInfo("Yield this combination:"); + tracklet_23.print(); +#endif + + if(tracklet_23.st2V > -200. && tracklet_23.st2V < 200){ + int bin = floor( (tracklet_23.st2V + 200) / 2 ); + trackletsInStSlimV[3][bin].push_back(tracklet_23); + } else{ + continue; + } + } + else{ + continue; + } + } + } + } +} + +void KalmanFastTracking_NEW_2::buildGlobalTracks() +{ + double pos_exp[3], window[3]; + for(std::list::iterator tracklet23 = trackletsInSt[3].begin(); tracklet23 != trackletsInSt[3].end(); ++tracklet23) + { + Tracklet tracklet_best[2]; + for(int i = 0; i < 2; ++i) //for two station-1 chambers + { + trackletsInSt[0].clear(); + if(!TRACK_DISPLACED){ + //Calculate the window in station 1 + if(KMAG_ON) + { + getSagittaWindowsInSt1(*tracklet23, pos_exp, window, i+1); + } + else + { + getExtrapoWindowsInSt1(*tracklet23, pos_exp, window, i+1); + } + } +#ifdef _DEBUG_ON + LogInfo("Using this back partial: "); + tracklet23->print(); + for(int j = 0; j < 3; j++) LogInfo("Extrapo: " << pos_exp[j] << " " << window[j]); +#endif + + _timers["global_st1"]->restart(); + if(!TRACK_DISPLACED){ + buildTrackletsInStation(i+1, 0, pos_exp, window); + } + if(TRACK_DISPLACED){ + buildTrackletsInStation(i+1, 0); + } + + _timers["global_st1"]->stop(); + + _timers["global_link"]->restart(); + Tracklet tracklet_best_prob, tracklet_best_vtx; + for(std::list::iterator tracklet1 = trackletsInSt[0].begin(); tracklet1 != trackletsInSt[0].end(); ++tracklet1) + { +#ifdef _DEBUG_ON + LogInfo("With this station 1 track:"); + tracklet1->print(); +#endif + + Tracklet tracklet_global = (*tracklet23) * (*tracklet1); + fitTracklet(tracklet_global); + if(!hodoMask(tracklet_global)) continue; + + ///Resolve the left-right with a tight pull cut, then a loose one, then resolve by single projections + if(!COARSE_MODE) + { + resolveLeftRight(tracklet_global, 75.); + resolveLeftRight(tracklet_global, 150.); + resolveSingleLeftRight(tracklet_global); + } + if(TRACK_DISPLACED){ + double firstChiSq = tracklet_global.calcChisq(); + Tracklet tracklet_global2 = (*tracklet23) * (*tracklet1); + tracklet_global2.setCharge(-1*tracklet_global2.getCharge()); /**By default, the value returned by getCharge is based on the x0 of the tracklet. For a particle produced at the target, this is a valid way to extract charge. However, for a displaced particle, the x0 does not tell you anything useful about the charge of the particle, which is why we need to check both possible charge values. getCharge is used later on when extracting certain track quality values, so using the wrong charge leads to tracks getting rejected due to poor quality values*/ + if(!COARSE_MODE) + { + resolveLeftRight(tracklet_global2, 75.); + resolveLeftRight(tracklet_global2, 150.); + resolveSingleLeftRight(tracklet_global2); + } + double secondChiSq = tracklet_global2.calcChisq(); + if(secondChiSq < firstChiSq){ + tracklet_global = tracklet_global2; + } + } + + ///Remove bad hits if needed + removeBadHits(tracklet_global); + + //Most basic cuts + if(!acceptTracklet(tracklet_global)) continue; + + //Get the tracklets that has the best prob + if(tracklet_global < tracklet_best_prob) tracklet_best_prob = tracklet_global; + + ///Set vertex information - only applied when KF is enabled + ///TODO: maybe in the future add a Genfit-based equivalent here, for now leave as is + if(enable_KF && NOT_DISPLACED) + { + _timers["global_kalman"]->restart(); + SRecTrack recTrack = processOneTracklet(tracklet_global); + _timers["global_kalman"]->stop(); + tracklet_global.chisq_vtx = recTrack.getChisqVertex(); + + if(recTrack.isValid() && tracklet_global.chisq_vtx < tracklet_best_vtx.chisq_vtx) tracklet_best_vtx = tracklet_global; + } + +#ifdef _DEBUG_ON + LogInfo("New tracklet: "); + tracklet_global.print(); + + LogInfo("Current best by prob:"); + tracklet_best_prob.print(); + + LogInfo("Comparison I: " << (tracklet_global < tracklet_best_prob)); + LogInfo("Quality I : " << acceptTracklet(tracklet_global)); + + if(enable_KF && NOT_DISPLACED) + { + LogInfo("Current best by vtx:"); + tracklet_best_vtx.print(); + + LogInfo("Comparison II: " << (tracklet_global.chisq_vtx < tracklet_best_vtx.chisq_vtx)); + //LogInfo("Quality II : " << recTrack.isValid()); + } +#endif + } + _timers["global_link"]->stop(); + + //The selection logic is, prefer the tracks with best p-value, as long as it's not low-pz + if(enable_KF && NOT_DISPLACED && tracklet_best_prob.isValid() > 0 && 1./tracklet_best_prob.invP > 18.) + { + tracklet_best[i] = tracklet_best_prob; + } + else if(enable_KF && NOT_DISPLACED && tracklet_best_vtx.isValid() > 0) //otherwise select the one with best vertex chisq, TODO: maybe add a z-vtx constraint + { + tracklet_best[i] = tracklet_best_vtx; + } + else if(tracklet_best_prob.isValid() > 0) //then fall back to the default only choice + { + tracklet_best[i] = tracklet_best_prob; + } + } + + //Merge the tracklets from two stations if necessary + Tracklet tracklet_merge; + if(fabs(tracklet_best[0].getMomentum() - tracklet_best[1].getMomentum())/tracklet_best[0].getMomentum() < MERGE_THRES) + { + //Merge the track and re-fit + tracklet_merge = tracklet_best[0].merge(tracklet_best[1]); + fitTracklet(tracklet_merge); + +#ifdef _DEBUG_ON + LogInfo("Merging two track candidates with momentum: " << tracklet_best[0].getMomentum() << " " << tracklet_best[1].getMomentum()); + LogInfo("tracklet_best_1:"); tracklet_best[0].print(); + LogInfo("tracklet_best_2:"); tracklet_best[1].print(); + LogInfo("tracklet_merge:"); tracklet_merge.print(); +#endif + } + + if(tracklet_merge.isValid() > 0 && tracklet_merge < tracklet_best[0] && tracklet_merge < tracklet_best[1]) + { +#ifdef _DEBUG_ON + LogInfo("Choose merged tracklet"); +#endif + trackletsInSt[4].push_back(tracklet_merge); + } + else if(tracklet_best[0].isValid() > 0 && tracklet_best[0] < tracklet_best[1]) + { +#ifdef _DEBUG_ON + LogInfo("Choose tracklet with station-0"); +#endif + trackletsInSt[4].push_back(tracklet_best[0]); + } + else if(tracklet_best[1].isValid() > 0) + { +#ifdef _DEBUG_ON + LogInfo("Choose tracklet with station-1"); +#endif + trackletsInSt[4].push_back(tracklet_best[1]); + } + } + + trackletsInSt[4].sort(); +} + + +void KalmanFastTracking_NEW_2::buildGlobalTracksDisplaced() +{ + double pos_exp[3], window[3]; + for(std::list::iterator tracklet23 = trackletsInSt[3].begin(); tracklet23 != trackletsInSt[3].end(); ++tracklet23) + { + + Tracklet tracklet_best_prob, tracklet_best_vtx; + + double posx = tracklet23->tx * ( z_plane[3] - tracklet23->st2Z ) + tracklet23->st2X; + double posu = tracklet23->st2Usl * ( z_plane[1] - tracklet23->st2Z ) + tracklet23->st2U; + double posv = tracklet23->st2Vsl * ( z_plane[5] - tracklet23->st2Z ) + tracklet23->st2V; + double posy = tracklet23->ty * ( z_plane[3] - tracklet23->st2Z ) + tracklet23->st2Y; + + + Tracklet tracklet_best[2]; + for(int i = 0; i < 1; ++i) //for two station-1 chambers //WPM edited so that it only does one chamber. I think that's all we're using in our simulation... + { + + bool validTrackFound = false; //WPM + int pxSlices[8] = {1, 3, 5, 7, 9, 11, 13, 15}; //This is another scan outward from a linear extrapolation from station 2+3. We don't know the momentum or charge at this point! The range here does limit the pz range that you can find to some extent, but I can get below 10 GeV with this range + for(int pxs = 0; pxs < 8; pxs++){ //WPM + if(validTrackFound) continue; //WPM potentially controversial. Trying to get out of px window loop + + int charges[2] = {-1,1}; //WPM + for(int ch = 0; ch < 2; ch++){ //WPM + + if(validTrackFound) continue; //WPM potentially controversial. Trying to get out of px window loop. Finding higher pz tracks takes less time + + trackletsInStSlimX[0][0].clear(); + trackletsInStSlimU[0][0].clear(); + trackletsInStSlimV[0][0].clear(); + + trackletsInSt[0].clear(); + if(!TRACK_DISPLACED){ + //Calculate the window in station 1 + if(KMAG_ON) + { + getSagittaWindowsInSt1(*tracklet23, pos_exp, window, i+1); + } + else + { + getExtrapoWindowsInSt1(*tracklet23, pos_exp, window, i+1); + } + } +#ifdef _DEBUG_ON + LogInfo("Using this back partial: "); + tracklet23->print(); + for(int j = 0; j < 3; j++) LogInfo("Extrapo: " << pos_exp[j] << " " << window[j]); +#endif + + (*tracklet23).setCharge(charges[ch]); //WPM + double expXZSlope = ((*tracklet23).tx - 0.002 * charges[ch]*pxSlices[pxs]); + + _timers["global_st1"]->restart(); + if(!TRACK_DISPLACED){ + buildTrackletsInStation(i+1, 0, pos_exp, window); + } + if(TRACK_DISPLACED){ + pos_exp[0] = posx+charges[ch]*pxSlices[pxs]; + //get expected U and V positions in station 1 + double testSt1Upos = p_geomSvc->getCostheta(1) * ( expXZSlope * (z_plane[1] - z_plane[3]) + pos_exp[0]) + p_geomSvc->getSintheta(1) * (tracklet23->ty * z_plane[1] + tracklet23->y0); + double testSt1Vpos = p_geomSvc->getCostheta(5) * ( expXZSlope * (z_plane[5] - z_plane[3]) + pos_exp[0]) + p_geomSvc->getSintheta(5) * (tracklet23->ty * z_plane[5] + tracklet23->y0); + pos_exp[1] = testSt1Upos; + pos_exp[2] = testSt1Vpos; + window[0] = 1.25; + window[1] = 1.5; + window[2] = 1.5; + buildTrackletsInStationSlim(i+1, 0, pos_exp, window); + buildTrackletsInStationSlimU(i+1, 0, pos_exp, window); + buildTrackletsInStationSlimV(i+1, 0, pos_exp, window); + getNum1Combos(); + bool doTight = false; + if(num1XCombos*num1UCombos*num1VCombos > 3000) doTight = true; //Some station 1 pileup mitigation! + if(!(buildTrackletsInStation1_NEW(i+1, 0, expXZSlope, (*tracklet23).ty, (*tracklet23).y0, doTight, pos_exp, window))) continue; //Find station 1 hit combinations in the relevant window + } + _timers["global_st1"]->stop(); + + if(_timers["global_st1"]->get_accumulated_time()/1000. > 10.) return; + + _timers["global_link"]->restart(); + int tracklet_counter = 0; //WPM + +#ifdef _DEBUG_PATRICK + LogInfo("the size of trackletsInSt[0] is "<::iterator tracklet1 = trackletsInSt[0].begin(); tracklet1 != trackletsInSt[0].end(); ++tracklet1) + { //loop over the potential station 1 tracklets that we found +#ifdef _DEBUG_ON + LogInfo("a new station 1 tracklet global tracks displaced. trackletCounter = "<print(); + trackletCounter++; +#endif + + tracklet_counter++; //WPM +#ifdef _DEBUG_ON + LogInfo("With this station 1 track:"); + tracklet1->print(); +#endif + + Tracklet tracklet_global = (*tracklet23) * (*tracklet1); + tracklet_global.setCharge(charges[ch]); //WPM + fitTracklet(tracklet_global); + if(!COARSE_MODE) + { + //I don't actually know if this is necessary anymore + resolveLeftRight(tracklet_global, 75.); + resolveLeftRight(tracklet_global, 150.); + resolveSingleLeftRight(tracklet_global); + } + + ///Remove bad hits if needed + //removeBadHits(tracklet_global); + +#ifdef _DEBUG_ON + LogInfo("removed bad hits in global tracks displaced"); +#endif + + //Most basic cuts + if(!acceptTracklet(tracklet_global)) continue; + +#ifdef _DEBUG_ON + LogInfo("accepted tracklet global tracks displaced"); +#endif + + //Get the tracklets that has the best prob + if(tracklet_global < tracklet_best_prob) tracklet_best_prob = tracklet_global; + + ///Set vertex information - only applied when KF is enabled + ///TODO: maybe in the future add a Genfit-based equivalent here, for now leave as is + if(enable_KF && NOT_DISPLACED) + { + _timers["global_kalman"]->restart(); + SRecTrack recTrack = processOneTracklet(tracklet_global); + _timers["global_kalman"]->stop(); + tracklet_global.chisq_vtx = recTrack.getChisqVertex(); + + if(recTrack.isValid() && tracklet_global.chisq_vtx < tracklet_best_vtx.chisq_vtx) tracklet_best_vtx = tracklet_global; + } + +#ifdef _DEBUG_ON + LogInfo("New tracklet: "); + tracklet_global.print(); + + LogInfo("Current best by prob:"); + tracklet_best_prob.print(); + + LogInfo("Comparison I: " << (tracklet_global < tracklet_best_prob)); + LogInfo("Quality I : " << acceptTracklet(tracklet_global)); + + if(enable_KF && NOT_DISPLACED) + { + LogInfo("Current best by vtx:"); + tracklet_best_vtx.print(); + + LogInfo("Comparison II: " << (tracklet_global.chisq_vtx < tracklet_best_vtx.chisq_vtx)); + //LogInfo("Quality II : " << recTrack.isValid()); + } +#endif + } + + _timers["global_link"]->stop(); + + //The selection logic is, prefer the tracks with best p-value, as long as it's not low-pz + if(enable_KF && NOT_DISPLACED && tracklet_best_prob.isValid() > 0 && 1./tracklet_best_prob.invP > 18.) + { + tracklet_best[i] = tracklet_best_prob; + //if(tracklet_best_prob.hits.size()==6) validTrackFound = true; + } + else if(enable_KF && NOT_DISPLACED && tracklet_best_vtx.isValid() > 0) //otherwise select the one with best vertex chisq, TODO: maybe add a z-vtx constraint + { + tracklet_best[i] = tracklet_best_vtx; + //if(tracklet_best_vtx.hits.size()==6) validTrackFound = true; + } + else if(tracklet_best_prob.isValid() > 0) //then fall back to the default only choice + { + tracklet_best[i] = tracklet_best_prob; + //if(tracklet_best_prob.hits.size()==6) validTrackFound = true; + } + } + if(tracklet_best_prob.chisq < 1.) break; //MIGHT NEED TO RECONSIDER THIS ACTUALLY + } + if(tracklet_best_prob.chisq < 1.) break; //SIMILARLY THIS MIGHT BE TOO TIGHT + } + + //Merge the tracklets from two stations if necessary + Tracklet tracklet_merge; + if(fabs(tracklet_best[0].getMomentum() - tracklet_best[1].getMomentum())/tracklet_best[0].getMomentum() < MERGE_THRES) + { + //Merge the track and re-fit + tracklet_merge = tracklet_best[0].merge(tracklet_best[1]); + fitTracklet(tracklet_merge); + +#ifdef _DEBUG_ON + LogInfo("Merging two track candidates with momentum: " << tracklet_best[0].getMomentum() << " " << tracklet_best[1].getMomentum()); + LogInfo("tracklet_best_1:"); tracklet_best[0].print(); + LogInfo("tracklet_best_2:"); tracklet_best[1].print(); + LogInfo("tracklet_merge:"); tracklet_merge.print(); +#endif + } + + if(tracklet_merge.isValid() > 0 && tracklet_merge < tracklet_best[0] && tracklet_merge < tracklet_best[1]) + { +#ifdef _DEBUG_ON + LogInfo("Choose merged tracklet"); +#endif + + trackletsInSt[4].push_back(tracklet_merge); + } + else if(tracklet_best[0].isValid() > 0 && tracklet_best[0] < tracklet_best[1]) + { +#ifdef _DEBUG_ON + LogInfo("Choose tracklet with station-0"); +#endif + trackletsInSt[4].push_back(tracklet_best[0]); + } + else if(tracklet_best[1].isValid() > 0) + { +#ifdef _DEBUG_ON + LogInfo("Choose tracklet with station-1"); +#endif + trackletsInSt[4].push_back(tracklet_best[1]); + } + } + + trackletsInSt[4].sort(); + +#ifdef _DEBUG_PATRICK + LogInfo("end of buildGlobalTracksDisplaced"); +#endif + + return; +} + +void KalmanFastTracking_NEW_2::resolveLeftRight(Tracklet& tracklet, double threshold) +{ +#ifdef _DEBUG_ON + LogInfo("Left right for this track.."); + tracklet.print(); +#endif + + //Check if the track has been updated + bool isUpdated = false; + + //Four possibilities + int possibility[4][2] = {{1, 1}, {1, -1}, {-1, 1}, {-1, -1}}; + + //Total number of hit pairs in this tracklet + int nPairs = tracklet.hits.size()/2; + + int nResolved = 0; + std::list::iterator hit1 = tracklet.hits.begin(); + std::list::iterator hit2 = tracklet.hits.begin(); + ++hit2; + while(true) + { +#ifdef _DEBUG_ON + LogInfo(hit1->hit.index << " " << hit2->sign << " === " << hit2->hit.index << " " << hit2->sign); + int detectorID1 = hit1->hit.detectorID; + int detectorID2 = hit2->hit.detectorID; + LogInfo("Hit1: " << tracklet.getExpPositionX(z_plane[detectorID1])*costheta_plane[detectorID1] + tracklet.getExpPositionY(z_plane[detectorID1])*sintheta_plane[detectorID1] << " " << hit1->hit.pos + hit1->hit.driftDistance << " " << hit1->hit.pos - hit1->hit.driftDistance); + LogInfo("Hit2: " << tracklet.getExpPositionX(z_plane[detectorID2])*costheta_plane[detectorID2] + tracklet.getExpPositionY(z_plane[detectorID2])*sintheta_plane[detectorID2] << " " << hit2->hit.pos + hit2->hit.driftDistance << " " << hit2->hit.pos - hit2->hit.driftDistance); +#endif + + if(hit1->hit.index > 0 && hit2->hit.index > 0 && hit1->sign*hit2->sign == 0) + { + int index_min = -1; + double pull_min = 1E6; + for(int i = 0; i < 4; i++) + { + double slope_local = (hit1->pos(possibility[i][0]) - hit2->pos(possibility[i][1]))/(z_plane[hit1->hit.detectorID] - z_plane[hit2->hit.detectorID]); + double inter_local = hit1->pos(possibility[i][0]) - slope_local*z_plane[hit1->hit.detectorID]; + + if(fabs(slope_local) > slope_max[hit1->hit.detectorID] || fabs(inter_local) > intersection_max[hit1->hit.detectorID]) continue; + + double tx, ty, x0, y0; + double err_tx, err_ty, err_x0, err_y0; + if(tracklet.stationID == 7 && hit1->hit.detectorID <= 6) + { + tracklet.getXZInfoInSt1(tx, x0); + tracklet.getXZErrorInSt1(err_tx, err_x0); + } + else + { + tx = tracklet.tx; + x0 = tracklet.x0; + err_tx = tracklet.err_tx; + err_x0 = tracklet.err_x0; + } + ty = tracklet.ty; + y0 = tracklet.y0; + err_ty = tracklet.err_ty; + err_y0 = tracklet.err_y0; + + double slope_exp = costheta_plane[hit1->hit.detectorID]*tx + sintheta_plane[hit1->hit.detectorID]*ty; + double err_slope = fabs(costheta_plane[hit1->hit.detectorID]*err_tx) + fabs(sintheta_plane[hit2->hit.detectorID]*err_ty); + double inter_exp = costheta_plane[hit1->hit.detectorID]*x0 + sintheta_plane[hit1->hit.detectorID]*y0; + double err_inter = fabs(costheta_plane[hit1->hit.detectorID]*err_x0) + fabs(sintheta_plane[hit2->hit.detectorID]*err_y0); + + double pull = sqrt((slope_exp - slope_local)*(slope_exp - slope_local)/err_slope/err_slope + (inter_exp - inter_local)*(inter_exp - inter_local)/err_inter/err_inter); + if(pull < pull_min) + { + index_min = i; + pull_min = pull; + } + +#ifdef _DEBUG_ON + LogInfo(hit1->hit.detectorID << ": " << i << " " << possibility[i][0] << " " << possibility[i][1]); + LogInfo(tx << " " << x0 << " " << ty << " " << y0); + LogInfo("Slope: " << slope_local << " " << slope_exp << " " << err_slope); + LogInfo("Intersection: " << inter_local << " " << inter_exp << " " << err_inter); + LogInfo("Current: " << pull << " " << index_min << " " << pull_min); +#endif + } + + //LogInfo("Final: " << index_min << " " << pull_min); + if(index_min >= 0 && pull_min < threshold)//((tracklet.stationID == 5 && pull_min < 25.) || (tracklet.stationID == 6 && pull_min < 100.))) + { + hit1->sign = possibility[index_min][0]; + hit2->sign = possibility[index_min][1]; + isUpdated = true; + } + } + + ++nResolved; + if(nResolved >= nPairs) break; + + ++hit1; + ++hit1; + ++hit2; + ++hit2; + } + + if(isUpdated) fitTracklet(tracklet); +} + +void KalmanFastTracking_NEW_2::resolveSingleLeftRight(Tracklet& tracklet) +{ +#ifdef _DEBUG_ON + LogInfo("Single left right for this track.."); + tracklet.print(); +#endif + + //Check if the track has been updated + bool isUpdated = false; + for(std::list::iterator hit_sign = tracklet.hits.begin(); hit_sign != tracklet.hits.end(); ++hit_sign) + { + if(hit_sign->hit.index < 0 || hit_sign->sign != 0) continue; + + int detectorID = hit_sign->hit.detectorID; + double pos_exp = tracklet.getExpPositionX(z_plane[detectorID])*costheta_plane[detectorID] + tracklet.getExpPositionY(z_plane[detectorID])*sintheta_plane[detectorID]; + hit_sign->sign = pos_exp > hit_sign->hit.pos ? 1 : -1; + + isUpdated = true; + } + + if(isUpdated) fitTracklet(tracklet); +} + +void KalmanFastTracking_NEW_2::removeBadHits(Tracklet& tracklet) +{ +#ifdef _DEBUG_ON + LogInfo("Removing hits for this track.."); + tracklet.calcChisq(); + tracklet.print(); +#endif + + //Check if the track has beed updated + int signflipflag[nChamberPlanes]; + for(int i = 0; i < nChamberPlanes; ++i) signflipflag[i] = 0; + + bool isUpdated = true; + while(isUpdated) + { + isUpdated = false; + tracklet.calcChisq(); + + SignedHit* hit_remove = nullptr; + SignedHit* hit_neighbour = nullptr; + double res_remove1 = -1.; + double res_remove2 = -1.; + for(std::list::iterator hit_sign = tracklet.hits.begin(); hit_sign != tracklet.hits.end(); ++hit_sign) + { + if(hit_sign->hit.index < 0) continue; + + int detectorID = hit_sign->hit.detectorID; + double res_curr = fabs(tracklet.residual[detectorID-1]); + if(res_remove1 < res_curr) + { + res_remove1 = res_curr; + res_remove2 = fabs(tracklet.residual[detectorID-1] - 2.*hit_sign->sign*hit_sign->hit.driftDistance); + hit_remove = &(*hit_sign); + + std::list::iterator iter = hit_sign; + hit_neighbour = detectorID % 2 == 0 ? &(*(--iter)) : &(*(++iter)); + } + } + if(hit_remove == nullptr) continue; + if(hit_remove->sign == 0 && tracklet.isValid() > 0) continue; //if sign is undecided, and chisq is OKay, then pass + + double cut = hit_remove->sign == 0 ? hit_remove->hit.driftDistance + resol_plane[hit_remove->hit.detectorID] : resol_plane[hit_remove->hit.detectorID]; + if(res_remove1 > cut) + { +#ifdef _DEBUG_ON + LogInfo("Dropping this hit: " << res_remove1 << " " << res_remove2 << " " << signflipflag[hit_remove->hit.detectorID-1] << " " << cut); + hit_remove->hit.print(); + hit_neighbour->hit.print(); +#endif + + //can only be changed less than twice + if(res_remove2 < cut && signflipflag[hit_remove->hit.detectorID-1] < 2) + { + hit_remove->sign = -hit_remove->sign; + hit_neighbour->sign = 0; + ++signflipflag[hit_remove->hit.detectorID-1]; +#ifdef _DEBUG_ON + LogInfo("Only changing the sign."); +#endif + } + else + { + //Set the index of the hit to be removed to -1 so it's not used anymore + //also set the sign assignment of the neighbour hit to 0 (i.e. undecided) + hit_remove->hit.index = -1; + hit_neighbour->sign = 0; + int planeType = p_geomSvc->getPlaneType(hit_remove->hit.detectorID); + if(planeType == 1) + { + --tracklet.nXHits; + } + else if(planeType == 2) + { + --tracklet.nUHits; + } + else + { + --tracklet.nVHits; + } + + //If both hit pairs are not included, the track can be rejected + if(hit_neighbour->hit.index < 0) + { +#ifdef _DEBUG_ON + LogInfo("Both hits in a view are missing! Will exit the bad hit removal..."); +#endif + return; + } + } + isUpdated = true; + } + + if(isUpdated) + { + fitTracklet(tracklet); + resolveSingleLeftRight(tracklet); + } + } +} + +void KalmanFastTracking_NEW_2::resolveLeftRight(SRawEvent::hit_pair hpair, int& LR1, int& LR2) +{ + LR1 = 0; + LR2 = 0; + + //If either hit is missing, no left-right can be assigned + if(hpair.first < 0 || hpair.second < 0) + { + return; + } + + int possibility[4][2] = {{1, 1}, {1, -1}, {-1, 1}, {-1, -1}}; + int nResolved = 0; + for(int i = 0; i < 4; i++) + { + if(nResolved > 1) break; + + int hitID1 = hpair.first; + int hitID2 = hpair.second; + double slope_local = (hitAll[hitID1].pos + possibility[i][0]*hitAll[hitID1].driftDistance - hitAll[hitID2].pos - possibility[i][1]*hitAll[hitID2].driftDistance)/(z_plane[hitAll[hitID1].detectorID] - z_plane[hitAll[hitID2].detectorID]); + double intersection_local = hitAll[hitID1].pos + possibility[i][0]*hitAll[hitID1].driftDistance - slope_local*z_plane[hitAll[hitID1].detectorID]; + + //LogInfo(i << " " << nResolved << " " << slope_local << " " << intersection_local); + if(fabs(slope_local) < slope_max[hitAll[hitID1].detectorID] && fabs(intersection_local) < intersection_max[hitAll[hitID1].detectorID]) + { + nResolved++; + LR1 = possibility[i][0]; + LR2 = possibility[i][1]; + } + } + + if(nResolved > 1) + { + LR1 = 0; + LR2 = 0; + } + + //LogInfo("Final: " << LR1 << " " << LR2); +} + +void KalmanFastTracking_NEW_2::buildTrackletsInStation(int stationID, int listID, double* pos_exp, double* window) +{ +#ifdef _DEBUG_ON + LogInfo("Building tracklets in station " << stationID); +#endif + + //actuall ID of the tracklet lists + int sID = stationID - 1; + + //Extract the X, U, V hit pairs + std::list pairs_X, pairs_U, pairs_V; + if(pos_exp == nullptr) + { + pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0]); + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1]); + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2]); + } + else + { + //Note that in pos_exp[], index 0 stands for X, index 1 stands for U, index 2 stands for V + pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0], pos_exp[0], window[0]); + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1], pos_exp[1], window[1]); + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2], pos_exp[2], window[2]); + } + +#ifdef _DEBUG_ON + LogInfo("Hit pairs in this event: "); + for(std::list::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_U.begin(); iter != pairs_U.end(); ++iter) LogInfo("U :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_V.begin(); iter != pairs_V.end(); ++iter) LogInfo("V :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif + + if(pairs_X.empty() || pairs_U.empty() || pairs_V.empty()) + { +#ifdef _DEBUG_ON + LogInfo("Not all view has hits in station " << stationID); +#endif + return; + } + + //X-U combination first, then add V pairs + for(std::list::iterator xiter = pairs_X.begin(); xiter != pairs_X.end(); ++xiter) + { + //U projections from X plane + double x_pos = xiter->second >= 0 ? 0.5*(hitAll[xiter->first].pos + hitAll[xiter->second].pos) : hitAll[xiter->first].pos; + double u_min = x_pos*u_costheta[sID] - u_win[sID]; + double u_max = u_min + 2.*u_win[sID]; + +#ifdef _DEBUG_ON + LogInfo("Trying X hits " << xiter->first << " " << xiter->second << " " << hitAll[xiter->first].elementID << " at " << x_pos); + LogInfo("U plane window:" << u_min << " " << u_max); +#endif + for(std::list::iterator uiter = pairs_U.begin(); uiter != pairs_U.end(); ++uiter) + { + double u_pos = uiter->second >= 0 ? 0.5*(hitAll[uiter->first].pos + hitAll[uiter->second].pos) : hitAll[uiter->first].pos; +#ifdef _DEBUG_ON + LogInfo("Trying U hits " << uiter->first << " " << uiter->second << " " << hitAll[uiter->first].elementID << " at " << u_pos); +#endif + if(u_pos < u_min || u_pos > u_max) continue; + + //V projections from X and U plane + double z_x = xiter->second >= 0 ? z_plane_x[sID] : z_plane[hitAll[xiter->first].detectorID]; + double z_u = uiter->second >= 0 ? z_plane_u[sID] : z_plane[hitAll[uiter->first].detectorID]; + double z_v = z_plane_v[sID]; + double v_win1 = spacing_plane[hitAll[uiter->first].detectorID]*2.*u_costheta[sID]; + double v_win2 = fabs((z_u + z_v - 2.*z_x)*u_costheta[sID]*TX_MAX); + double v_win3 = fabs((z_v - z_u)*u_sintheta[sID]*TY_MAX); + double v_win = v_win1 + v_win2 + v_win3 + 2.*spacing_plane[hitAll[uiter->first].detectorID]; + double v_min = 2*x_pos*u_costheta[sID] - u_pos - v_win; + double v_max = v_min + 2.*v_win; + +#ifdef _DEBUG_ON + LogInfo("V plane window:" << v_min << " " << v_max); +#endif + for(std::list::iterator viter = pairs_V.begin(); viter != pairs_V.end(); ++viter) + { + double v_pos = viter->second >= 0 ? 0.5*(hitAll[viter->first].pos + hitAll[viter->second].pos) : hitAll[viter->first].pos; +#ifdef _DEBUG_ON + LogInfo("Trying V hits " << viter->first << " " << viter->second << " " << hitAll[viter->first].elementID << " at " << v_pos); +#endif + if(v_pos < v_min || v_pos > v_max) continue; + + //Now add the tracklet + int LR1 = 0; + int LR2 = 0; + Tracklet tracklet_new; + tracklet_new.stationID = stationID; + + //resolveLeftRight(*xiter, LR1, LR2); + if(xiter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->first], LR1)); + tracklet_new.nXHits++; + } + if(xiter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->second], LR2)); + tracklet_new.nXHits++; + } + if(!OLD_TRACKING){ + tracklet_new.getSlopesX(hitAll[xiter->first], hitAll[xiter->second]); //Here, we find the four possible X-Z lines + } + //resolveLeftRight(*uiter, LR1, LR2); + if(uiter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[uiter->first], LR1)); + tracklet_new.nUHits++; + } + if(uiter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[uiter->second], LR2)); + tracklet_new.nUHits++; + } + if(!OLD_TRACKING){ + tracklet_new.getSlopesU(hitAll[uiter->first], hitAll[uiter->second]); //find the four possible U-Z lines + } + + //resolveLeftRight(*viter, LR1, LR2); + if(viter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[viter->first], LR1)); + tracklet_new.nVHits++; + } + if(viter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[viter->second], LR2)); + tracklet_new.nVHits++; + } + if(!OLD_TRACKING){ + tracklet_new.getSlopesV(hitAll[viter->first], hitAll[viter->second]); //find the four possible V-Z lines + } + + tracklet_new.sortHits(); + if(tracklet_new.isValid() == 0) //TODO: What IS THIS? + { + fitTracklet(tracklet_new); //This is where the original DCA minimization is performed + } + else + { + continue; + } + +#ifdef _DEBUG_ON + tracklet_new.print(); +#endif + if(acceptTracklet(tracklet_new)) + { + trackletsInSt[listID].push_back(tracklet_new); + } +#ifdef _DEBUG_ON + else + { + LogInfo("Rejected!!!"); + } +#endif + } + } + } + + //Reduce the tracklet list and add dummy hits + //reduceTrackletList(trackletsInSt[listID]); + for(std::list::iterator iter = trackletsInSt[listID].begin(); iter != trackletsInSt[listID].end(); ++iter) + { + iter->addDummyHits(); + } + + //Only retain the best 200 tracklets if exceeded + //std::cout<<"NUMBER of tracklets before resize = "< 1000) + { + trackletsInSt[listID].sort(); + trackletsInSt[listID].resize(1000); + } +} + + + + +bool KalmanFastTracking_NEW_2::buildTrackletsInStation1_NEW(int stationID, int listID, double expXZSlope, double expYSlope, double y0, bool tight, double* pos_exp, double* window) +{ +#ifdef _DEBUG_ON + LogInfo("Building tracklets in station " << stationID); +#endif + +#ifdef _DEBUG_RES + LogInfo("In buildTrackletsInStation1_NEW"); +#endif + + + double slopeComparisonSt1 = (tight ? 0.05 : m_slopeComparisonSt1); + + double testTU = p_geomSvc->getCostheta(1)*expXZSlope + p_geomSvc->getSintheta(1)*expYSlope; + double testTV = p_geomSvc->getCostheta(5)*expXZSlope + p_geomSvc->getSintheta(5)*expYSlope; + + double expX0 = -1*expXZSlope*z_plane[3] + pos_exp[0]; + + bool st1TrackletFound = false; + + //actuall ID of the tracklet lists + int sID = stationID - 1; + + //We have the hit combinations in station 1 X, U, and V wires separately at this point + + for(std::list::iterator trackletX = trackletsInStSlimX[0][0].begin(); trackletX != trackletsInStSlimX[0][0].end(); ++trackletX){ + + if(trackletX->hits.size() < 2 && tight) continue; + +#ifdef _DEBUG_RES + std::cout<<"expected x slope = "<print(); +#endif + + if(trackletX->hits.size() == 2){ //if there are 2 hits, we should be able to determine the hit signs and roughly check if the hit combination gives the right expected slopes + double bestSlopeDiffX = 1.0; + double slopeDiffX = 1.0; + int bestTrackletX = 5; + double trackletXslope = 1.0; + int nValidXSlopes = 0; + for(int t3 = 0; t3 < trackletX->possibleXLines.size(); t3++){ + slopeDiffX = trackletX->possibleXLines.at(t3).slopeX - expXZSlope; +#ifdef _DEBUG_RES + std::cout<<"x slope diff = "<possibleXLines.at(t3).slopeX; + } + } + + if(bestTrackletX > 4){ + continue; + } else{ + for(std::list::iterator hit1 = trackletX->hits.begin(); hit1 != trackletX->hits.end(); ++ hit1) + { + if(hit1->hit.detectorID == 4){ + if(bestTrackletX == 0){ + hit1->sign = 1; + } + if(bestTrackletX == 1){ + hit1->sign = -1; + } + if(bestTrackletX == 2){ + hit1->sign = 1; + } + if(bestTrackletX == 3){ + hit1->sign = -1; + } + } + if(hit1->hit.detectorID == 3){ + if(bestTrackletX == 0){ + hit1->sign = 1; + } + if(bestTrackletX == 1){ + hit1->sign = 1; + } + if(bestTrackletX == 2){ + hit1->sign = -1; + } + if(bestTrackletX == 3){ + hit1->sign = -1; + } + } + } + } + } + + for(std::list::iterator trackletU = trackletsInStSlimU[0][0].begin(); trackletU != trackletsInStSlimU[0][0].end(); ++trackletU){ + + if(trackletU->hits.size() < 2 && tight) continue; + +#ifdef _DEBUG_RES + std::cout<<"expected u slope = "<print(); +#endif + + + if(trackletU->hits.size() == 2){ + double bestSlopeDiffU = 1.0; + double slopeDiffU = 1.0; + int bestTrackletU = 5; + double trackletUslope = 1.0; + int nValidUSlopes = 0; + for(int t3 = 0; t3 < trackletU->possibleULines.size(); t3++){ + slopeDiffU = trackletU->possibleULines.at(t3).slopeU - testTU; +#ifdef _DEBUG_RES + std::cout<<"u slope diff = "<possibleULines.at(t3).slopeU; + } + } + + if(bestTrackletU > 4){ + continue; + } else{ + for(std::list::iterator hit1 = trackletU->hits.begin(); hit1 != trackletU->hits.end(); ++hit1) + { + if(hit1->hit.detectorID == 1){ + if(bestTrackletU == 0){ + hit1->sign = 1; + } + if(bestTrackletU == 1){ + hit1->sign = -1; + } + if(bestTrackletU == 2){ + hit1->sign = 1; + } + if(bestTrackletU == 3){ + hit1->sign = -1; + } + } + if(hit1->hit.detectorID == 2){ + if(bestTrackletU == 0){ + hit1->sign = 1; + } + if(bestTrackletU == 1){ + hit1->sign = 1; + } + if(bestTrackletU == 2){ + hit1->sign = -1; + } + if(bestTrackletU == 3){ + hit1->sign = -1; + } + } + } + } + } + + + for(std::list::iterator trackletV = trackletsInStSlimV[0][0].begin(); trackletV != trackletsInStSlimV[0][0].end(); ++trackletV){ + + if(trackletV->hits.size() < 2 && tight) continue; + +#ifdef _DEBUG_RES + std::cout<<"expected v slope = "<print(); +#endif + + + if(trackletV->hits.size() == 2){ + double bestSlopeDiffV = 1.0; + double slopeDiffV = 1.0; + int bestTrackletV = 5; + double trackletVslope = 1.0; + int nValidVSlopes = 0; + for(int t3 = 0; t3 < trackletV->possibleVLines.size(); t3++){ + slopeDiffV = trackletV->possibleVLines.at(t3).slopeV - testTV; +#ifdef _DEBUG_RES + std::cout<<"v slope diff = "<possibleVLines.at(t3).slopeV; + } + } + + if(bestTrackletV > 4){ + continue; + } else{ + for(std::list::iterator hit1 = trackletV->hits.begin(); hit1 != trackletV->hits.end(); ++ hit1) + { + if(hit1->hit.detectorID == 5){ + if(bestTrackletV == 0){ + hit1->sign = 1; + } + if(bestTrackletV == 1){ + hit1->sign = -1; + } + if(bestTrackletV == 2){ + hit1->sign = 1; + } + if(bestTrackletV == 3){ + hit1->sign = -1; + } + } + if(hit1->hit.detectorID == 6){ + if(bestTrackletV == 0){ + hit1->sign = 1; + } + if(bestTrackletV == 1){ + hit1->sign = 1; + } + if(bestTrackletV == 2){ + hit1->sign = -1; + } + if(bestTrackletV == 3){ + hit1->sign = -1; + } + } + } + } + } + + if( trackletV->hits.size() < 2 && trackletU->hits.size() < 2 && trackletX->hits.size() < 2 ) return false; //We require at least 4 out of 6 possible hits + + Tracklet tracklet_new_Station1; + + tracklet_new_Station1 = (*trackletX) + (*trackletU) + (*trackletV); + tracklet_new_Station1.stationID = stationID; + + tracklet_new_Station1.y0 = y0; + tracklet_new_Station1.ty = expYSlope; + + tracklet_new_Station1.x0 = expX0; + tracklet_new_Station1.tx = expXZSlope; + + + tracklet_new_Station1.sortHits(); +#ifdef _DEBUG_RES + std::cout<<"station 1 chisq using no drift distance = "< 300 || isnan(tracklet_new_Station1.calcChisq_noDrift()) ) continue; + fitTracklet(tracklet_new_Station1); + + //hit sign assignment for station 1 + for(std::list::iterator hit1 = tracklet_new_Station1.hits.begin(); hit1 != tracklet_new_Station1.hits.end(); ++hit1){ + if(hit1->sign == 0){ + hit1->sign = 1; + double dcaPlus = tracklet_new_Station1.calcChisq(); + hit1->sign = -1; + double dcaMinus = tracklet_new_Station1.calcChisq(); + if(std::abs(dcaPlus) < std::abs(dcaMinus)){ + hit1->sign = 1; + } else{ + hit1->sign = -1; + } + } + } + + fitTracklet(tracklet_new_Station1); + +#ifdef _DEBUG_RES + LogInfo("FINAL station 1 fitting"); + tracklet_new_Station1.print(); +#endif + + if(tracklet_new_Station1.chisq < 20.){ + trackletsInSt[listID].push_back(tracklet_new_Station1); + } + + } + } + } + + //Reduce the tracklet list and add dummy hits + //reduceTrackletList(trackletsInSt[listID]); + for(std::list::iterator iter = trackletsInSt[listID].begin(); iter != trackletsInSt[listID].end(); ++iter) + { + iter->addDummyHits(); + } + + if(trackletsInSt[listID].size() > 0) return true; +} + + +//This function finds valid X hits combinations +void KalmanFastTracking_NEW_2::buildTrackletsInStationSlim(int stationID, int listID, double* pos_exp, double* window) +{ +#ifdef _DEBUG_ON + LogInfo("Building tracklets in station (slim version) " << stationID); +#endif + + //actuall ID of the tracklet lists + int sID = stationID - 1; + + //Extract the X, U, V hit pairs + std::list pairs_X, pairs_U, pairs_V; + if(pos_exp == nullptr) + { + pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0]); + } + else + { + //Note that in pos_exp[], index 0 stands for X, index 1 stands for U, index 2 stands for V + pairs_X = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][0], pos_exp[0], window[0]); + } + +#ifdef _DEBUG_ON + LogInfo("Hit pairs in this event: "); + for(std::list::iterator iter = pairs_X.begin(); iter != pairs_X.end(); ++iter) LogInfo("X :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif + + if(pairs_X.empty()) + { +#ifdef _DEBUG_ON + LogInfo("Not all view has hits in station " << stationID); +#endif + return; + } + + //X-U combination first, then add V pairs + for(std::list::iterator xiter = pairs_X.begin(); xiter != pairs_X.end(); ++xiter) + { + + int LR1 = 0; + int LR2 = 0; + Tracklet tracklet_new; + tracklet_new.stationID = stationID; + + if(xiter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->first], LR1)); + tracklet_new.nXHits++; + } + if(xiter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->second], LR2)); + tracklet_new.nXHits++; + } + + if(xiter->first >= 0){ + if(stationID == 3){ + tracklet_new.st2X = hitAll[xiter->first].pos; + tracklet_new.st2Z = z_plane[hitAll[xiter->first].detectorID]; + } + if(stationID == 4 || stationID == 5){ + tracklet_new.st3X = hitAll[xiter->first].pos; + tracklet_new.st3Z = z_plane[hitAll[xiter->first].detectorID]; + } + } else if(xiter->second >= 0){ + if(stationID == 3){ + tracklet_new.st2X = hitAll[xiter->second].pos; + tracklet_new.st2Z = z_plane[hitAll[xiter->second].detectorID]; + } + if(stationID == 4 || stationID == 5){ + tracklet_new.st3X = hitAll[xiter->second].pos; + tracklet_new.st3Z = z_plane[hitAll[xiter->second].detectorID]; + } + } + + if(!OLD_TRACKING){ + tracklet_new.getSlopesX(hitAll[xiter->first], hitAll[xiter->second]); //Here, we find the four possible X-Z lines + } + + tracklet_new.sortHits(); +#ifdef _DEBUG_ON + tracklet_new.print(); +#endif + + trackletsInStSlimX[listID][0].push_back(tracklet_new); + } + +} + + +void KalmanFastTracking_NEW_2::buildTrackletsInStationSlimU(int stationID, int listID, double* pos_exp, double* window) +{ +#ifdef _DEBUG_ON + LogInfo("Building U tracklets in station (slim version) " << stationID); +#endif + + //actuall ID of the tracklet lists + int sID = stationID - 1; + + //Extract the X, U, V hit pairs + std::list pairs_X, pairs_U, pairs_V; + if(pos_exp == nullptr) + { + if(stationID == 4 || stationID == 5){ + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2]); + } + else{ + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1]); + } + } + else + { + if(stationID == 4 || stationID == 5){ + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2], pos_exp[2], window[2]); + } + else{ + //Note that in pos_exp[], index 0 stands for X, index 1 stands for U, index 2 stands for V + pairs_U = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1], pos_exp[1], window[1]); + } + } + +#ifdef _DEBUG_ON + LogInfo("Hit pairs in this event: "); + for(std::list::iterator iter = pairs_U.begin(); iter != pairs_U.end(); ++iter) LogInfo("U :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif + + if(pairs_U.empty()) + { +#ifdef _DEBUG_ON + LogInfo("Not all view has hits in station " << stationID); +#endif + return; + } + + //X-U combination first, then add V pairs + for(std::list::iterator xiter = pairs_U.begin(); xiter != pairs_U.end(); ++xiter) + { + + int LR1 = 0; + int LR2 = 0; + Tracklet tracklet_new; + tracklet_new.stationID = stationID; + + if(xiter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->first], LR1)); + tracklet_new.nUHits++; + } + if(xiter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->second], LR2)); + tracklet_new.nUHits++; + } + + if(xiter->first >= 0){ + if(stationID == 3){ + tracklet_new.st2U = hitAll[xiter->first].pos; + tracklet_new.st2Z = z_plane[hitAll[xiter->first].detectorID]; + } + if(stationID == 4 || stationID == 5){ + tracklet_new.st3U = hitAll[xiter->first].pos; + tracklet_new.st3Z = z_plane[hitAll[xiter->first].detectorID]; + } + } else if(xiter->second >= 0){ + if(stationID == 3){ + tracklet_new.st2U = hitAll[xiter->second].pos; + tracklet_new.st2Z = z_plane[hitAll[xiter->second].detectorID]; + } + if(stationID == 4 || stationID == 5){ + tracklet_new.st3U = hitAll[xiter->second].pos; + tracklet_new.st3Z = z_plane[hitAll[xiter->second].detectorID]; + } + } + + if(!OLD_TRACKING){ + tracklet_new.getSlopesU(hitAll[xiter->first], hitAll[xiter->second]); //Here, we find the four possible X-Z lines + } + + tracklet_new.sortHits(); +#ifdef _DEBUG_ON + tracklet_new.print(); +#endif + + trackletsInStSlimU[listID][0].push_back(tracklet_new); + } + +} + + + +void KalmanFastTracking_NEW_2::buildTrackletsInStationSlimV(int stationID, int listID, double* pos_exp, double* window) +{ +#ifdef _DEBUG_ON + LogInfo("Building V tracklets in station (slim version) " << stationID); +#endif + + //actuall ID of the tracklet lists + int sID = stationID - 1; + + //Extract the X, V, V hit pairs + std::list pairs_X, pairs_U, pairs_V; + if(pos_exp == nullptr) + { + if(stationID == 4 || stationID == 5){ + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1]); + } + else{ + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2]); + } + } + else + { + if(stationID == 4 || stationID == 5){ + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][1], pos_exp[1], window[1]); + } + else{ + //Note that in pos_exp[], index 0 stands for X, index 1 stands for U, index 2 stands for V + pairs_V = rawEvent->getPartialHitPairsInSuperDetector(superIDs[sID][2], pos_exp[2], window[2]); + } + } + +#ifdef _DEBUG_ON + LogInfo("Hit pairs in this event: "); + for(std::list::iterator iter = pairs_V.begin(); iter != pairs_V.end(); ++iter) LogInfo("V :" << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif + + if(pairs_V.empty()) + { +#ifdef _DEBUG_ON + LogInfo("Not all view has hits in station " << stationID); +#endif + return; + } + + //X-V combination first, then add V pairs + for(std::list::iterator xiter = pairs_V.begin(); xiter != pairs_V.end(); ++xiter) + { + + int LR1 = 0; + int LR2 = 0; + Tracklet tracklet_new; + tracklet_new.stationID = stationID; + + if(xiter->first >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->first], LR1)); + tracklet_new.nVHits++; + } + if(xiter->second >= 0) + { + tracklet_new.hits.push_back(SignedHit(hitAll[xiter->second], LR2)); + tracklet_new.nVHits++; + } + + if(xiter->first >= 0){ + if(stationID == 3){ + tracklet_new.st2V = hitAll[xiter->first].pos; + tracklet_new.st2Z = z_plane[hitAll[xiter->first].detectorID]; + } + if(stationID == 4 || stationID == 5){ + tracklet_new.st3V = hitAll[xiter->first].pos; + tracklet_new.st3Z = z_plane[hitAll[xiter->first].detectorID]; + } + } else if(xiter->second >= 0){ + if(stationID == 3){ + tracklet_new.st2V = hitAll[xiter->second].pos; + tracklet_new.st2Z = z_plane[hitAll[xiter->second].detectorID]; + } + if(stationID == 4 || stationID == 5){ + tracklet_new.st3V = hitAll[xiter->second].pos; + tracklet_new.st3Z = z_plane[hitAll[xiter->second].detectorID]; + } + } + + if(!OLD_TRACKING){ + tracklet_new.getSlopesV(hitAll[xiter->first], hitAll[xiter->second]); //Here, we find the four possible X-Z lines + } + + tracklet_new.sortHits(); +#ifdef _DEBUG_ON + tracklet_new.print(); +#endif + + trackletsInStSlimV[listID][0].push_back(tracklet_new); + } + +} + + + +bool KalmanFastTracking_NEW_2::acceptTracklet(Tracklet& tracklet) +{ + //Tracklet itself is okay with enough hits (4-out-of-6) and small chi square + if(tracklet.isValid() == 0) + { +#ifdef _DEBUG_ON + LogInfo("Failed in quality check!"); +#endif + return false; + } + + if(COARSE_MODE) return true; + /* //This algorithm ignores hodomasking requirements for now. It was only losing efficiency from what I can tell + //Hodoscope masking requirement + if(!hodoMask(tracklet)) return false; + + //For back partials, require projection inside KMAG, and muon id in prop. tubes + if(tracklet.stationID > nStations-2) + { + if(!COSMIC_MODE && !p_geomSvc->isInKMAG(tracklet.getExpPositionX(Z_KMAG_BEND), tracklet.getExpPositionY(Z_KMAG_BEND))) return false; + if(!TRACK_ELECTRONS && !(muonID_comp(tracklet) || muonID_search(tracklet))) return false; //Muon check for 2-3 connected tracklets. This needs to be off for electron tracks + if(TRACK_ELECTRONS && !(muonID_comp(tracklet) || muonID_search(tracklet) || tracklet.stationID > 5)){ + return false; + } + }*/ //WPM + +#ifdef _DEBUG_ON + LogInfo("Made it through various checks"); +#endif + + //If everything is fine ... +#ifdef _DEBUG_ON + LogInfo("AcceptTracklet!!!"); +#endif + return true; +} + +bool KalmanFastTracking_NEW_2::hodoMask(Tracklet& tracklet) +{ + //LogInfo(tracklet.stationID); + if(TRACK_ELECTRONS && (tracklet.stationID == 4 || tracklet.stationID == 5)) return true; //Patrick's skip of hodoscope checks for station 3 tracks in the electron-tracking setup. I could actually probably extrapolate backwards the station 2 hodoscope, now that I get an accurate X-Z slope in station 3 + int nHodoHits = 0; + if(!OLD_TRACKING){ + //Performing a valid extrapolation in X-Z for station 2 tracklets. This should be improved. Currently carries around the old fudge factor + if(tracklet.stationID == 3){ + for(std::vector::iterator stationID = stationIDs_mask[tracklet.stationID-1].begin(); stationID != stationIDs_mask[tracklet.stationID-1].end(); ++stationID){ + bool masked = false; + for(std::list::iterator iter = hitIDs_mask[*stationID-1].begin(); iter != hitIDs_mask[*stationID-1].end(); ++iter){ + int detectorID = hitAll[*iter].detectorID; + int elementID = hitAll[*iter].elementID; + + int idx1 = detectorID - nChamberPlanes - 1; + int idx2 = elementID - 1; + + double factor = tracklet.stationID == nChamberPlanes/6-2 ? 5. : 3.; //special for station-2, based on real data tuning + double xfudge = tracklet.stationID < nStations-1 ? 0.5*(x_mask_max[idx1][idx2] - x_mask_min[idx1][idx2]) : 0.15*(x_mask_max[idx1][idx2] - x_mask_min[idx1][idx2]); + double z_hodo = z_mask[idx1]; + + for(unsigned int pl = 0; pl < tracklet.possibleXLines.size(); pl++){ + double extrapolation = tracklet.possibleXLines.at(pl).slopeX*(z_hodo - tracklet.possibleXLines.at(pl).initialZ) + tracklet.possibleXLines.at(pl).initialX; + double err_x = std::abs(factor*extrapolation + xfudge); + double x_min = x_mask_min[idx1][idx2] - err_x; + double x_max = x_mask_max[idx1][idx2] + err_x; + if(extrapolation > x_min && extrapolation < x_max){ + masked = true; + break; + } + } + } + if(!masked) return false; + } + } + } + + if(tracklet.stationID > 5){ + for(std::vector::iterator stationID = stationIDs_mask[tracklet.stationID-1].begin(); stationID != stationIDs_mask[tracklet.stationID-1].end(); ++stationID) + { + bool masked = false; + for(std::list::iterator iter = hitIDs_mask[*stationID-1].begin(); iter != hitIDs_mask[*stationID-1].end(); ++iter) + { + int detectorID = hitAll[*iter].detectorID; + int elementID = hitAll[*iter].elementID; + + int idx1 = detectorID - nChamberPlanes - 1; + int idx2 = elementID - 1; + + double factor = tracklet.stationID == nChamberPlanes/6-2 ? 5. : 3.; //special for station-2, based on real data tuning + double xfudge = tracklet.stationID < nStations-1 ? 0.5*(x_mask_max[idx1][idx2] - x_mask_min[idx1][idx2]) : 0.15*(x_mask_max[idx1][idx2] - x_mask_min[idx1][idx2]); + double z_hodo = z_mask[idx1]; + double x_hodo = tracklet.getExpPositionX(z_hodo); + double y_hodo = tracklet.getExpPositionY(z_hodo); + double err_x = factor*tracklet.getExpPosErrorX(z_hodo) + xfudge; + double err_y = factor*tracklet.getExpPosErrorY(z_hodo); + + double x_min = x_mask_min[idx1][idx2] - err_x; + double x_max = x_mask_max[idx1][idx2] + err_x; + double y_min = y_mask_min[idx1][idx2] - err_y; + double y_max = y_mask_max[idx1][idx2] + err_y; + +#ifdef _DEBUG_ON + LogInfo(*iter); + hitAll[*iter].print(); + LogInfo(nHodoHits << "/" << stationIDs_mask[tracklet.stationID-1].size() << ": " << z_hodo << " " << x_hodo << " +/- " << err_x << " " << y_hodo << " +/-" << err_y << " : " << x_min << " " << x_max << " " << y_min << " " << y_max); +#endif + if(x_hodo > x_min && x_hodo < x_max && y_hodo > y_min && y_hodo < y_max) + { + nHodoHits++; + masked = true; + + if(TRACK_ELECTRONS && tracklet.stationID > 5) return true; //Once the first hodoscope hit is found (at z=1420cm), the combined tracklet passes for electron tracks + + break; + } + } + + if(!masked) return false; + } + } + +#ifdef _DEBUG_ON + LogInfo(tracklet.stationID << " " << nHodoHits << " " << stationIDs_mask[tracklet.stationID-1].size()); +#endif + return true; +} + +bool KalmanFastTracking_NEW_2::muonID_search(Tracklet& tracklet) +{ + //Set the cut value on multiple scattering + //multiple scattering: sigma = 0.0136*sqrt(L/L0)*(1. + 0.038*ln(L/L0))/P, L = 1m, L0 = 1.76cm + double cut = 0.03; + if(tracklet.stationID == nStations) + { + double cut_the = MUID_THE_P0*tracklet.invP; + double cut_emp = MUID_EMP_P0 + MUID_EMP_P1/tracklet.invP + MUID_EMP_P2/tracklet.invP/tracklet.invP; + cut = MUID_REJECTION*(cut_the > cut_emp ? cut_the : cut_emp); + } + + double slope[2] = {tracklet.tx, tracklet.ty}; + double pos_absorb[2] = {tracklet.getExpPositionX(MUID_Z_REF), tracklet.getExpPositionY(MUID_Z_REF)}; + PropSegment* segs[2] = {&(tracklet.seg_x), &(tracklet.seg_y)}; + for(int i = 0; i < 2; ++i) + { + //this shorting circuting can only be done to X-Z, Y-Z needs more complicated thing + //if(i == 0 && segs[i]->getNHits() > 2 && segs[i]->isValid() > 0 && fabs(slope[i] - segs[i]->a) < cut) continue; + + segs[i]->init(); + for(int j = 0; j < 4; ++j) + { + int index = detectorIDs_muid[i][j] - nChamberPlanes - 1; + double pos_ref = j < 2 ? pos_absorb[i] : segs[i]->getPosRef(pos_absorb[i] + slope[i]*(z_ref_muid[i][j] - MUID_Z_REF)); + double pos_exp = slope[i]*(z_mask[index] - z_ref_muid[i][j]) + pos_ref; + + if(!p_geomSvc->isInPlane(detectorIDs_muid[i][j], tracklet.getExpPositionX(z_mask[index]), tracklet.getExpPositionY(z_mask[index]))) continue; + + double win_tight = cut*(z_mask[index] - z_ref_muid[i][j]); + win_tight = win_tight > 2.54 ? win_tight : 2.54; + double win_loose = win_tight*2; + double dist_min = 1E6; + for(std::list::iterator iter = hitIDs_muid[i][j].begin(); iter != hitIDs_muid[i][j].end(); ++iter) + { + double pos = hitAll[*iter].pos; + double dist = pos - pos_exp; + if(dist < -win_loose) continue; + if(dist > win_loose) break; + + double dist_l = fabs(pos - hitAll[*iter].driftDistance - pos_exp); + double dist_r = fabs(pos + hitAll[*iter].driftDistance - pos_exp); + dist = dist_l < dist_r ? dist_l : dist_r; + if(dist < dist_min) + { + dist_min = dist; + if(dist < win_tight) + { + segs[i]->hits[j].hit = hitAll[*iter]; + segs[i]->hits[j].sign = fabs(pos - hitAll[*iter].driftDistance - pos_exp) < fabs(pos + hitAll[*iter].driftDistance - pos_exp) ? -1 : 1; + } + } + } + } + segs[i]->fit(); + + //this shorting circuting can only be done to X-Z, Y-Z needs more complicated thing + //if(i == 0 && !(segs[i]->isValid() > 0 && fabs(slope[i] - segs[i]->a) < cut)) return false; + } + + muonID_hodoAid(tracklet); + if(segs[0]->getNHits() + segs[1]->getNHits() >= MUID_MINHITS) + { + return true; + } + else if(segs[1]->getNHits() == 1 || segs[1]->getNPlanes() == 1) + { + return segs[1]->nHodoHits >= 2; + } + return false; +} + +bool KalmanFastTracking_NEW_2::muonID_comp(Tracklet& tracklet) +{ + //Set the cut value on multiple scattering + //multiple scattering: sigma = 0.0136*sqrt(L/L0)*(1. + 0.038*ln(L/L0))/P, L = 1m, L0 = 1.76cm + double cut = 0.03; + if(tracklet.stationID == nStations) + { + double cut_the = MUID_THE_P0*tracklet.invP; + double cut_emp = MUID_EMP_P0 + MUID_EMP_P1/tracklet.invP + MUID_EMP_P2/tracklet.invP/tracklet.invP; + cut = MUID_REJECTION*(cut_the > cut_emp ? cut_the : cut_emp); + } +#ifdef _DEBUG_ON + LogInfo("Muon ID cut is: " << cut << " rad."); +#endif + + double slope[2] = {tracklet.tx, tracklet.ty}; + PropSegment* segs[2] = {&(tracklet.seg_x), &(tracklet.seg_y)}; + + for(int i = 0; i < 2; ++i) + { +#ifdef _DEBUG_ON + if(i == 0) LogInfo("Working in X-Z:"); + if(i == 1) LogInfo("Working in Y-Z:"); +#endif + + double pos_ref = i == 0 ? tracklet.getExpPositionX(MUID_Z_REF) : tracklet.getExpPositionY(MUID_Z_REF); + if(segs[i]->getNHits() > 2 && segs[i]->isValid() > 0 && fabs(slope[i] - segs[i]->a) < cut && fabs(segs[i]->getExpPosition(MUID_Z_REF) - pos_ref) < MUID_R_CUT) + { +#ifdef _DEBUG_ON + LogInfo("Muon ID are already avaiable!"); +#endif + continue; + } + + for(std::list::iterator iter = propSegs[i].begin(); iter != propSegs[i].end(); ++iter) + { +#ifdef _DEBUG_ON + LogInfo("Testing this prop segment, with ref pos = " << pos_ref << ", slope_ref = " << slope[i]); + iter->print(); +#endif + if(fabs(iter->a - slope[i]) < cut && fabs(iter->getExpPosition(MUID_Z_REF) - pos_ref) < MUID_R_CUT) + { + *(segs[i]) = *iter; +#ifdef _DEBUG_ON + LogInfo("Accepted!"); +#endif + break; + } + } + + if(segs[i]->isValid() == 0) return false; + } + + if(segs[0]->getNHits() + segs[1]->getNHits() < MUID_MINHITS) return false; + return true; +} + +bool KalmanFastTracking_NEW_2::muonID_hodoAid(Tracklet& tracklet) +{ + double win = 0.03; + double factor = 5.; + if(tracklet.stationID == nStations) + { + double win_the = MUID_THE_P0*tracklet.invP; + double win_emp = MUID_EMP_P0 + MUID_EMP_P1/tracklet.invP + MUID_EMP_P2/tracklet.invP/tracklet.invP; + win = MUID_REJECTION*(win_the > win_emp ? win_the : win_emp); + factor = 3.; + } + + PropSegment* segs[2] = {&(tracklet.seg_x), &(tracklet.seg_y)}; + for(int i = 0; i < 2; ++i) + { + segs[i]->nHodoHits = 0; + for(std::list::iterator iter = hitIDs_muidHodoAid[i].begin(); iter != hitIDs_muidHodoAid[i].end(); ++iter) + { + int detectorID = hitAll[*iter].detectorID; + int elementID = hitAll[*iter].elementID; + + int idx1 = detectorID - nChamberPlanes - 1; + int idx2 = elementID - 1; + + double z_hodo = z_mask[idx1]; + double x_hodo = tracklet.getExpPositionX(z_hodo); + double y_hodo = tracklet.getExpPositionY(z_hodo); + double err_x = factor*tracklet.getExpPosErrorX(z_hodo) + win*(z_hodo - MUID_Z_REF); + double err_y = factor*tracklet.getExpPosErrorY(z_hodo) + win*(z_hodo - MUID_Z_REF); + + err_x = err_x/(x_mask_max[idx1][idx2] - x_mask_min[idx1][idx2]) > 0.25 ? 0.25*err_x/(x_mask_max[idx1][idx2] - x_mask_min[idx1][idx2]) : err_x; + err_y = err_y/(y_mask_max[idx1][idx2] - y_mask_min[idx1][idx2]) > 0.25 ? 0.25*err_y/(y_mask_max[idx1][idx2] - y_mask_min[idx1][idx2]) : err_y; + + double x_min = x_mask_min[idx1][idx2] - err_x; + double x_max = x_mask_max[idx1][idx2] + err_x; + double y_min = y_mask_min[idx1][idx2] - err_y; + double y_max = y_mask_max[idx1][idx2] + err_y; + + if(x_hodo > x_min && x_hodo < x_max && y_hodo > y_min && y_hodo < y_max) + { + segs[i]->hodoHits[segs[i]->nHodoHits++] = hitAll[*iter]; + if(segs[i]->nHodoHits > 4) break; + } + } + } + + return true; +} + +void KalmanFastTracking_NEW_2::buildPropSegments() +{ +#ifdef _DEBUG_ON + LogInfo("Building prop. tube segments"); +#endif + + for(int i = 0; i < 2; ++i) + { + propSegs[i].clear(); + + //note for prop tubes superID index starts from 4 + std::list pairs_forward = rawEvent->getPartialHitPairsInSuperDetector(superIDs[i+5][0]); + std::list pairs_backward = rawEvent->getPartialHitPairsInSuperDetector(superIDs[i+5][1]); + +#ifdef _DEBUG_ON + //std::cout << "superID: " << superIDs[i+5][0] << ", " << superIDs[i+5][1] << std::endl; + for(std::list::iterator iter = pairs_forward.begin(); iter != pairs_forward.end(); ++iter) + LogInfo("Forward: " << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); + for(std::list::iterator iter = pairs_backward.begin(); iter != pairs_backward.end(); ++iter) + LogInfo("Backward: " << iter->first << " " << iter->second << " " << hitAll[iter->first].index << " " << (iter->second < 0 ? -1 : hitAll[iter->second].index)); +#endif + + for(std::list::iterator fiter = pairs_forward.begin(); fiter != pairs_forward.end(); ++fiter) + { +#ifdef _DEBUG_ON + LogInfo("Trying forward pair " << fiter->first << " " << fiter->second); +#endif + for(std::list::iterator biter = pairs_backward.begin(); biter != pairs_backward.end(); ++biter) + { +#ifdef _DEBUG_ON + LogInfo("Trying backward pair " << biter->first << " " << biter->second); +#endif + + PropSegment seg; + + //Note that the backward plane comes as the first in pair + if(fiter->first >= 0) seg.hits[1] = SignedHit(hitAll[fiter->first], 0); + if(fiter->second >= 0) seg.hits[0] = SignedHit(hitAll[fiter->second], 0); + if(biter->first >= 0) seg.hits[3] = SignedHit(hitAll[biter->first], 0); + if(biter->second >= 0) seg.hits[2] = SignedHit(hitAll[biter->second], 0); + +#ifdef _DEBUG_ON + seg.print(); +#endif + seg.fit(); +#ifdef _DEBUG_ON + seg.print(); +#endif + + if(seg.isValid() > 0) + { + propSegs[i].push_back(seg); + } +#ifdef _DEBUG_ON + else + { + LogInfo("Rejected!"); + } +#endif + } + } + } +} + + +int KalmanFastTracking_NEW_2::fitTracklet(Tracklet& tracklet) +{ + tracklet_curr = tracklet; + + //idx = 0, using simplex; idx = 1 using migrad + int idx = 1; +#ifdef _ENABLE_MULTI_MINI + if(tracklet.stationID < nStations-1) idx = 0; +#endif + + + minimizer[idx]->SetLimitedVariable(0, "tx", tracklet.tx, 0.001, -TX_MAX, TX_MAX); + minimizer[idx]->SetLimitedVariable(1, "ty", tracklet.ty, 0.001, -TY_MAX, TY_MAX); + minimizer[idx]->SetLimitedVariable(2, "x0", tracklet.x0, 0.1, -X0_MAX, X0_MAX); + minimizer[idx]->SetLimitedVariable(3, "y0", tracklet.y0, 0.1, -Y0_MAX, Y0_MAX); + if(KMAG_ON) + { + minimizer[idx]->SetLimitedVariable(4, "invP", tracklet.invP, 0.001*tracklet.invP, INVP_MIN, INVP_MAX); + } + minimizer[idx]->Minimize(); + + tracklet.tx = minimizer[idx]->X()[0]; + tracklet.ty = minimizer[idx]->X()[1]; + tracklet.x0 = minimizer[idx]->X()[2]; + tracklet.y0 = minimizer[idx]->X()[3]; + + tracklet.err_tx = minimizer[idx]->Errors()[0]; + tracklet.err_ty = minimizer[idx]->Errors()[1]; + tracklet.err_x0 = minimizer[idx]->Errors()[2]; + tracklet.err_y0 = minimizer[idx]->Errors()[3]; + + if(KMAG_ON && tracklet.stationID == nStations) + { + tracklet.invP = minimizer[idx]->X()[4]; + tracklet.err_invP = minimizer[idx]->Errors()[4]; + } + + tracklet.chisq = minimizer[idx]->MinValue(); + + int status = minimizer[idx]->Status(); + + return status; +} + +int KalmanFastTracking_NEW_2::reduceTrackletList(std::list& tracklets) +{ + std::list targetList; + + tracklets.sort(); + while(!tracklets.empty()) + { + targetList.push_back(tracklets.front()); + tracklets.pop_front(); + +#ifdef _DEBUG_ON_LEVEL_2 + LogInfo("Current best tracklet in reduce"); + targetList.back().print(); +#endif + + for(std::list::iterator iter = tracklets.begin(); iter != tracklets.end(); ) + { + if(iter->similarity(targetList.back())) + { +#ifdef _DEBUG_ON_LEVEL_2 + LogInfo("Removing this tracklet: "); + iter->print(); +#endif + iter = tracklets.erase(iter); + continue; + } + else + { + ++iter; + } + } + } + + tracklets.assign(targetList.begin(), targetList.end()); + return 0; +} + +void KalmanFastTracking_NEW_2::getExtrapoWindowsInSt1(Tracklet& tracklet, double* pos_exp, double* window, int st1ID) +{ + if(tracklet.stationID != nStations-1) + { + for(int i = 0; i < 3; i++) + { + pos_exp[i] = 9999.; + window[i] = 0.; + } + return; + } + + for(int i = 0; i < 3; i++) + { + int detectorID = (st1ID-1)*6 + 2*i + 2; + int idx = p_geomSvc->getPlaneType(detectorID) - 1; + + double z_st1 = z_plane[detectorID]; + double x_st1 = tracklet.getExpPositionX(z_st1); + double y_st1 = tracklet.getExpPositionY(z_st1); + double err_x = tracklet.getExpPosErrorX(z_st1); + double err_y = tracklet.getExpPosErrorY(z_st1); + + pos_exp[idx] = p_geomSvc->getUinStereoPlane(detectorID, x_st1, y_st1); + window[idx] = 5.*(fabs(costheta_plane[detectorID]*err_x) + fabs(sintheta_plane[detectorID]*err_y)); + } +} + +void KalmanFastTracking_NEW_2::getSagittaWindowsInSt1(Tracklet& tracklet, double* pos_exp, double* window, int st1ID) +{ + if(tracklet.stationID != nStations-1) + { + for(int i = 0; i < 3; i++) + { + pos_exp[i] = 9999.; + window[i] = 0.; + } + return; + } + + double z_st3 = z_plane[tracklet.hits.back().hit.detectorID]; + double x_st3 = tracklet.getExpPositionX(z_st3); + double y_st3 = tracklet.getExpPositionY(z_st3); + + //For U, X, and V planes + for(int i = 0; i < 3; i++) + { + int detectorID = (st1ID-1)*6 + 2*i + 2; + int idx = p_geomSvc->getPlaneType(detectorID) - 1; + + if(!(idx >= 0 && idx <3)) continue; + + double pos_st3 = p_geomSvc->getUinStereoPlane(s_detectorID[idx], x_st3, y_st3); + + double z_st1 = z_plane[detectorID]; + double z_st2 = z_plane[s_detectorID[idx]]; + double x_st2 = tracklet.getExpPositionX(z_st2); + double y_st2 = tracklet.getExpPositionY(z_st2); + double pos_st2 = p_geomSvc->getUinStereoPlane(s_detectorID[idx], x_st2, y_st2); + + double s2_target = pos_st2 - pos_st3*(z_st2 - Z_TARGET)/(z_st3 - Z_TARGET); + double s2_dump = pos_st2 - pos_st3*(z_st2 - Z_DUMP)/(z_st3 - Z_DUMP); + + double pos_exp_target = SAGITTA_TARGET_CENTER*s2_target + pos_st3*(z_st1 - Z_TARGET)/(z_st3 - Z_TARGET); + double pos_exp_dump = SAGITTA_DUMP_CENTER*s2_dump + pos_st3*(z_st1 - Z_DUMP)/(z_st3 - Z_DUMP); + double win_target = fabs(s2_target*SAGITTA_TARGET_WIDTH); + double win_dump = fabs(s2_dump*SAGITTA_DUMP_WIDTH); + + double p_min = std::min(pos_exp_target - win_target, pos_exp_dump - win_dump); + double p_max = std::max(pos_exp_target + win_target, pos_exp_dump + win_dump); + + //std::cout<<"Test sagitta window thing. The detectorID is "<::iterator iter = tracklet.hits.begin(); iter != tracklet.hits.end(); ++iter) + { + if(iter->hit.index < 0) continue; + + Node node_add(*iter); + kmtrk.getNodeList().push_back(node_add); + kmtrk.getHitIndexList().push_back(iter->sign*iter->hit.index); + } + + //Set initial state + TrkPar trkpar_curr; + trkpar_curr._z = p_geomSvc->getPlanePosition(kmtrk.getNodeList().back().getHit().detectorID); + //FIXME Debug Testing: sign reverse + //TODO seems to be fixed + trkpar_curr._state_kf[0][0] = tracklet.getCharge()*tracklet.invP/sqrt(1. + tracklet.tx*tracklet.tx + tracklet.ty*tracklet.ty); + trkpar_curr._state_kf[1][0] = tracklet.tx; + trkpar_curr._state_kf[2][0] = tracklet.ty; + trkpar_curr._state_kf[3][0] = tracklet.getExpPositionX(trkpar_curr._z); + trkpar_curr._state_kf[4][0] = tracklet.getExpPositionY(trkpar_curr._z); + + trkpar_curr._covar_kf.Zero(); + trkpar_curr._covar_kf[0][0] = 0.001;//1E6*tracklet.err_invP*tracklet.err_invP; + trkpar_curr._covar_kf[1][1] = 0.01;//1E6*tracklet.err_tx*tracklet.err_tx; + trkpar_curr._covar_kf[2][2] = 0.01;//1E6*tracklet.err_ty*tracklet.err_ty; + trkpar_curr._covar_kf[3][3] = 100;//1E6*tracklet.getExpPosErrorX(trkpar_curr._z)*tracklet.getExpPosErrorX(trkpar_curr._z); + trkpar_curr._covar_kf[4][4] = 100;//1E6*tracklet.getExpPosErrorY(trkpar_curr._z)*tracklet.getExpPosErrorY(trkpar_curr._z); + + kmtrk.setCurrTrkpar(trkpar_curr); + kmtrk.getNodeList().back().getPredicted() = trkpar_curr; + */ + + /* + //Fit the track first with possibily a few nodes unresolved + if(!fitTrack(kmtrk)) + { +#ifdef _DEBUG_ON + LogInfo("!fitTrack(kmtrk) - try flip charge"); +#endif + trkpar_curr._state_kf[0][0] *= -1.; + kmtrk.setCurrTrkpar(trkpar_curr); + kmtrk.getNodeList().back().getPredicted() = trkpar_curr; + if(!fitTrack(kmtrk)) + { +#ifdef _DEBUG_ON + LogInfo("!fitTrack(kmtrk) - failed flip charge also"); +#endif + SRecTrack strack = tracklet.getSRecTrack(); + strack.setKalmanStatus(-1); + return strack; + } + } + + if(!kmtrk.isValid()) + { +#ifdef _DEBUG_ON + LogInfo("!kmtrk.isValid() Chi2 = " << kmtrk.getChisq() << " - try flip charge"); +#endif + trkpar_curr._state_kf[0][0] *= -1.; + kmtrk.setCurrTrkpar(trkpar_curr); + kmtrk.getNodeList().back().getPredicted() = trkpar_curr; + if(!fitTrack(kmtrk)) + { +#ifdef _DEBUG_ON + LogInfo("!fitTrack(kmtrk) - failed flip charge also"); +#endif + SRecTrack strack = tracklet.getSRecTrack(); + strack.setKalmanStatus(-1); + return strack; + } + +#ifdef _DEBUG_ON + LogInfo("Chi2 after flip charge: " << kmtrk.getChisq()); + if(kmtrk.isValid()) + { + LogInfo("flip charge worked!"); + } +#endif + } + +#ifdef _DEBUG_ON + LogInfo("kmtrk.print()"); + kmtrk.print(); + LogInfo("kmtrk.printNodes()"); + kmtrk.printNodes(); +#endif + */ + + //Resolve left-right based on the current solution, re-fit if anything changed + //resolveLeftRight(kmtrk); + if(fitTrack(kmtrk) && kmtrk.isValid()) + { + SRecTrack strack = kmtrk.getSRecTrack(); + + //Set trigger road ID + TriggerRoad road(tracklet); + strack.setTriggerRoad(road.getRoadID()); + + //Set prop tube slopes + strack.setNHitsInPT(tracklet.seg_x.getNHits(), tracklet.seg_y.getNHits()); + strack.setPTSlope(tracklet.seg_x.a, tracklet.seg_y.a); + + strack.setKalmanStatus(1); + + return strack; + } + else + { +#ifdef _DEBUG_ON + LogInfo("!kmtrk.isValid()"); +#endif + SRecTrack strack = tracklet.getSRecTrack(); + strack.setKalmanStatus(-1); + + return strack; + } +} + +bool KalmanFastTracking_NEW_2::fitTrack(KalmanTrack& kmtrk) +{ + if(kmtrk.getNodeList().empty()) return false; + + if(kmfitter->processOneTrack(kmtrk) == 0) + { + return false; + } + kmfitter->updateTrack(kmtrk); + + return true; +} + +void KalmanFastTracking_NEW_2::resolveLeftRight(KalmanTrack& kmtrk) +{ + bool isUpdated = false; + + std::list::iterator hitID = kmtrk.getHitIndexList().begin(); + for(std::list::iterator node = kmtrk.getNodeList().begin(); node != kmtrk.getNodeList().end(); ) + { + if(*hitID == 0) + { + double x_hit = node->getSmoothed().get_x(); + double y_hit = node->getSmoothed().get_y(); + double pos_hit = p_geomSvc->getUinStereoPlane(node->getHit().detectorID, x_hit, y_hit); + + int sign = 0; + if(pos_hit > node->getHit().pos) + { + sign = 1; + } + else + { + sign = -1; + } + + //update the node list + TMatrixD m(1, 1), dm(1, 1); + m[0][0] = node->getHit().pos + sign*node->getHit().driftDistance; + dm[0][0] = p_geomSvc->getPlaneResolution(node->getHit().detectorID)*p_geomSvc->getPlaneResolution(node->getHit().detectorID); + node->setMeasurement(m, dm); + *hitID = sign*node->getHit().index; + + isUpdated = true; + } + + ++node; + ++hitID; + } + + if(isUpdated) fitTrack(kmtrk); +} + +void KalmanFastTracking_NEW_2::printTimers() { + std::cout <<"KalmanFastTracking_NEW_2::printTimers: " << std::endl; + std::cout <<"================================================================" << std::endl; + std::cout << "Tracklet St2 "<<_timers["st2"]->get_accumulated_time()/1000. << " sec" <get_accumulated_time()/1000. << " sec" <get_accumulated_time()/1000. << " sec" <get_accumulated_time()/1000. << " sec" <get_accumulated_time()/1000. << " sec" <get_accumulated_time()/1000. << " sec" <get_accumulated_time()/1000. << " sec" <get_accumulated_time()/1000. << " sec" < slopeComparison) return false; + if(bestExtrapComp > windowSize) return false; + + + tracklet2.acceptedXLine2 = line2X; + tracklet3.acceptedXLine3 = line3X; + //Give the station 2 and station 3 tracklets the same tx and ty value. I could get an X0 and Y0 extrapolation, but that doesn't seem to be strictly necessary. The X0 and Y0 values are found in the fittracklet function for the combined station 2 + station 3 tracklet + tracklet2.tx = (line2X.slopeX + line3X.slopeX)/2; + tracklet3.tx = (line2X.slopeX + line3X.slopeX)/2; + + tracklet2.st2X = line2X.initialX; + tracklet3.st2X = line3X.initialX; //yes, I know it looks like a typo, but I set the st2x for tracklet 3 here. It's used elsewhere + tracklet3.st3X = line3X.initialX; + + //extract slope measurement using the long lever-arm between station 2 and 3 + double newSlopeX = (tracklet3.possibleXLines.at(choiceOfT3).initialX - tracklet2.possibleXLines.at(choiceOfT2).initialX)/(tracklet3.possibleXLines.at(choiceOfT3).initialZ - tracklet2.possibleXLines.at(choiceOfT2).initialZ); + + tracklet2.st2Xsl = newSlopeX; + tracklet3.st2Xsl = newSlopeX; + + + for(std::list::iterator hit1 = tracklet2.hits.begin(); hit1 != tracklet2.hits.end(); ++hit1) + { + if(hit1->hit.detectorID == 15){ + if(choiceOfT2 == 0){ + hit1->sign = 1; + } + if(choiceOfT2 == 1){ + hit1->sign = -1; + } + if(choiceOfT2 == 2){ + hit1->sign = 1; + } + if(choiceOfT2 == 3){ + hit1->sign = -1; + } + } else{ + if(choiceOfT2 == 0){ + hit1->sign = 1; + } + if(choiceOfT2 == 1){ + hit1->sign = 1; + } + if(choiceOfT2 == 2){ + hit1->sign = -1; + } + if(choiceOfT2 == 3){ + hit1->sign = -1; + } + } + } + + for(std::list::iterator hit1 = tracklet3.hits.begin(); hit1 != tracklet3.hits.end(); ++hit1) + { + if(hit1->hit.detectorID == 21 || hit1->hit.detectorID == 27){ + if(choiceOfT3 == 0){ + hit1->sign = 1; + } + if(choiceOfT3 == 1){ + hit1->sign = -1; + } + if(choiceOfT3 == 2){ + hit1->sign = 1; + } + if(choiceOfT3 == 3){ + hit1->sign = -1; + } + } else{ + if(choiceOfT3 == 0){ + hit1->sign = 1; + } + if(choiceOfT3 == 1){ + hit1->sign = 1; + } + if(choiceOfT3 == 2){ + hit1->sign = -1; + } + if(choiceOfT3 == 3){ + hit1->sign = -1; + } + } + } + + + return true; + +} + + +//For the case when st2 X combo has 2 hits and st3 has 1, or vise versa +bool KalmanFastTracking_NEW_2::compareTrackletsSlim_3hits(Tracklet& tracklet2, Tracklet& tracklet3, int pass, double slopeComparison, double windowSize) +{ + + if( ! ( (tracklet2.hits.size() == 2 && tracklet3.hits.size() == 1 ) || (tracklet2.hits.size() == 1 && tracklet3.hits.size() == 2 ) ) ) return false; + + double bestMatch = 100.; + if(tracklet2.hits.size() == 2){ + + unsigned int bestT2 = 5; + for(unsigned int t2 = 0; t2 < tracklet2.possibleXLines.size(); t2++){ + double extrapolation = tracklet2.possibleXLines.at(t2).slopeX*(z_plane[tracklet3.getHit(0).hit.detectorID] - tracklet2.possibleXLines.at(t2).initialZ) + tracklet2.possibleXLines.at(t2).initialX; + if(std::abs(tracklet3.getHit(0).hit.pos - extrapolation) < bestMatch && std::abs(tracklet3.getHit(0).hit.pos - extrapolation) < windowSize){ + bestMatch = std::abs(tracklet3.getHit(0).hit.pos - extrapolation); + bestT2 = t2; + } + } + + if(bestMatch > 99. || bestT2 == 5){ + return false; + } else{ + + double newSlopeX = (tracklet3.getHit(0).hit.pos - tracklet2.possibleXLines.at(bestT2).initialX)/(z_plane[tracklet3.getHit(0).hit.detectorID] - tracklet2.possibleXLines.at(bestT2).initialZ); + + tracklet2.acceptedXLine2 = tracklet2.possibleXLines.at(bestT2); + tracklet3.acceptedXLine3 = tracklet2.possibleXLines.at(bestT2); + tracklet2.tx = newSlopeX; + tracklet3.tx = newSlopeX; + + tracklet2.st2Xsl = newSlopeX; + tracklet3.st2Xsl = newSlopeX; + + + for(std::list::iterator hit1 = tracklet2.hits.begin(); hit1 != tracklet2.hits.end(); ++hit1) + { + if(hit1->hit.detectorID == 15){ + if(bestT2 == 0){ + hit1->sign = 1; + } + if(bestT2 == 1){ + hit1->sign = -1; + } + if(bestT2 == 2){ + hit1->sign = 1; + } + if(bestT2 == 3){ + hit1->sign = -1; + } + } else{ + if(bestT2 == 0){ + hit1->sign = 1; + } + if(bestT2 == 1){ + hit1->sign = 1; + } + if(bestT2 == 2){ + hit1->sign = -1; + } + if(bestT2 == 3){ + hit1->sign = -1; + } + } + } + + + + return true; + } + } + + if(tracklet3.hits.size() == 2){ + + unsigned int bestT3 = 5; + for(unsigned int t3 = 0; t3 < tracklet3.possibleXLines.size(); t3++){ + double extrapolation = tracklet3.possibleXLines.at(t3).slopeX*(z_plane[tracklet2.getHit(0).hit.detectorID] - tracklet3.possibleXLines.at(t3).initialZ) + tracklet3.possibleXLines.at(t3).initialX; + if(std::abs(tracklet2.getHit(0).hit.pos - extrapolation) < bestMatch && std::abs(tracklet2.getHit(0).hit.pos - extrapolation) < windowSize){ + bestMatch = std::abs(tracklet2.getHit(0).hit.pos - extrapolation); + bestT3 = t3; + } + } + + if(bestMatch > 99. || bestT3 == 5){ + return false; + } else{ + + double newSlopeX = (tracklet2.getHit(0).hit.pos - tracklet3.possibleXLines.at(bestT3).initialX)/(z_plane[tracklet2.getHit(0).hit.detectorID] - tracklet3.possibleXLines.at(bestT3).initialZ); + + tracklet2.acceptedXLine2 = tracklet3.possibleXLines.at(bestT3); + tracklet3.acceptedXLine3 = tracklet3.possibleXLines.at(bestT3); + tracklet2.tx = newSlopeX; + tracklet3.tx = newSlopeX; + + tracklet2.st2Xsl = newSlopeX; + tracklet3.st2Xsl = newSlopeX; + + + for(std::list::iterator hit1 = tracklet3.hits.begin(); hit1 != tracklet3.hits.end(); ++hit1) + { + if(hit1->hit.detectorID == 21 || hit1->hit.detectorID == 27){ + if(bestT3 == 0){ + hit1->sign = 1; + } + if(bestT3 == 1){ + hit1->sign = -1; + } + if(bestT3 == 2){ + hit1->sign = 1; + } + if(bestT3 == 3){ + hit1->sign = -1; + } + } else{ + if(bestT3 == 0){ + hit1->sign = 1; + } + if(bestT3 == 1){ + hit1->sign = 1; + } + if(bestT3 == 2){ + hit1->sign = -1; + } + if(bestT3 == 3){ + hit1->sign = -1; + } + } + } + + return true; + + } + } +} + + +bool KalmanFastTracking_NEW_2::compareTrackletsSlimU(Tracklet& tracklet2, Tracklet& tracklet3, int pass, double slopeComparison, double windowSize) +{ + if( !( tracklet2.hits.size() == 2 && tracklet3.hits.size() == 2 ) ) return false; + + double slopeWindow = 0.005; + double extrapoWindow = 5.0; + + if(pass == 2){ + slopeWindow = 0.008; + extrapoWindow = 12.; + } + + //Here we will compare the possible X-Z slopes within the station 2 and station 3 tracklets + Tracklet::linedef line2U; + Tracklet::linedef line3U; + Tracklet::linedef line2U_v2; + Tracklet::linedef line3U_v2; + + int choiceOfT2 = 5; + int choiceOfT3 = 5; + int choiceOfT2_v2 = 5; + int choiceOfT3_v2 = 5; + + double st3pos = (tracklet3.getHit(0).hit.pos + tracklet3.getHit(1).hit.pos)/2; + double st3posZ = (z_plane[tracklet3.getHit(0).hit.detectorID] + z_plane[tracklet3.getHit(1).hit.detectorID])/2; + + double slopeComp = 1.0; + double bestExtrapComp = 100.; + + double slopeComp2 = 1.0; + double bestExtrapComp2 = 100.; + + double bestExtrapMatch = 100.; + + double secondSlope = 1.1; + for(unsigned int t2 = 0; t2 < tracklet2.possibleULines.size(); t2++){ + + double st2ExtrapMatch = tracklet2.possibleULines.at(t2).slopeU*(st3posZ - tracklet2.possibleULines.at(t2).initialZ) + tracklet2.possibleULines.at(t2).initialU - st3pos; + if( std::abs(st2ExtrapMatch) < windowSize && std::abs(st2ExtrapMatch) < bestExtrapMatch ){ + + for(unsigned int t3 = 0; t3 < tracklet3.possibleULines.size(); t3++){ + + if(std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU) < slopeComp && std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU) < slopeComparison){ + + slopeComp = std::abs(tracklet3.possibleULines.at(t3).slopeU - tracklet2.possibleULines.at(t2).slopeU); + bestExtrapComp = st2ExtrapMatch; + bestExtrapMatch = std::abs(st2ExtrapMatch); + line2U = tracklet2.possibleULines.at(t2); + line3U = tracklet3.possibleULines.at(t3); + choiceOfT2 = t2; + choiceOfT3 = t3; + + } + } + } + } + + + +#ifdef _DEBUG_RES + LogInfo("slopeComp = "< slopeComparison) return false; + if(bestExtrapComp > windowSize) return false; + + + tracklet2.acceptedULine2 = line2U; + tracklet3.acceptedULine3 = line3U; + + tracklet2.st2U = line2U.initialU; + tracklet3.st2U = line3U.initialU; + tracklet3.st3U = line3U.initialU; + + double newSlopeU = (tracklet3.possibleULines.at(choiceOfT3).initialU - tracklet2.possibleULines.at(choiceOfT2).initialU)/(tracklet3.possibleULines.at(choiceOfT3).initialZ - tracklet2.possibleULines.at(choiceOfT2).initialZ); + tracklet2.st2Usl = newSlopeU; + tracklet3.st2Usl = newSlopeU; + + + for(std::list::iterator hit1 = tracklet2.hits.begin(); hit1 != tracklet2.hits.end(); ++hit1) + { + if(hit1->hit.detectorID == 17){ + if(choiceOfT2 == 0){ + hit1->sign = 1; + } + if(choiceOfT2 == 1){ + hit1->sign = -1; + } + if(choiceOfT2 == 2){ + hit1->sign = 1; + } + if(choiceOfT2 == 3){ + hit1->sign = -1; + } + } else{ + if(choiceOfT2 == 0){ + hit1->sign = 1; + } + if(choiceOfT2 == 1){ + hit1->sign = 1; + } + if(choiceOfT2 == 2){ + hit1->sign = -1; + } + if(choiceOfT2 == 3){ + hit1->sign = -1; + } + } + } + + for(std::list::iterator hit1 = tracklet3.hits.begin(); hit1 != tracklet3.hits.end(); ++hit1) + { + if(hit1->hit.detectorID == 19 || hit1->hit.detectorID == 25){ + if(choiceOfT3 == 0){ + hit1->sign = 1; + } + if(choiceOfT3 == 1){ + hit1->sign = -1; + } + if(choiceOfT3 == 2){ + hit1->sign = 1; + } + if(choiceOfT3 == 3){ + hit1->sign = -1; + } + } else{ + if(choiceOfT3 == 0){ + hit1->sign = 1; + } + if(choiceOfT3 == 1){ + hit1->sign = 1; + } + if(choiceOfT3 == 2){ + hit1->sign = -1; + } + if(choiceOfT3 == 3){ + hit1->sign = -1; + } + } + } + + return true; + +} + +bool KalmanFastTracking_NEW_2::compareTrackletsSlimU_3hits(Tracklet& tracklet2, Tracklet& tracklet3, int pass, double slopeComparison, double windowSize) +{ + + if( ! ( (tracklet2.hits.size() == 2 && tracklet3.hits.size() == 1 ) || (tracklet2.hits.size() == 1 && tracklet3.hits.size() == 2 ) ) ) return false; + + double bestMatch = 100.; + if(tracklet2.hits.size() == 2){ + + unsigned int bestT2 = 5; + for(unsigned int t2 = 0; t2 < tracklet2.possibleULines.size(); t2++){ + double extrapolation = tracklet2.possibleULines.at(t2).slopeU*(z_plane[tracklet3.getHit(0).hit.detectorID] - tracklet2.possibleULines.at(t2).initialZ) + tracklet2.possibleULines.at(t2).initialU; + if(std::abs(tracklet3.getHit(0).hit.pos - extrapolation) < bestMatch && std::abs(tracklet3.getHit(0).hit.pos - extrapolation) < windowSize){ + bestMatch = std::abs(tracklet3.getHit(0).hit.pos - extrapolation); + bestT2 = t2; + } + } + + if(bestMatch > 99. || bestT2 == 5){ + return false; + } else{ + + double newSlopeU = (tracklet3.getHit(0).hit.pos - tracklet2.possibleULines.at(bestT2).initialU)/(z_plane[tracklet3.getHit(0).hit.detectorID] - tracklet2.possibleULines.at(bestT2).initialZ); + + tracklet2.acceptedULine2 = tracklet2.possibleULines.at(bestT2); + tracklet3.acceptedULine3 = tracklet2.possibleULines.at(bestT2); + tracklet2.tx = newSlopeU; + tracklet3.tx = newSlopeU; + + tracklet2.st2Usl = newSlopeU; + tracklet3.st2Usl = newSlopeU; + + + for(std::list::iterator hit1 = tracklet2.hits.begin(); hit1 != tracklet2.hits.end(); ++hit1) + { + if(hit1->hit.detectorID == 17){ + if(bestT2 == 0){ + hit1->sign = 1; + } + if(bestT2 == 1){ + hit1->sign = -1; + } + if(bestT2 == 2){ + hit1->sign = 1; + } + if(bestT2 == 3){ + hit1->sign = -1; + } + } else{ + if(bestT2 == 0){ + hit1->sign = 1; + } + if(bestT2 == 1){ + hit1->sign = 1; + } + if(bestT2 == 2){ + hit1->sign = -1; + } + if(bestT2 == 3){ + hit1->sign = -1; + } + } + } + + + return true; + } + } + + if(tracklet3.hits.size() == 2){ + + unsigned int bestT3 = 5; + for(unsigned int t3 = 0; t3 < tracklet3.possibleULines.size(); t3++){ + double extrapolation = tracklet3.possibleULines.at(t3).slopeU*(z_plane[tracklet2.getHit(0).hit.detectorID] - tracklet3.possibleULines.at(t3).initialZ) + tracklet3.possibleULines.at(t3).initialU; + if(std::abs(tracklet2.getHit(0).hit.pos - extrapolation) < bestMatch && std::abs(tracklet2.getHit(0).hit.pos - extrapolation) < windowSize){ + bestMatch = std::abs(tracklet2.getHit(0).hit.pos - extrapolation); + bestT3 = t3; + } + } + + if(bestMatch > 99. || bestT3 == 5){ + return false; + } else{ + + double newSlopeU = (tracklet2.getHit(0).hit.pos - tracklet3.possibleULines.at(bestT3).initialU)/(z_plane[tracklet2.getHit(0).hit.detectorID] - tracklet3.possibleULines.at(bestT3).initialZ); + + tracklet2.acceptedULine2 = tracklet3.possibleULines.at(bestT3); + tracklet3.acceptedULine3 = tracklet3.possibleULines.at(bestT3); + tracklet2.tx = newSlopeU; + tracklet3.tx = newSlopeU; + + tracklet2.st2Usl = newSlopeU; + tracklet3.st2Usl = newSlopeU; + + for(std::list::iterator hit1 = tracklet3.hits.begin(); hit1 != tracklet3.hits.end(); ++hit1) + { + if(hit1->hit.detectorID == 19 || hit1->hit.detectorID == 25){ + if(bestT3 == 0){ + hit1->sign = 1; + } + if(bestT3 == 1){ + hit1->sign = -1; + } + if(bestT3 == 2){ + hit1->sign = 1; + } + if(bestT3 == 3){ + hit1->sign = -1; + } + } else{ + if(bestT3 == 0){ + hit1->sign = 1; + } + if(bestT3 == 1){ + hit1->sign = 1; + } + if(bestT3 == 2){ + hit1->sign = -1; + } + if(bestT3 == 3){ + hit1->sign = -1; + } + } + } + + + return true; + + } + } +} + + + +bool KalmanFastTracking_NEW_2::compareTrackletsSlimV(Tracklet& tracklet2, Tracklet& tracklet3, int pass, double slopeComparison, double windowSize) +{ + if( !( tracklet2.hits.size() == 2 && tracklet3.hits.size() == 2 ) ) return false; + + double slopeWindow = 0.005; + double extrapoWindow = 5.0; + + if(pass == 2){ + slopeWindow = 0.008; + extrapoWindow = 12.; + } + + //Here we will compare the possible X-Z slopes within the station 2 and station 3 tracklets + Tracklet::linedef line2V; + Tracklet::linedef line3V; + Tracklet::linedef line2V_v2; + Tracklet::linedef line3V_v2; + + int choiceOfT2 = 5; + int choiceOfT3 = 5; + int choiceOfT2_v2 = 5; + int choiceOfT3_v2 = 5; + + double st3pos = (tracklet3.getHit(0).hit.pos + tracklet3.getHit(1).hit.pos)/2; + double st3posZ = (z_plane[tracklet3.getHit(0).hit.detectorID] + z_plane[tracklet3.getHit(1).hit.detectorID])/2; + + double slopeComp = 1.0; + double bestExtrapComp = 100.; + + double slopeComp2 = 1.0; + double bestExtrapComp2 = 100.; + + double bestExtrapMatch = 100.; + + double secondSlope = 1.1; + for(unsigned int t2 = 0; t2 < tracklet2.possibleVLines.size(); t2++){ + + double st2ExtrapMatch = tracklet2.possibleVLines.at(t2).slopeV*(st3posZ - tracklet2.possibleVLines.at(t2).initialZ) + tracklet2.possibleVLines.at(t2).initialV - st3pos; + if( std::abs(st2ExtrapMatch) < windowSize && std::abs(st2ExtrapMatch) < bestExtrapMatch ){ + + for(unsigned int t3 = 0; t3 < tracklet3.possibleVLines.size(); t3++){ + + if(std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV) < slopeComp && std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV) < slopeComparison){ + + slopeComp = std::abs(tracklet3.possibleVLines.at(t3).slopeV - tracklet2.possibleVLines.at(t2).slopeV); + bestExtrapComp = st2ExtrapMatch; + bestExtrapMatch = std::abs(st2ExtrapMatch); + line2V = tracklet2.possibleVLines.at(t2); + line3V = tracklet3.possibleVLines.at(t3); + choiceOfT2 = t2; + choiceOfT3 = t3; + + } + } + } + } + + + +#ifdef _DEBUG_RES + LogInfo("slopeComp = "< slopeComparison) return false; + if(bestExtrapComp > windowSize) return false; + + + + + + + + tracklet2.acceptedVLine2 = line2V; + tracklet3.acceptedVLine3 = line3V; + + tracklet2.st2V = line2V.initialV; + tracklet3.st2V = line3V.initialV; + tracklet3.st3V = line3V.initialV; + + double newSlopeV = (tracklet3.possibleVLines.at(choiceOfT3).initialV - tracklet2.possibleVLines.at(choiceOfT2).initialV)/(tracklet3.possibleVLines.at(choiceOfT3).initialZ - tracklet2.possibleVLines.at(choiceOfT2).initialZ); + + tracklet2.st2Vsl = newSlopeV; + tracklet3.st2Vsl = newSlopeV; + + for(std::list::iterator hit1 = tracklet2.hits.begin(); hit1 != tracklet2.hits.end(); ++hit1) + { + if(hit1->hit.detectorID == 13){ + if(choiceOfT2 == 0){ + hit1->sign = 1; + } + if(choiceOfT2 == 1){ + hit1->sign = -1; + } + if(choiceOfT2 == 2){ + hit1->sign = 1; + } + if(choiceOfT2 == 3){ + hit1->sign = -1; + } + } else{ + if(choiceOfT2 == 0){ + hit1->sign = 1; + } + if(choiceOfT2 == 1){ + hit1->sign = 1; + } + if(choiceOfT2 == 2){ + hit1->sign = -1; + } + if(choiceOfT2 == 3){ + hit1->sign = -1; + } + } + } + + for(std::list::iterator hit1 = tracklet3.hits.begin(); hit1 != tracklet3.hits.end(); ++hit1) + { + if(hit1->hit.detectorID == 23 || hit1->hit.detectorID == 29){ + if(choiceOfT3 == 0){ + hit1->sign = 1; + } + if(choiceOfT3 == 1){ + hit1->sign = -1; + } + if(choiceOfT3 == 2){ + hit1->sign = 1; + } + if(choiceOfT3 == 3){ + hit1->sign = -1; + } + } else{ + if(choiceOfT3 == 0){ + hit1->sign = 1; + } + if(choiceOfT3 == 1){ + hit1->sign = 1; + } + if(choiceOfT3 == 2){ + hit1->sign = -1; + } + if(choiceOfT3 == 3){ + hit1->sign = -1; + } + } + } + + return true; + +} + + +bool KalmanFastTracking_NEW_2::compareTrackletsSlimV_3hits(Tracklet& tracklet2, Tracklet& tracklet3, int pass, double slopeComparison, double windowSize) +{ + + if( ! ( (tracklet2.hits.size() == 2 && tracklet3.hits.size() == 1 ) || (tracklet2.hits.size() == 1 && tracklet3.hits.size() == 2 ) ) ) return false; + + double bestMatch = 100.; + if(tracklet2.hits.size() == 2){ + + unsigned int bestT2 = 5; + for(unsigned int t2 = 0; t2 < tracklet2.possibleVLines.size(); t2++){ + double extrapolation = tracklet2.possibleVLines.at(t2).slopeV*(z_plane[tracklet3.getHit(0).hit.detectorID] - tracklet2.possibleVLines.at(t2).initialZ) + tracklet2.possibleVLines.at(t2).initialV; + if(std::abs(tracklet3.getHit(0).hit.pos - extrapolation) < bestMatch && std::abs(tracklet3.getHit(0).hit.pos - extrapolation) < windowSize){ + bestMatch = std::abs(tracklet3.getHit(0).hit.pos - extrapolation); + bestT2 = t2; + } + } + + if(bestMatch > 99. || bestT2 == 5){ + return false; + } else{ + + double newSlopeV = (tracklet3.getHit(0).hit.pos - tracklet2.possibleVLines.at(bestT2).initialV)/(z_plane[tracklet3.getHit(0).hit.detectorID] - tracklet2.possibleVLines.at(bestT2).initialZ); + + tracklet2.acceptedVLine2 = tracklet2.possibleVLines.at(bestT2); + tracklet3.acceptedVLine3 = tracklet2.possibleVLines.at(bestT2); + tracklet2.tx = newSlopeV; + tracklet3.tx = newSlopeV; + + tracklet2.st2Vsl = newSlopeV; + tracklet3.st2Vsl = newSlopeV; + + + for(std::list::iterator hit1 = tracklet2.hits.begin(); hit1 != tracklet2.hits.end(); ++hit1) + { + if(hit1->hit.detectorID == 13){ + if(bestT2 == 0){ + hit1->sign = 1; + } + if(bestT2 == 1){ + hit1->sign = -1; + } + if(bestT2 == 2){ + hit1->sign = 1; + } + if(bestT2 == 3){ + hit1->sign = -1; + } + } else{ + if(bestT2 == 0){ + hit1->sign = 1; + } + if(bestT2 == 1){ + hit1->sign = 1; + } + if(bestT2 == 2){ + hit1->sign = -1; + } + if(bestT2 == 3){ + hit1->sign = -1; + } + } + } + + + return true; + } + } + + if(tracklet3.hits.size() == 2){ + + unsigned int bestT3 = 5; + for(unsigned int t3 = 0; t3 < tracklet3.possibleVLines.size(); t3++){ + double extrapolation = tracklet3.possibleVLines.at(t3).slopeV*(z_plane[tracklet2.getHit(0).hit.detectorID] - tracklet3.possibleVLines.at(t3).initialZ) + tracklet3.possibleVLines.at(t3).initialV; + if(std::abs(tracklet2.getHit(0).hit.pos - extrapolation) < bestMatch && std::abs(tracklet2.getHit(0).hit.pos - extrapolation) < windowSize){ + bestMatch = std::abs(tracklet2.getHit(0).hit.pos - extrapolation); + bestT3 = t3; + } + } + + if(bestMatch > 99. || bestT3 == 5){ + return false; + } else{ + + double newSlopeV = (tracklet2.getHit(0).hit.pos - tracklet3.possibleVLines.at(bestT3).initialV)/(z_plane[tracklet2.getHit(0).hit.detectorID] - tracklet3.possibleVLines.at(bestT3).initialZ); + + tracklet2.acceptedVLine2 = tracklet3.possibleVLines.at(bestT3); + tracklet3.acceptedVLine3 = tracklet3.possibleVLines.at(bestT3); + tracklet2.tx = newSlopeV; + tracklet3.tx = newSlopeV; + + tracklet2.st2Vsl = newSlopeV; + tracklet3.st2Vsl = newSlopeV; + + for(std::list::iterator hit1 = tracklet3.hits.begin(); hit1 != tracklet3.hits.end(); ++hit1) + { + if(hit1->hit.detectorID == 23 || hit1->hit.detectorID == 29){ + if(bestT3 == 0){ + hit1->sign = 1; + } + if(bestT3 == 1){ + hit1->sign = -1; + } + if(bestT3 == 2){ + hit1->sign = 1; + } + if(bestT3 == 3){ + hit1->sign = -1; + } + } else{ + if(bestT3 == 0){ + hit1->sign = 1; + } + if(bestT3 == 1){ + hit1->sign = 1; + } + if(bestT3 == 2){ + hit1->sign = -1; + } + if(bestT3 == 3){ + hit1->sign = -1; + } + } + } + + + return true; + + } + } +} + diff --git a/packages/reco/ktracker/KalmanFastTracking_NEW_2.h b/packages/reco/ktracker/KalmanFastTracking_NEW_2.h new file mode 100644 index 00000000..d194c617 --- /dev/null +++ b/packages/reco/ktracker/KalmanFastTracking_NEW_2.h @@ -0,0 +1,306 @@ +/* +KalmanFastTracking_NEW.h + +Fast tracking utility of Kalman filter track, used to improve the tracking speed and also for online monitoring + +Author: Kun Liu, liuk@fnal.gov +Created: 05-24-2013 +*/ + +#ifndef _KALMANFASTTRACKING_NEW_2_H +#define _KALMANFASTTRACKING_NEW_2_H + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "TMathBase.h" + +#include "SRawEvent.h" +#include "KalmanTrack.h" +#include "KalmanFitter.h" +#include "FastTracklet.h" + +class TGeoManager; + +class PHField; +class PHTimer; + +class KalmanFastTracking_NEW_2 +{ +public: + explicit KalmanFastTracking_NEW_2(const PHField* field, const TGeoManager *geom, bool flag = true); + ~KalmanFastTracking_NEW_2(); + + //set/get verbosity + void Verbosity(const int a) {verbosity = a;} + int Verbosity() const {return verbosity;} + void printTimers(); + + //Set the input event + int setRawEvent(SRawEvent* event_input); + void setRawEventDebug(SRawEvent* event_input); + + //Event quality cut + bool acceptEvent(SRawEvent* rawEvent); + + ///Tracklet finding stuff + //Build tracklets in a station + void buildTrackletsInStation(int stationID, int listID, double* pos_exp = nullptr, double* window = nullptr); + void buildTrackletsInStationSlim(int stationID, int listID, double* pos_exp = nullptr, double* window = nullptr); + void buildTrackletsInStationSlimU(int stationID, int listID, double* pos_exp = nullptr, double* window = nullptr); + void buildTrackletsInStationSlimV(int stationID, int listID, double* pos_exp = nullptr, double* window = nullptr); + + bool buildTrackletsInStation1_NEW(int stationID, int listID, double expXZSlope, double expYSlope, double y0, bool tight, double* pos_exp = nullptr, double* window = nullptr); + + //Build back partial tracks using tracklets in station 2 & 3 + void buildBackPartialTracks(); + void buildBackPartialTracksSlim_v3(int cut); + void buildBackPartialTracksSlimX(int pass, double slopeComparison, double windowSize); + void buildBackPartialTracksSlimU(int pass, double slopeComparison, double windowSize); + void buildBackPartialTracksSlimV(int pass, double slopeComparison, double windowSize); + + //Build global tracks by connecting station 23 tracklets and station 1 tracklets + void buildGlobalTracks(); + + //Build global tracks by connecting station 23 tracklets and station 1 tracklets + void buildGlobalTracksDisplaced(); + + //Fit tracklets + int fitTracklet(Tracklet& tracklet); + + //Check the quality of tracklet, number of hits + bool acceptTracklet(Tracklet& tracklet); + bool hodoMask(Tracklet& tracklet); + bool muonID_comp(Tracklet& tracklet); + bool muonID_search(Tracklet& tracklet); + bool muonID_hodoAid(Tracklet& tracklet); + + bool compareTracklets(Tracklet& tracklet1, Tracklet& tracklet2); + + bool compareTrackletsSlim(Tracklet& tracklet1, Tracklet& tracklet2, int pass, double slopeComparison, double windowSize); + bool compareTrackletsSlim_3hits(Tracklet& tracklet1, Tracklet& tracklet2, int pass, double slopeComparison, double windowSize); + + bool compareTrackletsSlimU(Tracklet& tracklet1, Tracklet& tracklet2, int pass, double slopeComparison, double windowSize); + bool compareTrackletsSlimU_3hits(Tracklet& tracklet1, Tracklet& tracklet2, int pass, double slopeComparison, double windowSize); + + bool compareTrackletsSlimV(Tracklet& tracklet1, Tracklet& tracklet2, int pass, double slopeComparison, double windowSize); + bool compareTrackletsSlimV_3hits(Tracklet& tracklet1, Tracklet& tracklet2, int pass, double slopeComparison, double windowSize); + + void buildPropSegments(); + + //Resolve left-right when possible + void resolveLeftRight(SRawEvent::hit_pair hpair, int& LR1, int& LR2); + void resolveLeftRight(Tracklet& tracklet, double threshold); + void resolveSingleLeftRight(Tracklet& tracklet); + + //Remove bad hit if needed + void removeBadHits(Tracklet& tracklet); + + //Reduce the list of tracklets, returns the number of elements reduced + int reduceTrackletList(std::list& tracklets); + + //Get exp postion and window using sagitta method in station 1 + void getSagittaWindowsInSt1(Tracklet& tracklet, double* pos_exp, double* window, int st1ID); + void getExtrapoWindowsInSt1(Tracklet& tracklet, double* pos_exp, double* window, int st1ID); + + //Print the distribution of tracklets at detector back/front + void printAtDetectorBack(int stationID, std::string outputFileName); + + ///Track fitting stuff + //Convert Tracklet to KalmanTrack and solve left-right problem, and eventually to a SRecTrack + SRecTrack processOneTracklet(Tracklet& tracklet); + + //Use Kalman fitter to fit a track + bool fitTrack(KalmanTrack& kmtrk); + + //Resolve left right by Kalman fitting results + void resolveLeftRight(KalmanTrack& kmtrk); + + ///Final output + std::list& getFinalTracklets() { return trackletsInSt[outputListIdx]; } + std::list& getBackPartials() { return trackletsInSt[3]; } + std::list& getTrackletList(int i) { return trackletsInSt[i]; } + std::list& getSRecTracks() { return stracks; } + std::list& getPropSegments(int i) { return propSegs[i]; } + + ///Set the index of the final output tracklet list + void setOutputListID(unsigned int i) { outputListIdx = i; } + + ///Tool, a simple-minded chi square fit + void chi2fit(int n, double x[], double y[], double& a, double& b); + +private: + //verbosity following Fun4All convention + int verbosity; + + //Raw event input + SRawEvent* rawEvent; + std::vector hitAll; + + //Tracklets in one event, id = 0, 1, 2 for station 0/1, 2, 3+/-, id = 3 for station 2&3 combined, id = 4 for global tracks + //Likewise for the next part + //std::list trackletsInSt[5]; + //std::list trackletsInStSlimX[5]; + //std::list trackletsInStSlimU[5]; + //std::list trackletsInStSlimV[5]; + + std::list trackletsInSt[5]; + std::list trackletsInStSlimX[5][200]; + std::list trackletsInStSlimU[5][200]; + std::list trackletsInStSlimV[5][200]; + + long int num23XCombos; + long int num23UCombos; + long int num23VCombos; + + int getNum23Combos(){ + num23XCombos = 0; + num23UCombos = 0; + num23VCombos = 0; + for(unsigned int b = 0; b < 200; b++){ + num23XCombos += trackletsInStSlimX[3][b].size(); + num23UCombos += trackletsInStSlimU[3][b].size(); + num23VCombos += trackletsInStSlimV[3][b].size(); + } + } + + bool isSlimMiddle(){ + int nX = 0; + int nU = 0; + int nV = 0; + for(unsigned int b = 85; b < 115; b++){ + //std::cout<<"bs that we test: "< #include +//#define _DEBUG_ON + #ifdef _DEBUG_ON # define LogDebug(exp) std::cout << "DEBUG: " << __FUNCTION__ <<": "<< __LINE__ << ": " << exp << std::endl #else @@ -112,7 +116,9 @@ int SQReco::InitRun(PHCompositeNode* topNode) if(ret != Fun4AllReturnCodes::EVENT_OK) return ret; //Init track finding - _fastfinder = new KalmanFastTracking(_phfield, _t_geo_manager, false); + //_fastfinder = new KalmanFastTracking(_phfield, _t_geo_manager, false); + //_fastfinder = new KalmanFastTracking_NEW(_phfield, _t_geo_manager, false); + _fastfinder = new KalmanFastTracking_NEW_2(_phfield, _t_geo_manager, false); _fastfinder->Verbosity(Verbosity()); @@ -346,8 +352,9 @@ int SQReco::process_event(PHCompositeNode* topNode) _recEvent->setRawEvent(_rawEvent); _recEvent->setRecStatus(finderstatus); } - if(Verbosity() >= Fun4AllBase::VERBOSITY_A_LOT) _fastfinder->printTimers(); - + //if(Verbosity() >= Fun4AllBase::VERBOSITY_A_LOT) _fastfinder->printTimers(); //WPM + _fastfinder->printTimers(); //WPM + int nTracklets = 0; int nFittedTracks = 0; std::list& rec_tracklets = _fastfinder->getFinalTracklets(); @@ -396,8 +403,11 @@ int SQReco::process_event(PHCompositeNode* topNode) { if(_fitter_type == SQReco::LEGACY){ fitOK = fitSt3TrackletCand(*iter, _kfitter); + //std::cout<<"it was legacy"< Fun4AllBase::VERBOSITY_A_LOT) - iter->print(); - _tracklet_vector->push_back(&(*iter)); - } + //iter->print(); + _tracklet_vector->push_back(&(*iter)); + } + } } } diff --git a/packages/reco/ktracker/SQReco.h b/packages/reco/ktracker/SQReco.h index 205422a5..69029746 100644 --- a/packages/reco/ktracker/SQReco.h +++ b/packages/reco/ktracker/SQReco.h @@ -21,6 +21,8 @@ class PHField; class Tracklet; class KalmanFastTracking; +class KalmanFastTracking_NEW; +class KalmanFastTracking_NEW_2; class KalmanFitter; class EventReducer; class SRawEvent; @@ -113,7 +115,9 @@ class SQReco: public SubsysReco TrackletVector* _tracklet_vector; TString _evt_reducer_opt; - KalmanFastTracking* _fastfinder; + //KalmanFastTracking* _fastfinder; + //KalmanFastTracking_NEW* _fastfinder; + KalmanFastTracking_NEW_2* _fastfinder; EventReducer* _eventReducer; bool _enable_KF; diff --git a/packages/reco/ktracker/UtilSRawEvent.cxx b/packages/reco/ktracker/UtilSRawEvent.cxx index b49891a8..39d48be4 100644 --- a/packages/reco/ktracker/UtilSRawEvent.cxx +++ b/packages/reco/ktracker/UtilSRawEvent.cxx @@ -68,7 +68,9 @@ bool UtilSRawEvent::SetHit(SRawEvent* sraw, const SQHitVector* hit_vec, std::map h.tdcTime = sq_hit->get_tdc_time(); h.driftDistance = fabs(sq_hit->get_drift_distance()); //MC L-R info removed here h.pos = sq_hit->get_pos(); + //std::cout<<"in sethit. index = "<get_hit_id()<<", detID = "<get_detector_id()<<", elementID = "<get_element_id()<<", tdcTime = "<get_tdc_time()<<", driftDistance = "<get_drift_distance())<<", pos = "<get_pos()<<", is_in_time = "<is_in_time()<is_in_time()) h.setInTime(); + //std::cout<<"and second in time check = "<is_in_time()<<" and "<insertHit(h); } sraw->reIndex(true); diff --git a/simulation/g4detectors/SQChamberRealization.cc b/simulation/g4detectors/SQChamberRealization.cc index 2cef0b1a..0c780214 100644 --- a/simulation/g4detectors/SQChamberRealization.cc +++ b/simulation/g4detectors/SQChamberRealization.cc @@ -63,42 +63,35 @@ int SQChamberRealization::process_event(PHCompositeNode* topNode) SQHitVector::Iter it = m_hit_vec->begin(); while (it != m_hit_vec->end()) { SQHit* hit = *it; - int det_id = hit->get_detector_id(); - PlaneParam* param = &list_param[det_id]; - if (! param->on) { - it++; - continue; - } - - int ele_id = hit->get_element_id(); - bool is_eff = (gRandom->Rndm() < param->eff); - if (Verbosity() >= 2) { - string det_name = GeomSvc::instance()->getDetectorName(det_id); - cout << " Hit: det=" << det_id << ":" << det_name << " ele=" << ele_id << " is_eff=" << is_eff << endl; - } - if (! is_eff) { - it = m_hit_vec->erase(it); - continue; - } + int det_id = hit->get_detector_id(); + string det_name = GeomSvc::instance()->getDetectorName(det_id); + + bool is_eff = true; + //std::cout<<"test det_name: "<Rndm() < m_eff_d0 ); + else if (det_name.substr(0, 2) == "D1" ) is_eff = (gRandom->Rndm() < m_eff_d1 ); + else if (det_name.substr(0, 2) == "D2" ) is_eff = (gRandom->Rndm() < m_eff_d2 ); + else if (det_name.substr(0, 3) == "D3p") is_eff = (gRandom->Rndm() < m_eff_d3p); + else if (det_name.substr(0, 3) == "D3m") is_eff = (gRandom->Rndm() < m_eff_d3m); + else if (det_name.substr(0, 3) == "P1X") is_eff = (gRandom->Rndm() < m_eff_p1x); + else if (det_name.substr(0, 3) == "P1Y") is_eff = (gRandom->Rndm() < m_eff_p1y); + else if (det_name.substr(0, 3) == "P2X") is_eff = (gRandom->Rndm() < m_eff_p2x); + else if (det_name.substr(0, 3) == "P2Y") is_eff = (gRandom->Rndm() < m_eff_p2y); + //std::cout<<"what is is_eff? "<set_in_time(is_eff); // Temporary solution!! + + TGraphErrors* gr_x2t; + TGraphErrors* gr_x2dt; + if (m_cal_xt->FindX2T(det_id, gr_x2t, gr_x2dt)) { + int ele_id = hit->get_element_id(); + double dist = hit->get_drift_distance(); + double mean_t = gr_x2t ->Eval(fabs(dist)); + double width_t = gr_x2dt->Eval(fabs(dist)); + double drift_time = -1; + for (int i_try = 0; i_try < 10000; i_try++) { + drift_time = gRandom->Gaus(mean_t, width_t); + if (drift_time >= 0) break; - CalibParamXT::Set* xt = m_cal_xt->GetParam(det_id); - if (xt) { - double dist = hit->get_drift_distance(); - int dist_sign = dist > 0 ? +1 : -1; - dist *= dist_sign; // Made positive. - - double dx; - if (param->reso_fixed >= 0) dx = param->reso_fixed; - else dx = xt->x2dx.Eval(dist); - if (param->reso_scale >= 0) dx *= param->reso_scale; - if (Verbosity() >= 2) cout << " dist=" << dist << " dx=" << dx << " X0=" << xt->X0 << " X1=" << xt->X1 << endl; - - double dist_new; - int n_try = 10000; - while (n_try > 0) { - dist_new = gRandom->Gaus(dist, dx); - if (xt->X0 <= dist_new && dist_new <= xt->X1) break; - n_try--; } if (n_try == 0) { cout << PHWHERE << " Failed at generating an in-range drift time. Something unexpected. Abort." << endl; diff --git a/simulation/g4detectors/SQDigitizer.cc b/simulation/g4detectors/SQDigitizer.cc index 324f88f6..f64b8d0c 100644 --- a/simulation/g4detectors/SQDigitizer.cc +++ b/simulation/g4detectors/SQDigitizer.cc @@ -56,7 +56,7 @@ SQDigitizer::SQDigitizer(const std::string& name, const int verbose): p_geomSvc(nullptr), enableDC1(false), enableDPHodo(true), - digitize_secondaries(false) + digitize_secondaries(true) { detIDByName.clear(); Verbosity(0);