11#include "GaudiKernel/MsgStream.h"
12#include "GaudiKernel/ITHistSvc.h"
41#define MIN_TRACK_SEC 50
46 template<
typename ...Ptr>
48 anyNullPtr(Ptr&&...p){
49 return ((p!=
nullptr) && ...) ;
106 std::string tree_name =
"am" + std::to_string(0);
107 std::string tree_title =
"Ambank " + std::to_string(0) +
" matrices";
108 m_good_tree =
new TTree(tree_name.c_str(), tree_title.c_str());
114 return StatusCode::SUCCESS;
122 auto h_vc = std::make_unique<TH1F>(
"h_vc",
"h_vc",500,-1e-4,1e-4);
123 auto h_vd = std::make_unique<TH1F>(
"h_vd",
"h_vd",500,-1e-2,1e-2);
124 auto h_vf = std::make_unique<TH1F>(
"h_vf",
"h_vf",500,-1e-2,1e-2);
125 auto h_vz = std::make_unique<TH1F>(
"h_vz",
"h_vz",500,-1e-2,1e-2);
126 auto h_veta = std::make_unique<TH1F>(
"h_veta",
"h_veta",500,-1e-2,1e-2);
133 return StatusCode::SUCCESS;
140 TTree *old_tree = (TTree*)
file->Get(
"slice");
141 old_tree->SetBranchAddress(
"c_max", &
m_sliceMax.qOverPt);
142 old_tree->SetBranchAddress(
"c_min", &
m_sliceMin.qOverPt);
143 old_tree->SetBranchAddress(
"c_slices", &
m_sliceNBins.qOverPt);
145 old_tree->SetBranchAddress(
"phi_max", &
m_sliceMax.phi);
146 old_tree->SetBranchAddress(
"phi_min", &
m_sliceMin.phi);
147 old_tree->SetBranchAddress(
"phi_slices", &
m_sliceNBins.phi);
149 old_tree->SetBranchAddress(
"d0_max", &
m_sliceMax.d0);
150 old_tree->SetBranchAddress(
"d0_min", &
m_sliceMin.d0);
151 old_tree->SetBranchAddress(
"d0_slices", &
m_sliceNBins.d0);
153 old_tree->SetBranchAddress(
"z0_max", &
m_sliceMax.z0);
154 old_tree->SetBranchAddress(
"z0_min", &
m_sliceMin.z0);
155 old_tree->SetBranchAddress(
"z0_slices", &
m_sliceNBins.z0);
157 old_tree->SetBranchAddress(
"eta_max", &
m_sliceMax.eta);
158 old_tree->SetBranchAddress(
"eta_min", &
m_sliceMin.eta);
159 old_tree->SetBranchAddress(
"eta_slices", &
m_sliceNBins.eta);
161 old_tree->GetEntry(0);
164 TTree *new_tree =
new TTree(
"slice",
"Slice boundaries");
167 new_tree->Branch(
"c_max", &
m_sliceMax.qOverPt);
168 new_tree->Branch(
"c_min", &
m_sliceMin.qOverPt);
189 return StatusCode::SUCCESS;
200 std::string tree_name =
"am" + std::to_string(0);
201 std::string tree_title =
"Ambank " + std::to_string(0) +
" constants";
202 m_ctree =
new TTree(tree_name.c_str(), tree_title.c_str());
210 m_ctree->Branch(
"sectorID", &anInt,
"sectorID[nplane]/I");
211 m_ctree->Branch(
"hashID", &anInt,
"hashID[nplane]/I");
212 m_ctree->Branch(
"nhit", &aFloat,
"nhit/F");
214 m_ctree->Branch(
"Cd", &aDouble,
"Cd/D");
215 m_ctree->Branch(
"Cc", &aDouble,
"Cc/D");
216 m_ctree->Branch(
"Cf", &aDouble,
"Cf/D");
217 m_ctree->Branch(
"Cz0", &aDouble,
"Cz0/D");
218 m_ctree->Branch(
"Co", &aDouble,
"Co/D");
220 m_ctree->Branch(
"Vc", &aDouble,
"Vc[ndim]/D");
221 m_ctree->Branch(
"Vd", &aDouble,
"Vd[ndim]/D");
222 m_ctree->Branch(
"Vf", &aDouble,
"Vf[ndim]/D");
223 m_ctree->Branch(
"Vz0", &aDouble,
"Vz0[ndim]/D");
224 m_ctree->Branch(
"Vo", &aDouble,
"Vo[ndim]/D");
226 m_ctree->Branch(
"kernel", &aDouble,
"kernel[nkernel]/D");
227 m_ctree->Branch(
"kaverages", &aDouble,
"kaverages[nkaverages]/D");
230 return StatusCode::SUCCESS;
239 if (!
file.is_open())
return;
243 while (
file >> sector)
245 if (sector >= nSectors)
264 for (
size_t entry = 0; entry < (size_t)
m_matrix_tree->GetEntries(); entry++)
268 reader.readEntry(entry);
269 std::vector<module_t> & modules = reader.getModules();
275 ATH_MSG_DEBUG(
"Insufficient tracks in sector " << reader.getEntry());
285 if (!success)
continue;
289 writer.fill(modules, acc);
301 int missing =
m_pmap->getCoordOffset(ip);
309 unsigned int nusable = acc_norm.
nusable() - 1;
311 coordsToUse[missing] =
false;
313 if (
m_pmap->getDim(ip) == 2)
315 coordsToUse[missing+1] =
false;
321 bool success =
GetConstants(acc_norm, geo, entry, coordsToUse, nusable);
349 std::vector<double> inv_covariance =
invert(
m_nCoords, mtx_reduced, coordsToUse);
352 std::vector<double> eigvals;
355 eigen(nusable,
m_nCoords, mtx_reduced, coordsToUse, eigvals, eigvecs);
358 geo =
makeConsts(acc_norm, coordsToUse, inv_covariance, eigvals, eigvecs);
371 float coverage =
static_cast<float>(acc.track_bins.size());
372 m_ctree->SetBranchAddress(
"sectorID", acc.FTK_modules.data());
373 m_ctree->SetBranchAddress(
"hashID", modules.data());
374 m_ctree->SetBranchAddress(
"nhit", &coverage);
376 m_ctree->SetBranchAddress(
"Cc", &geo.pars.qOverPt);
377 m_ctree->SetBranchAddress(
"Cd", &geo.pars.d0);
378 m_ctree->SetBranchAddress(
"Cf", &geo.pars.phi);
379 m_ctree->SetBranchAddress(
"Cz0", &geo.pars.z0);
380 m_ctree->SetBranchAddress(
"Co", &geo.pars.eta);
382 m_ctree->SetBranchAddress(
"Vc", geo.Vcurvature.data());
383 m_ctree->SetBranchAddress(
"Vd", geo.Vd0.data());
384 m_ctree->SetBranchAddress(
"Vf", geo.Vphi.data());
385 m_ctree->SetBranchAddress(
"Vz0", geo.Vz0.data());
386 m_ctree->SetBranchAddress(
"Vo", geo.Veta.data());
388 m_ctree->SetBranchAddress(
"kaverages", geo.kaverages.data());
389 m_ctree->SetBranchAddress(
"kernel", geo.kernel.data());
395 const std::string prefix{
"/TRIGFPGATrackSimTREEGOODOUT/"};
396 auto getHistogram = [&](
const std::string & suffix)->TH1*{
398 const auto sc =
m_tHistSvc->getHist(prefix+suffix, ptr);
399 return (
sc == StatusCode::SUCCESS) ? ptr:
nullptr;
401 auto h_vc = getHistogram(
"h_vc");
402 auto h_vd = getHistogram(
"h_vd");
403 auto h_vf = getHistogram(
"h_vf");
404 auto h_vz = getHistogram(
"h_vz");
405 auto h_veta = getHistogram(
"h_veta");
406 if (anyNullPtr(h_vc, h_vd, h_vf, h_vz, h_veta)){
407 ATH_MSG_ERROR(
"FPGATrackSimConstGenAlgo::fillConstTree; nullptr");
412 h_vc->Fill(geo.Vcurvature[i]);
413 h_vd->Fill(geo.Vd0[i]);
414 h_vf->Fill(geo.Vphi[i]);
415 h_vz->Fill(geo.Vz0[i]);
416 h_veta->Fill(geo.Veta[i]);
424 if (TMath::IsNaN(value))
432#define CHECK_NAN(var) (isNAN((var), #var))
440 if (
CHECK_NAN(geo.pars.qOverPt))
return true;
444 if (
CHECK_NAN(geo.pars.phi))
return true;
448 if (
CHECK_NAN(geo.pars.eta))
return true;
453 if (
CHECK_NAN(geo.Vcurvature[i]))
return true;
466 if (
CHECK_NAN(geo.kaverages[i]))
return true;
468 if (
CHECK_NAN(geo.kernel(i,j)))
return true;
489 double coverage =
static_cast<double>(acc.track_bins.size());
490 size_t nCoords = acc.hit_coords.size();
493 acc.pars[i] /= coverage;
495 for (
unsigned i = 0; i < nCoords; i++)
497 acc.hit_coords[i] /= coverage;
498 if (std::abs(acc.hit_coords[i]) <
MTX_TOLERANCE) acc.coords_usable[i] =
false;
499 else acc.coords_usable[i] =
true;
503 for (
unsigned i = 0; i < nCoords; i++)
505 acc.hit_x_QoP[i] = (acc.hit_x_QoP[i] - acc.hit_coords[i] * acc.pars.qOverPt * coverage) / (coverage-1);
506 acc.hit_x_d0[i] = (acc.hit_x_d0[i] - acc.hit_coords[i] * acc.pars.d0 * coverage) / (coverage-1);
507 acc.hit_x_z0[i] = (acc.hit_x_z0[i] - acc.hit_coords[i] * acc.pars.z0 * coverage) / (coverage-1);
508 acc.hit_x_phi[i] = (acc.hit_x_phi[i] - acc.hit_coords[i] * acc.pars.phi * coverage) / (coverage-1);
509 acc.hit_x_eta[i] = (acc.hit_x_eta[i] - acc.hit_coords[i] * acc.pars.eta * coverage) / (coverage-1);
512 for (
unsigned j = i ; j < nCoords; ++j)
514 acc.covariance[j * nCoords + i] = acc.covariance[i * nCoords + j] =
515 (acc.covariance[i * nCoords + j] - acc.hit_coords[i] * acc.hit_coords[j] * coverage) / (coverage-1);
524 std::vector<double>
const & inv_covariance,
527 size_t nCoords = acc.hit_coords.size();
538 if (!usable[i])
continue;
539 for (
size_t j = 0; j < nCoords; j++)
541 if (!usable[j])
continue;
543 geo.kernel(i, j) = eigvecs(i, j) / sqrt(eigvals[i]);
545 geo.kaverages[i] += -geo.kernel(i, j) * acc.hit_coords[j];
550 for (
size_t i = 0; i < nCoords; i++)
552 geo.pars.d0 += -geo.Vd0[i] * acc.hit_coords[i];
553 geo.pars.qOverPt += -geo.Vcurvature[i] * acc.hit_coords[i];
554 geo.pars.phi += -geo.Vphi[i] * acc.hit_coords[i];
555 geo.pars.z0 += -geo.Vz0[i] * acc.hit_coords[i];
556 geo.pars.eta += -geo.Veta[i] * acc.hit_coords[i];
559 geo.real =
static_cast<int>(acc.track_bins.size());
574 std::vector<double>
x(n);
576 for (
size_t i = 0; i < n; i++)
577 for (
size_t j = 0; j < n; j++)
578 x[i] +=
A[i * n + j] * b[j];
602 TMatrixD mtx(n, n, mtx_v.data());
603 TMatrixD newmtx(nDimToUse, nDimToUse);
606 for (
size_t i = 0; i < n; i++)
608 if (!usable[i])
continue;
611 for (
size_t j = 0; j < n; j++)
613 if (!usable[j])
continue;
614 newmtx[counteri][counterj] = mtx[i][j];
617 assert(counterj == nDimToUse);
620 assert(counteri == nDimToUse);
636 std::vector<double> inv(n_full * n_full);
641 for (
size_t i = 0; i < n_full; i++)
643 if (!usable[i])
continue;
646 for (
size_t j = 0; j < n_full; j++)
648 if (!usable[j])
continue;
649 inv[i*n_full + j] = mtx[counteri][counterj];
676 TVectorD eigvals_redu;
677 TMatrixD eigvecs_redu = mtx.EigenVectors(eigvals_redu);
680 eigvals_full.resize(n_full, 0);
681 eigvecs_full.
resize(n_full, n_full, 0);
685 size_t j_redu = n_redu - 1;
686 for (
size_t i_full = 0; i_full < n_full; i_full++)
688 if (!usable[i_full])
continue;
691 for (
size_t j_full = 0; j_full < n_full; j_full++)
693 if (!usable[j_full])
continue;
694 eigvecs_full(i_full, j_full) = eigvecs_redu[i_redu][j_redu];
697 eigvals_full[i_full] = eigvals_redu[j_redu];
706 for (
size_t i = 0; i < size; i++)
707 total += vec1[i] * vec2[i];
716 if (!usable[i])
continue;
717 double norm =
dot(geo.kernel[i], geo.kernel[i], nCoords);
719 auto project = [&](std::vector<double> & hit_x_par,
double & par)
721 double pr =
dot(hit_x_par.data(), geo.kernel[i], nCoords) / norm;
722 for (
int j = 0; j < nCoords; j++) hit_x_par[j] += -geo.kernel(i,j) * pr;
723 par += -geo.kaverages[i] * pr;
727 project(geo.Vcurvature, geo.pars.qOverPt);
728 project(geo.Vphi, geo.pars.phi);
730 project(geo.Veta, geo.pars.eta);
741 return StatusCode::SUCCESS;
759 for (
int missing = 0; missing <
m_nLayers; missing++) {
760 filename =
"corrgen_raw_" + std::to_string(
m_nLayers) +
"L_reg" + std::to_string(
m_region) +
"_checkGood" + std::to_string(
m_CheckGood2ndStage) +
"_skipPlane" + std::to_string(missing) +
".gcon";
771 return StatusCode::SUCCESS;
784 std::string sectorHW_filename =
"sectorsHW_raw_" + std::to_string(
m_nLayers) +
"L_reg" + std::to_string(
m_region) +
"_checkGood" + std::to_string(
m_CheckGood2ndStage) +
".patt";
785 FILE *sector_file = fopen(sector_filename.c_str(),
"w");
787 ATH_MSG_ERROR(
"Cannot open output file " << sector_filename);
788 return StatusCode::FAILURE;
790 FILE *sectorHW_file = fopen(sectorHW_filename.c_str(),
"w");
791 if (!sectorHW_file) {
792 ATH_MSG_ERROR(
"Cannot open output file " << sectorHW_filename);
793 fclose (sector_file);
794 return StatusCode::FAILURE;
802 while (reader.nextEntry())
805 size_t sector = reader.getEntry();
807 fprintf(sector_file,
"%zu ", sector);
808 fprintf(sectorHW_file,
"%zu ", sector);
811 fprintf(sector_file,
"%d ", acc.FTK_modules[i]);
812 fprintf(sectorHW_file,
"%d ", reader.getModules()[i]);
814 fprintf(sector_file,
"0 %zu", acc.track_bins.size());
815 fprintf(sector_file,
"\n");
816 fprintf(sectorHW_file,
"0 %zu", acc.track_bins.size());
817 fprintf(sectorHW_file,
"\n");
820 slice.addSectorToSlice(sector, pars);
824 fclose(sectorHW_file);
825 std::string slice_filename =
"slices_" + std::to_string(
m_nLayers) +
"L_reg" + std::to_string(
m_region) +
".root";
826 slice.saveSlices(slice_filename);
828 return StatusCode::SUCCESS;
835 FILE *const_file = fopen(filename.c_str(),
"w");
838 return StatusCode::FAILURE;
841 fprintf(const_file,
"! *** RECONSTRUCTION GEOMETRY CONSTANTS ***\n");
842 fprintf(const_file,
"\n");
843 fprintf(const_file,
"Version 2 ! File format version number\n");
844 fprintf(const_file,
"\n");
845 fprintf(const_file,
"! *** PHI is now in GLOBAL coordinate system ***\n");
846 fprintf(const_file,
" NPLANES\n");
848 fprintf(const_file,
" NSECTORS\n");
849 fprintf(const_file,
"%zu\n",geo_consts.size());
850 fprintf(const_file,
" NDIM\n");
851 fprintf(const_file,
" 2\n");
855 for (
size_t sector = 0; sector < geo_consts.size(); sector++)
858 fprintf(const_file,
"sector\n");
859 fprintf(const_file,
"%zu\n", sector);
861 fprintf(const_file,
" Vc \n");
863 fprintf(const_file,
"%e\n",geo_consts[sector].Vcurvature[i]);
866 fprintf(const_file,
" Vd \n");
868 fprintf(const_file,
"%e\n",geo_consts[sector].Vd0[i]);
871 fprintf(const_file,
" Vf \n");
873 fprintf(const_file,
"%e\n",geo_consts[sector].Vphi[i]);
876 fprintf(const_file,
" Vz0 \n");
878 fprintf(const_file,
"%e\n",geo_consts[sector].Vz0[i]);
881 fprintf(const_file,
" Vo \n");
883 fprintf(const_file,
"%e\n",geo_consts[sector].Veta[i]);
886 fprintf(const_file,
"kaverages\n");
888 fprintf(const_file,
"%e\n",
m_geo_consts[sector].kaverages[i]);
891 fprintf(const_file,
"kernel\n");
894 fprintf(const_file,
"%e\n",geo_consts[sector].kernel(i, j));
898 fprintf(const_file,
"Cc\n");
899 fprintf(const_file,
"%e\n",geo_consts[sector].pars.qOverPt);
901 fprintf(const_file,
"Cd\n");
902 fprintf(const_file,
"%e\n",geo_consts[sector].pars.d0);
904 fprintf(const_file,
"Cf\n");
905 fprintf(const_file,
"%e\n",geo_consts[sector].pars.phi);
907 fprintf(const_file,
"Cz0\n");
908 fprintf(const_file,
"%e\n",geo_consts[sector].pars.z0);
910 fprintf(const_file,
"Co\n");
911 fprintf(const_file,
"%e\n",geo_consts[sector].pars.eta);
916 return StatusCode::SUCCESS;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
Algorithm to generate fit constants.
Classes to read/write matrix files event by event.
Maps physical layers to logical layers.
Stores the range of eta/phi/etc. of each sector.
T_ResultType project(ParameterMapping::type< N > parameter_map, const T_Matrix &matrix)
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
Gaudi::Property< int > m_region
bool isSingular(TMatrixD mtx)
ServiceHandle< IFPGATrackSimEventSelectionSvc > m_EvtSel
StatusCode execute() override
ServiceHandle< ITHistSvc > m_tHistSvc
std::vector< std::vector< geo_constants > > m_geo_consts_with_missinghit
geo_constants calculate_gcorth(geo_constants geo, int nCoords, std::vector< bool > const &usable)
bool isNAN(double value, const char *name)
FPGATrackSimTrackPars m_sliceMin
StatusCode writeSectors()
double dot(const double *vec1, const double *vec2, size_t size)
Gaudi::Property< std::string > m_skipFile
StatusCode prepareOutputTree()
TMatrixD getReducedMatrix(size_t n, std::vector< double > const &mtx_v, std::vector< bool > const &usable, size_t nDimToUse)
Removes the rows/columns specified by !usable.
std::vector< double > matrix_multiply(std::vector< double > const &A, std::vector< double > const &b)
std::vector< bool > m_skipList
void eigen(size_t n_redu, size_t n_full, TMatrixD &mtx, std::vector< bool > const &usable, std::vector< double > &eigvals_v, vector2D< double > &eigvecs_v)
FPGATrackSimTrackParsI m_sliceNBins
std::vector< geo_constants > m_geo_consts
void readSkipList(size_t nEntries)
Gaudi::Property< bool > m_dumpMissingHitsConstants
FPGATrackSimMatrixAccumulator normalize(FPGATrackSimMatrixAccumulator const &acc_raw)
bool GetConstants(FPGATrackSimMatrixAccumulator const &acc_norm, geo_constants &geo, int entryNumber)
geo_constants makeConsts(FPGATrackSimMatrixAccumulator const &acc, std::vector< bool > const &usable, std::vector< double > const &inv_covariance, std::vector< double > const &eigvals, vector2D< double > const &eigvecs)
FPGATrackSimConstGenAlgo(const std::string &name, ISvcLocator *pSvcLocator)
StatusCode bookHistograms()
void createMissingHitsConstants(FPGATrackSimMatrixAccumulator const &acc_norm, size_t entry)
std::vector< double > invert(size_t n_full, TMatrixD mtx, std::vector< bool > const &usable)
Inverts a reduced matrix, then pads with zeros to recover a full-sized matrix.
Gaudi::Property< bool > m_Monitor
StatusCode initialize() override
StatusCode copySliceTree(TFile *file)
Gaudi::Property< bool > m_isSecondStage
StatusCode DumpConstants(std::vector< geo_constants > &geo_consts, std::string &filename)
const FPGATrackSimPlaneMap * m_pmap
Gaudi::Property< std::string > m_cfpath
Gaudi::Property< bool > m_CheckGood2ndStage
FPGATrackSimTrackPars m_sliceMax
ServiceHandle< IFPGATrackSimMappingSvc > m_FPGATrackSimMapping
void fillConstTree(std::vector< module_t > &modules, FPGATrackSimMatrixAccumulator &acc, geo_constants &geo)
bool failedConstants(geo_constants const &geo, std::vector< bool > const &usable)
StatusCode finalize() override
void generate_constants()
void resize(size_t x1, size_t x2, T const &t=T())
int count(std::string s, const std::string ®x)
count how many occurances of a regx are in a string
hold the test vectors and ease the comparison
std::vector< double > covariance
std::vector< bool > coords_usable