11 #include "GaudiKernel/MsgStream.h"
12 #include "GaudiKernel/ITHistSvc.h"
39 #include <TDecompLU.h>
41 #define MIN_TRACK_SEC 50 // min number of tracks per sector
46 template<
typename ...Ptr>
48 anyNullPtr(Ptr&&...
p){
49 return ((
p!=
nullptr) && ...) ;
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,-1
e-4,1
e-4);
123 auto h_vd = std::make_unique<TH1F>(
"h_vd",
"h_vd",500,-1
e-2,1
e-2);
124 auto h_vf = std::make_unique<TH1F>(
"h_vf",
"h_vf",500,-1
e-2,1
e-2);
125 auto h_vz = std::make_unique<TH1F>(
"h_vz",
"h_vz",500,-1
e-2,1
e-2);
126 auto h_veta = std::make_unique<TH1F>(
"h_veta",
"h_veta",500,-1
e-2,1
e-2);
133 return StatusCode::SUCCESS;
140 TTree *old_tree = (TTree*)
file->Get(
"slice");
161 old_tree->GetEntry(0);
164 TTree *new_tree =
new TTree(
"slice",
"Slice boundaries");
189 return StatusCode::SUCCESS;
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)
269 std::vector<module_t> & modules =
reader.getModules();
285 if (!success)
continue;
309 unsigned int nusable = acc_norm.
nusable() - 1;
311 coordsToUse[missing] =
false;
315 coordsToUse[missing+1] =
false;
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*{
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))
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;
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++)
553 geo.pars.qOverPt += -
geo.Vcurvature[
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;
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;
741 return StatusCode::SUCCESS;
759 for (
int missing = 0; missing <
m_nLayers; missing++) {
771 return StatusCode::SUCCESS;
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");
824 fclose(sectorHW_file);
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;