28#include <nlohmann/json.hpp>
34 nearZero(
const double & v){
35 return std::abs(v)<=std::numeric_limits<double>::min();
44static inline std::string
to_string(
const std::vector<T>& v)
46 std::ostringstream oss;
50 std::copy(v.begin(), v.end() - 1, std::ostream_iterator<T>(oss,
", "));
62 base_class(algname, name, ifc)
64 declareInterface<IFPGATrackSimRoadFinderTool>(
this);
71 const std::vector<Gaudi::Details::PropertyBase*> props = this->getProperties();
72 for( Gaudi::Details::PropertyBase* prop : props ) {
73 if (prop->ownerTypeName()==this->type()) {
74 ATH_MSG_DEBUG(
"Property:\t" << prop->name() <<
"\t : \t" << prop->toString());
88 if (nLogicalLayers == 0){
89 ATH_MSG_ERROR(
"Number of logical layers is zero in FPGATrackSimGenScanTool::initialize");
90 return StatusCode::FAILURE;
103 const int signedSize =
static_cast<int>(
m_binnedhits->getNLayers()) - 1;
119 return StatusCode::FAILURE;
127 return StatusCode::SUCCESS;
134 std::vector<FPGATrackSimRoad> &roads)
144 m_monitoring->parseTruthInfo(getTruthTracks(),(hits.size() < 100));
164 std::vector<HitPairSet> pairsets;
182 if (pairsets.size() >1) {
186 s +=
"(" + std::to_string(hit->
layer) +
"," + std::to_string(hit->
hitptr->
getR()) +
"), ";
198 const std::vector<std::vector<std::shared_ptr<const FPGATrackSimHit>>>& theseHits =
r.getAllHitPtrs();
202 std::vector<std::vector<std::shared_ptr<const FPGATrackSimHit>>>
vec(5);
203 for (
size_t ihit = 0; ihit < toUse.size(); ++ihit) {
204 unsigned int layer = toUse[ihit];
205 if (layer >= theseHits.size() || theseHits[layer].empty()) {
206 ATH_MSG_ERROR(
"Hit index out of range in keepHitsStrategy: layer=" << layer <<
", hits.size()=" << theseHits.size());
207 return StatusCode::FAILURE;
209 vec[ihit].push_back(theseHits[layer][0]);
211 r.setHits(std::move(
vec));
223 return StatusCode::SUCCESS;
228 std::vector<HitPairSet> &output_pairsets)
233 std::vector<std::vector<const StoredHit *>> hitsByLayer(
m_binnedhits->getNLayers());
253 if (passedPairFilter)
256 std::vector<HitPairSet> pairsets;
266 output_pairsets.push_back(pairset);
275 output_pairsets.push_back(std::move(pairs));
280 output_pairsets.push_back(std::move(filteredpairs));
283 return StatusCode::SUCCESS;
290 const std::vector<const StoredHit *>& newhits)
294 std::vector<bool> pairset_used(inputstate.
pairsets.size(),
false);
296 for (
auto &newhit : newhits) {
299 std::set<const StoredHit *> vetoList;
302 for (
unsigned ps_idx = 0; ps_idx < inputstate.
pairsets.size(); ++ps_idx) {
303 auto &pairset = inputstate.
pairsets[ps_idx];
308 pairset_used[ps_idx]=
true;
309 outputstate.
pairsets.push_back(std::move(newset));
311 for (
auto vetohit : pairset.hitlist) {
312 vetoList.insert(vetohit);
319 if (vetoList.count(prevhit) == 0) {
324 outputstate.
pairsets.push_back(std::move(newset));
331 if (lyridx <= allowed_missed_hits) {
340 for (
unsigned ps_idx = 0; ps_idx < inputstate.
pairsets.size(); ++ps_idx) {
341 auto &pairset = inputstate.
pairsets[ps_idx];
342 if ((!pairset_used[ps_idx])&&(lyridx < (pairset.hitlist.size() + allowed_missed_hits))) {
343 outputstate.
pairsets.push_back(pairset);
359 if (lyridx > allowed_missed_hits) {
372 std::vector<HitPairSet> &output_pairsets)
377 std::vector<std::vector<const StoredHit *>> hitsByLayer(
m_binnedhits->getNLayers());
384 std::vector<IntermediateState> states{
m_binnedhits->getNLayers()+1};
385 for (
unsigned lyridx = 0; lyridx <
m_binnedhits->getNLayers(); lyridx++) {
387 updateState(states[lyridx] , states[lyridx+1], lyridx, hitsByLayer[lyr]);
391 output_pairsets=states[
m_binnedhits->getNLayers()].pairsets;
395 return StatusCode::SUCCESS;
401 std::vector<std::vector<const StoredHit *>>& hitsByLayer)
406 hitsByLayer.at(hit.
layer).push_back(&hit);
409 return StatusCode::SUCCESS;
422 std::vector<const StoredHit *>
const * lastlyr = 0;
423 std::vector<const StoredHit *>
const * lastlastlyr = 0;
430 for (
const StoredHit *
const &ptr2 : *lastlyr) {
435 for (
const StoredHit *
const &ptr2 : *lastlastlyr) {
441 lastlastlyr = lastlyr;
442 lastlyr = &hitsByLayer[lyr];
446 return StatusCode::SUCCESS;
454 int lyr = std::min(
pair.first->layer,
pair.second->layer);
472 return StatusCode::SUCCESS;
478 std::vector<HitPairSet> &pairsets,
488 if ((std::abs(
int(
pair.second->layer) -
int(
pair.first->layer)) > 1)
489 && (pairset.hasLayer(std::min(
pair.first->layer,
pair.second->layer) + 1)))
503 int size = pairset.addPair(
pair);
505 ATH_MSG_VERBOSE(
"addPair " << pairsets.size() <<
" " << pairset.pairList.size() <<
" " << size);
516 pairsets.push_back(std::move(newpairset));
520 return StatusCode::SUCCESS;
538 std::vector<bool> allcutsPassed;
539 allcutsPassed.push_back(matchPhiPassed);
540 allcutsPassed.push_back(matchEtaPassed);
541 allcutsPassed.push_back(deltaDeltaPhiPassed);
542 allcutsPassed.push_back(deltaDeltaEtaPassed);
543 allcutsPassed.push_back(phiCurvaturePassed);
544 allcutsPassed.push_back(etaCurvaturePassed);
546 bool deltaPhiCurvaturePassed =
true;
547 bool deltaEtaCurvaturePassed =
true;
551 allcutsPassed.push_back(deltaPhiCurvaturePassed);
552 allcutsPassed.push_back(deltaEtaCurvaturePassed);
554 allcutsPassed.push_back(phiInExtrapPassed);
555 allcutsPassed.push_back(phiOutExtrapPassed);
558 unsigned passedCuts = std::count_if(allcutsPassed.begin(), allcutsPassed.end(),
559 [](
bool cut) { return cut; });
560 bool passedAll = (passedCuts == allcutsPassed.size());
571 cutvar(std::string name,
double val,
double cut, std::vector<TH1D *>& histset) :
572 m_name(std::move(name)), m_val(val), m_cut(cut), m_histset(histset) {}
573 bool passed() {
return std::abs(m_val) < m_cut; }
574 void fill(
unsigned cat) { m_histset[cat]->Fill(m_val); }
578 std::vector<TH1D *> &m_histset;
582 std::vector<cutvar> allcuts;
583 allcuts.push_back(cutvar(
"MatchPhi", pairset.
MatchPhi(
pair),
586 allcuts.push_back(cutvar(
"MatchEta", pairset.
MatchEta(
pair),
602 allcuts.push_back(cutvar(
605 allcuts.push_back(cutvar(
609 allcuts.push_back(cutvar(
612 allcuts.push_back(cutvar(
617 unsigned monitoringPassedCuts = std::count_if(allcuts.begin(), allcuts.end(),
618 [](cutvar& cut) { return cut.passed(); });
619 bool monitoringPassedAll = (monitoringPassedCuts == allcuts.size());
620 bool monitoringPassedAllButOne = (monitoringPassedCuts == allcuts.size() - 1);
621 for (cutvar& cut: allcuts) {
625 (monitoringPassedAll || (monitoringPassedAllButOne && !cut.passed())));
631 for (cutvar &cut : allcuts)
633 s += cut.m_name +
" : (" + cut.passed() +
", " + cut.m_val +
"), ";
635 ATH_MSG_DEBUG(
"PairSet test " << monitoringPassedAll <<
" " << s);
637 << *pairset.
lastpair().second <<
"\n "
638 << *
pair.first <<
"\n "
650 std::vector<std::vector<std::shared_ptr<const FPGATrackSimHit>>>
651 sorted_hits(
m_binnedhits->getNLayers(),std::vector<std::shared_ptr<const FPGATrackSimHit>>());
654 hitLayers |= 1 << hit->layer;
655 sorted_hits[hit->layer].push_back(hit->hitptr);
660 double chi2,chi2_phi,chi2_eta;
661 bool inBin =
fitRoad(hits, idx, fittedpars,
chi2, chi2_phi,chi2_eta);
667 r.setRoadID(
static_cast<int>(
m_roads.size()) - 1);
669 r.setHits(std::move(sorted_hits));
679 r.setHitLayers(hitLayers);
683 r.setFitParams(fittedpars);
685 r.setFitChi2_2d(chi2_phi,chi2_eta);
730 double dr = (
lastpair().second->hitptr->getR() -
pair.first->hitptr->getR()) / 2.0;
732 double newpairextrap =
pair.first->phiShift +
pair.dPhi() /
pair.dR() * dr;
733 return lastpairextrap - newpairextrap;
744 double dr = (
lastpair().second->hitptr->getR() -
pair.first->hitptr->getR()) / 2.0;
746 double newpairextrap =
pair.first->etaShift +
pair.dEta() /
pair.dR() * dr;
747 return lastpairextrap - newpairextrap;
778 double r = std::min(
lastpair().first->hitptr->getR(),
lastpair().second->hitptr->getR());
783 double r = std::max(
lastpair().first->hitptr->getR(),
lastpair().second->hitptr->getR());
792 double N =hits.size();
796 double sum_PhiR2 = 0;
809 double r = hit->hitptr->getR();
813 double dphi = hit->phiShift;
814 double dphi2 = dphi*dphi;
815 double deta = hit->etaShift;
816 double deta2 = deta*deta;
821 sum_PhiR2 += dphi*r2;
837 double r6_t0 = (-sum_R2 * sum_R4 + sum_R3*sum_R3);
838 double r5_t0 = (sum_R*sum_R4 - sum_R2*sum_R3);
839 double r4_t0 = (-sum_R * sum_R3 + sum_R2*sum_R2);
840 double r4_t1 = (-N*sum_R4 + sum_R2*sum_R2);
841 double r3_t0 = (N*sum_R3 - sum_R*sum_R2);
842 double r2_t0 = (-N*sum_R2 + sum_R*sum_R);
845 const double denom_phi = N * r6_t0 + sum_R * r5_t0 + sum_R2 * r4_t0;
846 if (nearZero(denom_phi)){
847 ATH_MSG_ERROR(
"Divide by zero (phi) trapped in FPGATrackSimGenScanTool::fitRoad");
852 std::vector<double> phivars(3);
853 phivars[0] = (sum_Phi*r6_t0 + sum_PhiR*r5_t0 + sum_PhiR2*r4_t0)/denom_phi;
854 phivars[1] = (sum_Phi*r5_t0 + sum_PhiR*r4_t1 + sum_PhiR2*r3_t0)/denom_phi;
855 phivars[2] = (sum_Phi*r4_t0 + sum_PhiR*r3_t0 + sum_PhiR2*r2_t0)/denom_phi;
859 const double denom_eta = N*sum_R2 - sum_R*sum_R;
860 if (nearZero(denom_eta)){
861 ATH_MSG_ERROR(
"Divide by zero (eta) trapped in FPGATrackSimGenScanTool::fitRoad");
865 std::vector<double> etavars(2);
866 etavars[0] = (-sum_R*sum_EtaR + sum_R2*sum_Eta)/denom_eta;
867 etavars[1] = (N*sum_EtaR - sum_R*sum_Eta)/denom_eta;
872 parshift[0] = etavars[0] + etavars[1]*
m_rin;
873 parshift[1]= etavars[0] + etavars[1]*
m_rout;
874 parshift[2]= -(phivars[0]/
m_rin + phivars[1] + phivars[2]*
m_rin) ;
875 parshift[3]= -(phivars[0]/
m_rout + phivars[1] + phivars[2]*
m_rout) ;
877 parshift[4]= -phivars[2]/4.0*
y*
y ;
880 const auto& lastStep =
m_binnedhits->getBinTool().lastStep();
882 parset[par]+=parshift[par];
883 inBin = inBin && (std::abs(parshift[par]) < lastStep->binWidth(par)/2.0);
886 double ec0 = etavars[0];
887 double ec1 = etavars[1];
888 eta_chi2 = sum_Eta2 - 2*ec0*sum_Eta - 2*ec1*sum_EtaR + N*ec0*ec0 + 2*ec0*ec1*sum_R + ec1*ec1*sum_R2;
890 double pc0 = phivars[0];
891 double pc1 = phivars[1];
892 double pc2 = phivars[2];
894 phi_chi2 = sum_Phi2 - 2*pc0*sum_Phi - 2*pc1*sum_PhiR - 2*pc2*sum_PhiR2 + N*pc0*pc0 + 2*pc0*pc1*sum_R + 2*pc0*pc2*sum_R2 + 2*pc1*pc2*sum_R3 + pc1*pc1*sum_R2 + pc2*pc2*sum_R4;
898 double r = hit->hitptr->getR();
899 ATH_MSG_VERBOSE(
"Fitted r= " <<
r <<
" phishift " << hit->phiShift <<
" =?= " << pc0+pc1*
r+pc2*
r*
r <<
" etashift " << hit->etaShift <<
" =?= " << ec0+ec1*
r);
903 ATH_MSG_DEBUG(
"Fitted parset inBin="<< inBin <<
" nhits=" << hits.size() <<
" " << parset <<
" chi2 " << eta_chi2 <<
"," << phi_chi2);
906 trackpars =
m_binnedhits->getBinTool().binDesc()->parSetToTrackPars(parset);
912 chi2 = (hits.size() == 5) ?
922 std::vector<unsigned> toUse;
926 if (hitmask == 0x1f) {
929 else if (hitmask == 0x1e) {
932 else if (hitmask == 0x1d) {
935 else if (hitmask == 0x1b) {
938 else if (hitmask == 0x17) {
941 else if (hitmask == 0x0f) {
948 if (hitmask == 0x1f) {
951 else if (hitmask == 0x1e) {
954 else if (hitmask == 0x1d) {
957 else if (hitmask == 0x1b) {
960 else if (hitmask == 0x17) {
963 else if (hitmask == 0x0f) {
970 if (hitmask == 0x1f) {
973 else if (hitmask == 0x1e) {
976 else if (hitmask == 0x1d) {
979 else if (hitmask == 0x1b) {
982 else if (hitmask == 0x17) {
985 else if (hitmask == 0x0f) {
992 if (hitmask == 0x1f) {
995 else if (hitmask == 0x1e) {
998 else if (hitmask == 0x1d) {
1001 else if (hitmask == 0x1b) {
1004 else if (hitmask == 0x17) {
1007 else if (hitmask == 0x0f) {
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
std::vector< size_t > vec
Binning Utilities for GenScanTool.
This is the monitoring for the FPGATrackSimGenScanTool.
: FPGATrackSim-specific class to represent an hit in the detector.
Maps physical layers to logical layers.
Maps ITK module indices to FPGATrackSim regions.
Structs that store the 5 track parameters.
double chi2(TH1 *h0, TH1 *h1)
void reverse(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of reverse for DataVector/List.
std::shared_ptr< const FPGATrackSimHit > hitptr
std::vector< FPGATrackSimBinUtil::StoredHit > hits
void fill(H5::Group &out_file, size_t iterations)