11 #include "GaudiKernel/MsgStream.h"
12 #include "GaudiKernel/ITHistSvc.h"
37 #include <TDecompLU.h>
39 #define MIN_TRACK_SEC 50 // min number of tracks per sector
44 template<
typename ...Ptr>
46 anyNullPtr(Ptr&&...
p){
47 return ((
p!=
nullptr) && ...) ;
105 std::string tree_title =
"Ambank " +
std::to_string(0) +
" matrices";
106 m_good_tree =
new TTree(tree_name.c_str(), tree_title.c_str());
112 return StatusCode::SUCCESS;
120 auto h_vc = std::make_unique<TH1F>(
"h_vc",
"h_vc",500,-1
e-4,1
e-4);
121 auto h_vd = std::make_unique<TH1F>(
"h_vd",
"h_vd",500,-1
e-2,1
e-2);
122 auto h_vf = std::make_unique<TH1F>(
"h_vf",
"h_vf",500,-1
e-2,1
e-2);
123 auto h_vz = std::make_unique<TH1F>(
"h_vz",
"h_vz",500,-1
e-2,1
e-2);
124 auto h_veta = std::make_unique<TH1F>(
"h_veta",
"h_veta",500,-1
e-2,1
e-2);
131 return StatusCode::SUCCESS;
138 TTree *old_tree = (TTree*)
file->Get(
"slice");
159 old_tree->GetEntry(0);
162 TTree *new_tree =
new TTree(
"slice",
"Slice boundaries");
187 return StatusCode::SUCCESS;
199 std::string tree_title =
"Ambank " +
std::to_string(0) +
" constants";
200 m_ctree =
new TTree(tree_name.c_str(), tree_title.c_str());
208 m_ctree->Branch(
"sectorID", &anInt,
"sectorID[nplane]/I");
209 m_ctree->Branch(
"hashID", &anInt,
"hashID[nplane]/I");
210 m_ctree->Branch(
"nhit", &aFloat,
"nhit/F");
212 m_ctree->Branch(
"Cd", &aDouble,
"Cd/D");
213 m_ctree->Branch(
"Cc", &aDouble,
"Cc/D");
214 m_ctree->Branch(
"Cf", &aDouble,
"Cf/D");
215 m_ctree->Branch(
"Cz0", &aDouble,
"Cz0/D");
216 m_ctree->Branch(
"Co", &aDouble,
"Co/D");
218 m_ctree->Branch(
"Vc", &aDouble,
"Vc[ndim]/D");
219 m_ctree->Branch(
"Vd", &aDouble,
"Vd[ndim]/D");
220 m_ctree->Branch(
"Vf", &aDouble,
"Vf[ndim]/D");
221 m_ctree->Branch(
"Vz0", &aDouble,
"Vz0[ndim]/D");
222 m_ctree->Branch(
"Vo", &aDouble,
"Vo[ndim]/D");
224 m_ctree->Branch(
"kernel", &aDouble,
"kernel[nkernel]/D");
225 m_ctree->Branch(
"kaverages", &aDouble,
"kaverages[nkaverages]/D");
228 return StatusCode::SUCCESS;
237 if (!
file.is_open())
return;
241 while (
file >> sector)
243 if (sector >= nSectors)
267 std::vector<module_t> & modules =
reader.getModules();
283 if (!success)
continue;
307 unsigned int nusable = acc_norm.
nusable() - 1;
309 coordsToUse[missing] =
false;
313 coordsToUse[missing+1] =
false;
347 std::vector<double> inv_covariance =
invert(
m_nCoords, mtx_reduced, coordsToUse);
350 std::vector<double> eigvals;
353 eigen(nusable,
m_nCoords, mtx_reduced, coordsToUse, eigvals, eigvecs);
356 geo =
makeConsts(acc_norm, coordsToUse, inv_covariance, eigvals, eigvecs);
369 float coverage =
static_cast<float>(
acc.track_bins.size());
370 m_ctree->SetBranchAddress(
"sectorID",
acc.FTK_modules.data());
371 m_ctree->SetBranchAddress(
"hashID", modules.data());
372 m_ctree->SetBranchAddress(
"nhit", &coverage);
374 m_ctree->SetBranchAddress(
"Cc", &
geo.pars.qOverPt);
375 m_ctree->SetBranchAddress(
"Cd", &
geo.pars.d0);
376 m_ctree->SetBranchAddress(
"Cf", &
geo.pars.phi);
377 m_ctree->SetBranchAddress(
"Cz0", &
geo.pars.z0);
378 m_ctree->SetBranchAddress(
"Co", &
geo.pars.eta);
380 m_ctree->SetBranchAddress(
"Vc",
geo.Vcurvature.data());
381 m_ctree->SetBranchAddress(
"Vd",
geo.Vd0.data());
382 m_ctree->SetBranchAddress(
"Vf",
geo.Vphi.data());
383 m_ctree->SetBranchAddress(
"Vz0",
geo.Vz0.data());
384 m_ctree->SetBranchAddress(
"Vo",
geo.Veta.data());
386 m_ctree->SetBranchAddress(
"kaverages",
geo.kaverages.data());
387 m_ctree->SetBranchAddress(
"kernel",
geo.kernel.data());
393 const std::string
prefix{
"/TRIGFPGATrackSimTREEGOODOUT/"};
394 auto getHistogram = [&](
const std::string &
suffix)->TH1*{
397 return (
sc == StatusCode::SUCCESS) ?
ptr:
nullptr;
399 auto h_vc = getHistogram(
"h_vc");
400 auto h_vd = getHistogram(
"h_vd");
401 auto h_vf = getHistogram(
"h_vf");
402 auto h_vz = getHistogram(
"h_vz");
403 auto h_veta = getHistogram(
"h_veta");
404 if (anyNullPtr(h_vc, h_vd, h_vf, h_vz, h_veta)){
405 ATH_MSG_ERROR(
"FPGATrackSimConstGenAlgo::fillConstTree; nullptr");
410 h_vc->Fill(
geo.Vcurvature[
i]);
411 h_vd->Fill(
geo.Vd0[
i]);
412 h_vf->Fill(
geo.Vphi[
i]);
413 h_vz->Fill(
geo.Vz0[
i]);
414 h_veta->Fill(
geo.Veta[
i]);
422 if (TMath::IsNaN(
value))
430 #define CHECK_NAN(var) (isNAN((var), #var))
487 double coverage =
static_cast<double>(
acc.track_bins.size());
488 size_t nCoords =
acc.hit_coords.size();
491 acc.pars[
i] /= coverage;
493 for (
unsigned i = 0;
i < nCoords;
i++)
495 acc.hit_coords[
i] /= coverage;
497 else acc.coords_usable[
i] =
true;
501 for (
unsigned i = 0;
i < nCoords;
i++)
503 acc.hit_x_QoP[
i] = (
acc.hit_x_QoP[
i] -
acc.hit_coords[
i] *
acc.pars.qOverPt * coverage) / (coverage-1);
504 acc.hit_x_d0[
i] = (
acc.hit_x_d0[
i] -
acc.hit_coords[
i] *
acc.pars.d0 * coverage) / (coverage-1);
505 acc.hit_x_z0[
i] = (
acc.hit_x_z0[
i] -
acc.hit_coords[
i] *
acc.pars.z0 * coverage) / (coverage-1);
506 acc.hit_x_phi[
i] = (
acc.hit_x_phi[
i] -
acc.hit_coords[
i] *
acc.pars.phi * coverage) / (coverage-1);
507 acc.hit_x_eta[
i] = (
acc.hit_x_eta[
i] -
acc.hit_coords[
i] *
acc.pars.eta * coverage) / (coverage-1);
510 for (
unsigned j =
i ; j < nCoords; ++j)
512 acc.covariance[j * nCoords +
i] =
acc.covariance[
i * nCoords + j] =
513 (
acc.covariance[
i * nCoords + j] -
acc.hit_coords[
i] *
acc.hit_coords[j] * coverage) / (coverage-1);
522 std::vector<double>
const & inv_covariance,
525 size_t nCoords =
acc.hit_coords.size();
536 if (!usable[
i])
continue;
537 for (
size_t j = 0; j < nCoords; j++)
539 if (!usable[j])
continue;
541 geo.kernel(
i, j) = eigvecs(
i, j) / sqrt(eigvals[
i]);
543 geo.kaverages[
i] += -
geo.kernel(
i, j) *
acc.hit_coords[j];
548 for (
size_t i = 0;
i < nCoords;
i++)
551 geo.pars.qOverPt += -
geo.Vcurvature[
i] *
acc.hit_coords[
i];
557 geo.real =
static_cast<int>(
acc.track_bins.size());
572 std::vector<double>
x(
n);
574 for (
size_t i = 0;
i <
n;
i++)
575 for (
size_t j = 0; j <
n; j++)
576 x[
i] +=
A[
i *
n + j] *
b[j];
600 TMatrixD mtx(
n,
n, mtx_v.data());
601 TMatrixD newmtx(nDimToUse, nDimToUse);
604 for (
size_t i = 0;
i <
n;
i++)
606 if (!usable[
i])
continue;
609 for (
size_t j = 0; j <
n; j++)
611 if (!usable[j])
continue;
612 newmtx[counteri][counterj] = mtx[
i][j];
615 assert(counterj == nDimToUse);
618 assert(counteri == nDimToUse);
634 std::vector<double> inv(n_full * n_full);
639 for (
size_t i = 0;
i < n_full;
i++)
641 if (!usable[
i])
continue;
644 for (
size_t j = 0; j < n_full; j++)
646 if (!usable[j])
continue;
647 inv[
i*n_full + j] = mtx[counteri][counterj];
674 TVectorD eigvals_redu;
675 TMatrixD eigvecs_redu = mtx.EigenVectors(eigvals_redu);
678 eigvals_full.resize(n_full, 0);
679 eigvecs_full.
resize(n_full, n_full, 0);
683 size_t j_redu = n_redu - 1;
684 for (
size_t i_full = 0; i_full < n_full; i_full++)
686 if (!usable[i_full])
continue;
689 for (
size_t j_full = 0; j_full < n_full; j_full++)
691 if (!usable[j_full])
continue;
692 eigvecs_full(i_full, j_full) = eigvecs_redu[i_redu][j_redu];
695 eigvals_full[i_full] = eigvals_redu[j_redu];
704 for (
size_t i = 0;
i <
size;
i++)
705 total += vec1[
i] *
vec2[
i];
714 if (!usable[
i])
continue;
717 auto project = [&](std::vector<double> & hit_x_par,
double &
par)
719 double pr =
dot(hit_x_par.data(),
geo.kernel[
i], nCoords) /
norm;
720 for (
int j = 0; j < nCoords; j++) hit_x_par[j] += -
geo.kernel(
i,j) *
pr;
739 return StatusCode::SUCCESS;
757 for (
int missing = 0; missing <
m_nLayers; missing++) {
769 return StatusCode::SUCCESS;
783 FILE *sector_file = fopen(sector_filename.c_str(),
"w");
784 FILE *sectorHW_file = fopen(sectorHW_filename.c_str(),
"w");
791 while (
reader.nextEntry())
794 size_t sector =
reader.getEntry();
796 fprintf(sector_file,
"%zu ", sector);
797 fprintf(sectorHW_file,
"%zu ", sector);
800 fprintf(sector_file,
"%d ",
acc.FTK_modules[
i]);
801 fprintf(sectorHW_file,
"%d ",
reader.getModules()[
i]);
803 fprintf(sector_file,
"0 %zu",
acc.track_bins.size());
804 fprintf(sector_file,
"\n");
805 fprintf(sectorHW_file,
"0 %zu",
acc.track_bins.size());
806 fprintf(sectorHW_file,
"\n");
813 fclose(sectorHW_file);
815 slice.saveSlices(slice_filename);
822 FILE *const_file = fopen(
filename.c_str(),
"w");
824 fprintf(const_file,
"! *** RECONSTRUCTION GEOMETRY CONSTANTS ***\n");
825 fprintf(const_file,
"\n");
826 fprintf(const_file,
"Version 2 ! File format version number\n");
827 fprintf(const_file,
"\n");
828 fprintf(const_file,
"! *** PHI is now in GLOBAL coordinate system ***\n");
829 fprintf(const_file,
" NPLANES\n");
831 fprintf(const_file,
" NSECTORS\n");
832 fprintf(const_file,
"%zu\n",geo_consts.size());
833 fprintf(const_file,
" NDIM\n");
834 fprintf(const_file,
" 2\n");
838 for (
size_t sector = 0; sector < geo_consts.size(); sector++)
841 fprintf(const_file,
"sector\n");
842 fprintf(const_file,
"%zu\n", sector);
844 fprintf(const_file,
" Vc \n");
846 fprintf(const_file,
"%e\n",geo_consts[sector].Vcurvature[
i]);
849 fprintf(const_file,
" Vd \n");
851 fprintf(const_file,
"%e\n",geo_consts[sector].Vd0[
i]);
854 fprintf(const_file,
" Vf \n");
856 fprintf(const_file,
"%e\n",geo_consts[sector].Vphi[
i]);
859 fprintf(const_file,
" Vz0 \n");
861 fprintf(const_file,
"%e\n",geo_consts[sector].Vz0[
i]);
864 fprintf(const_file,
" Vo \n");
866 fprintf(const_file,
"%e\n",geo_consts[sector].Veta[
i]);
869 fprintf(const_file,
"kaverages\n");
871 fprintf(const_file,
"%e\n",
m_geo_consts[sector].kaverages[
i]);
874 fprintf(const_file,
"kernel\n");
877 fprintf(const_file,
"%e\n",geo_consts[sector].kernel(
i, j));
881 fprintf(const_file,
"Cc\n");
882 fprintf(const_file,
"%e\n",geo_consts[sector].
pars.qOverPt);
884 fprintf(const_file,
"Cd\n");
885 fprintf(const_file,
"%e\n",geo_consts[sector].
pars.d0);
887 fprintf(const_file,
"Cf\n");
888 fprintf(const_file,
"%e\n",geo_consts[sector].
pars.phi);
890 fprintf(const_file,
"Cz0\n");
891 fprintf(const_file,
"%e\n",geo_consts[sector].
pars.z0);
893 fprintf(const_file,
"Co\n");
894 fprintf(const_file,
"%e\n",geo_consts[sector].
pars.eta);