21#include "GaudiKernel/ITHistSvc.h"
42 coerceToIntRange(
double v){
43 constexpr double minint = std::numeric_limits<int>::min();
44 constexpr double maxint = std::numeric_limits<int>::max();
45 auto d = std::clamp(v, minint, maxint);
47 return {
static_cast<int>(
d), d != v};
53 const std::array<std::regex, NnClusterizationFactory::kNNetworkTypes>
55 std::regex(
"^NumberParticles(|/|_.*)$"),
56 std::regex(
"^ImpactPoints([0-9])P(|/|_.*)$"),
57 std::regex(
"^ImpactPointErrorsX([0-9])(|/|_.*)$"),
58 std::regex(
"^ImpactPointErrorsY([0-9])(|/|_.*)$"),
62 const std::string& n,
const IInterface* p)
64 declareInterface<NnClusterizationFactory>(
this);
82 std::smatch match_result;
83 for(
const std::string &nn_name :
m_nnOrder) {
85 for (
unsigned int network_i=0; network_i<
kNNetworkTypes; ++network_i) {
86 if (std::regex_match( nn_name, match_result,
m_nnNames[network_i])) {
92 ATH_MSG_ERROR(
"Regex and match group of particle multiplicity do not coincide (groups=" << match_result.size()
94 <<
"; type=" << network_i <<
")");
97 if (n_particles<=0 or
static_cast<unsigned int>(n_particles)>
m_maxSubClusters) {
100 return StatusCode::FAILURE;
102 if (
static_cast<unsigned int>(n_particles)>=
m_NNId[network_i-1].size()) {
103 m_NNId[network_i-1].resize( n_particles );
105 m_NNId[network_i-1][n_particles-1] = nn_id;
108 m_NNId[network_i-1].resize(1);
110 m_NNId[network_i-1][0] = nn_id;
119 ATH_MSG_ERROR(
"No NN specified to estimate the number of particles.");
120 return StatusCode::FAILURE;
124 unsigned int type_i=0;
125 for (std::vector<unsigned int> &nn_id :
m_NNId) {
129 return StatusCode::FAILURE;
133 return StatusCode::FAILURE;
135 unsigned int n_particles=0;
136 for (
unsigned int &a_nn_id : nn_id ) {
138 if ((a_nn_id==0) or (a_nn_id>
m_nnOrder.size())) {
140 return StatusCode::FAILURE;
149 return StatusCode::SUCCESS;
156 const auto invalidValue{std::numeric_limits<double>::quiet_NaN()};
157 std::vector<double> inputData(vectorSize, invalidValue);
158 size_t vectorIndex{0};
159 for (
unsigned int u=0;u<
m_sizeX;u++){
160 for (
unsigned int s=0;s<
m_sizeY;s++){
161 inputData[vectorIndex++] = input.matrixOfToT[u][s];
164 for (
unsigned int s=0;s<
m_sizeY;s++){
165 inputData[vectorIndex++] = input.vectorOfPitchesY[s];
167 inputData[vectorIndex++] = input.ClusterPixLayer;
168 inputData[vectorIndex++] = input.ClusterPixBarrelEC;
169 inputData[vectorIndex++] = input.phi;
170 inputData[vectorIndex++] = input.theta;
171 if (not input.useTrackInfo) inputData[vectorIndex] = input.etaModule;
178 const auto invalidValue{std::numeric_limits<double>::quiet_NaN()};
179 std::vector<double> inputData(vectorSize, invalidValue);
180 size_t vectorIndex{0};
181 for (
unsigned int u=0;u<
m_sizeX;u++){
182 for (
unsigned int s=0;s<
m_sizeY;s++){
184 inputData[vectorIndex++] =
norm_rawToT(input.matrixOfToT[u][s]);
186 inputData[vectorIndex++] =
norm_ToT(input.matrixOfToT[u][s]);
190 for (
unsigned int s=0;s<
m_sizeY;s++){
191 const double rawPitch(input.vectorOfPitchesY[s]);
193 if (std::isnan(normPitch)){
196 inputData[vectorIndex++] = normPitch;
199 inputData[vectorIndex++] =
norm_layerType(input.ClusterPixBarrelEC);
200 if (input.useTrackInfo){
201 inputData[vectorIndex++] =
norm_phi(input.phi);
202 inputData[vectorIndex] =
norm_theta(input.theta);
204 inputData[vectorIndex++] =
norm_phiBS(input.phi);
220 Eigen::VectorXd valuesVector( vecSize );
226 for (
const auto & xvec: input.matrixOfToT){
227 for (
const auto & xyElement : xvec){
228 valuesVector[location++] = xyElement;
231 for (
const auto & pitch : input.vectorOfPitchesY) {
232 valuesVector[location++] = pitch;
234 valuesVector[location] = input.ClusterPixLayer;
236 valuesVector[location] = input.ClusterPixBarrelEC;
238 valuesVector[location] = input.phi;
240 valuesVector[location] = input.theta;
242 if (!input.useTrackInfo) {
243 valuesVector[location] = input.etaModule;
248 std::vector<Eigen::VectorXd> vectorOfEigen;
249 vectorOfEigen.push_back(valuesVector);
250 return vectorOfEigen;
258 if (!input)
return {};
264 if (!nn_collection.
isValid()) {
283 if (!input)
return {};
290 if (!nn_collection.
isValid()) {
303 const std::vector<double>& inputData)
const{
305 std::vector<double> resultNN_TTN{};
312 ATH_MSG_FATAL(
"NnClusterizationFactory::estimateNumberOfParticlesTTN: nullptr returned for TrainedNetwork");
317 ATH_MSG_VERBOSE(
" TTN Prob of n. particles (1): " << resultNN_TTN[0] <<
318 " (2): " << resultNN_TTN[1] <<
319 " (3): " << resultNN_TTN[2]);
326 std::vector<double>
result(3,0.0);
328 if (!lwtnn_collection.
isValid()) {
332 if (lwtnn_collection->empty()){
339 Eigen::VectorXd discriminant = lwtnn_collection->at(0)->compute(input);
340 const double & num0 = discriminant[0];
341 const double & num1 = discriminant[1];
342 const double & num2 = discriminant[2];
344 const auto inverseSum = 1./(num0+num1+num2);
345 result[0] = num0 * inverseSum;
346 result[1] = num1 * inverseSum;
347 result[2] = num2 * inverseSum;
355 std::vector<Amg::Vector2D>
358 std::vector<Amg::MatrixX> & errors,
359 int numberSubClusters)
const{
371 if (!nn_collection.
isValid()) {
376 return estimatePositionsTTN(**nn_collection, inputData,input,pCluster,numberSubClusters,errors);
384 std::vector<Amg::Vector2D>
388 std::vector<Amg::MatrixX> & errors,
389 int numberSubClusters)
const{
394 if (!input)
return {};
401 if (!nn_collection.
isValid()) {
405 return estimatePositionsTTN(**nn_collection, inputData,input,pCluster,numberSubClusters,errors);
412 std::vector<Amg::Vector2D>
414 const std::vector<double>& inputData,
417 int numberSubClusters,
418 std::vector<Amg::MatrixX> & errors)
const{
420 std::vector<Amg::Vector2D> allPositions{};
421 const auto endNnIdx = nn_collection.size();
422 if (numberSubClusters>0 and
static_cast<unsigned int>(numberSubClusters) <
m_maxSubClusters) {
423 const auto subClusterIndex = numberSubClusters-1;
428 if (not(networkIndex < endNnIdx)){
429 ATH_MSG_FATAL(
"estimatePositionsTTN: Requested collection index, "<< networkIndex <<
" is out of range.");
432 auto *
const pNetwork = nn_collection[networkIndex].get();
435 assert( position1P.size() % 2 == 0);
436 for (
unsigned int i=0; i<position1P.size()/2 ; ++i) {
437 ATH_MSG_DEBUG(
" Original RAW Estimated positions (" << i <<
") x: " <<
back_posX(position1P[0+i*2],applyRecentering) <<
" y: " <<
back_posY(position1P[1+i*2]));
440 std::vector<double> inputDataNew=inputData;
441 inputDataNew.reserve( inputDataNew.size() + numberSubClusters*2);
442 assert(
static_cast<unsigned int>(numberSubClusters*2) <= position1P.size() );
443 for (
unsigned int i=0; i<static_cast<unsigned int>(numberSubClusters*2); ++i) {
444 inputDataNew.push_back(position1P[i]);
450 if ((not (xNetworkIndex < endNnIdx)) or (not (yNetworkIndex < endNnIdx))){
451 ATH_MSG_FATAL(
"estimatePositionsTTN: A requested collection index, "<< xNetworkIndex <<
" or "<< yNetworkIndex <<
"is out of range.");
454 auto *pxNetwork = nn_collection.at(xNetworkIndex).get();
455 auto *pyNetwork = nn_collection.at(yNetworkIndex).get();
460 std::vector<Amg::MatrixX> errorMatrices1;
462 allPositions.reserve( allPositions.size() + myPosition1.size());
463 errors.reserve( errors.size() + myPosition1.size());
464 for (
unsigned int i=0;i<myPosition1.size();i++){
465 allPositions.push_back(myPosition1[i]);
466 errors.push_back(errorMatrices1[i]);
473 std::vector<Amg::Vector2D>
477 int numberSubClusters,
478 std::vector<Amg::MatrixX> & errors)
const {
480 if (not lwtnn_collection.
isValid()) {
484 if (lwtnn_collection->empty()){
490 std::vector<double> positionValues{};
491 std::vector<Amg::MatrixX> errorMatrices;
492 errorMatrices.reserve(numberSubClusters);
493 positionValues.reserve(numberSubClusters * 2);
494 std::size_t outputNode(0);
495 for (
int cluster = 1; cluster < numberSubClusters+1; cluster++) {
498 const auto pNetwork = lwtnn_collection->find(numberSubClusters);
499 const bool validGraph = (pNetwork != lwtnn_collection->end()) and (pNetwork->second !=
nullptr);
500 if (not validGraph) {
501 std::string infoMsg =
"Acceptable numbers of subclusters for the lwtnn collection:\n ";
502 for (
const auto &
pair: **lwtnn_collection){
503 infoMsg += std::to_string(
pair.first) +
"\n ";
505 infoMsg +=
"\nNumber of subclusters requested : "+ std::to_string(numberSubClusters);
507 ATH_MSG_FATAL(
"estimatePositionsLWTNN: No lwtnn network found for the number of clusters.\n"
508 <<
" If you are outside the valid range for an lwtnn-based configuration, please run with useNNTTrainedNetworks instead.\n Key = "
512 if(numberSubClusters==1) {
514 }
else if(numberSubClusters==2) {
516 }
else if(numberSubClusters==3) {
519 ATH_MSG_FATAL(
"Cannot evaluate LWTNN networks with " << numberSubClusters <<
" numberSubClusters" );
526 Eigen::VectorXd position = lwtnn_collection->at(numberSubClusters)->compute(input, {}, outputNode);
527 ATH_MSG_DEBUG(
"Testing for numberSubClusters " << numberSubClusters <<
" and cluster " << cluster);
528 for (
int i=0; i<position.rows(); i++) {
531 positionValues.push_back(position[1]);
532 positionValues.push_back(position[2]);
535 const float rawRmsX = std::sqrt(1.0/position[3]);
536 const float rawRmsY = std::sqrt(1.0/position[4]);
540 ATH_MSG_DEBUG(
" Estimated RMS errors (1) x: " << rmsX <<
", y: " << rmsY);
546 errorMatrices.push_back(erm);
550 errors=std::move(errorMatrices);
557 constexpr double pitch = 0.05;
558 const double corrected = posPixels * pitch;
564 std::vector<float>& pitches)
const{
565 double p = posPixels + (
m_sizeY - 1) * 0.5;
567 double p_center = -100;
569 for (
unsigned int i = 0; i <
m_sizeY; i++) {
570 if (p >= i and p <= (i + 1)) p_Y = p_actual + (p - i + 0.5) * pitches.at(i);
571 if (i == (
m_sizeY - 1) / 2) p_center = p_actual + 0.5 * pitches.at(i);
572 p_actual += pitches.at(i);
574 return std::abs(p_Y - p_center);
579 std::vector<double>& outputY,
580 std::vector<Amg::MatrixX>& errorMatrix,
581 int nParticles)
const{
582 int sizeOutputX=outputX.size()/nParticles;
583 int sizeOutputY=outputY.size()/nParticles;
590 errorMatrix.reserve( errorMatrix.size() + nParticles);
591 for (
int i=0;i<nParticles;i++){
593 for (
int u=0;u<sizeOutputX;u++){
594 sumValuesX+=outputX[i*sizeOutputX+u];
597 for (
int u=0;u<sizeOutputY;u++){
598 sumValuesY+=outputY[i*sizeOutputY+u];
600 ATH_MSG_VERBOSE(
" minimumX: " << minimumX <<
" maximumX: " << maximumX <<
" sizeOutputX " << sizeOutputX);
601 ATH_MSG_VERBOSE(
" minimumY: " << minimumY <<
" maximumY: " << maximumY <<
" sizeOutputY " << sizeOutputY);
603 for (
int u=0;u<sizeOutputX;u++){
604 RMSx+=outputX[i*sizeOutputX+u]/sumValuesX*std::pow(minimumX+(maximumX-minimumX)/(
double)(sizeOutputX-2)*(u-1./2.),2);
606 RMSx=std::sqrt(RMSx);
608 double intervalErrorX=3*RMSx;
610 int minBinX=(int)(1+(-intervalErrorX-minimumX)/(maximumX-minimumX)*(
double)(sizeOutputX-2));
611 int maxBinX=(int)(1+(intervalErrorX-minimumX)/(maximumX-minimumX)*(
double)(sizeOutputX-2));
612 if (maxBinX>sizeOutputX-1) maxBinX=sizeOutputX-1;
613 if (minBinX<0) minBinX=0;
616 for (
int u=minBinX;u<maxBinX+1;u++){
617 RMSx+=outputX[i*sizeOutputX+u]/sumValuesX*std::pow(minimumX+(maximumX-minimumX)/(
double)(sizeOutputX-2)*(u-1./2.),2);
619 RMSx=std::sqrt(RMSx);
621 for (
int u=0;u<sizeOutputY;u++){
622 RMSy+=outputY[i*sizeOutputY+u]/sumValuesY*std::pow(minimumY+(maximumY-minimumY)/(
double)(sizeOutputY-2)*(u-1./2.),2);
624 RMSy=std::sqrt(RMSy);
626 double intervalErrorY=3*RMSy;
628 int minBinY=(int)(1+(-intervalErrorY-minimumY)/(maximumY-minimumY)*(
double)(sizeOutputY-2));
629 int maxBinY=(int)(1+(intervalErrorY-minimumY)/(maximumY-minimumY)*(
double)(sizeOutputY-2));
630 if (maxBinY>sizeOutputY-1) maxBinY=sizeOutputY-1;
631 if (minBinY<0) minBinY=0;
634 for (
int u=minBinY;u<maxBinY+1;u++){
635 RMSy+=outputY[i*sizeOutputY+u]/sumValuesY*std::pow(minimumY+(maximumY-minimumY)/(
double)(sizeOutputY-2)*(u-1./2.),2);
637 RMSy=std::sqrt(RMSy);
638 ATH_MSG_VERBOSE(
"Computed error, sigma(X) " << RMSx <<
" sigma(Y) " << RMSy );
643 errorMatrix.push_back(erm);
648 std::vector<Amg::Vector2D>
657 ATH_MSG_ERROR(
"Dynamic cast failed at line "<<__LINE__<<
" of NnClusterizationFactory.cxx.");
660 int numParticles=output.size()/2;
661 int columnWeightedPosition=input.columnWeightedPosition;
662 int rowWeightedPosition=input.rowWeightedPosition;
663 ATH_MSG_VERBOSE(
" REF POS columnWeightedPos: " << columnWeightedPosition <<
" rowWeightedPos: " << rowWeightedPosition );
664 bool applyRecentering=
false;
666 applyRecentering=
true;
669 applyRecentering=
true;
671 std::vector<Amg::Vector2D> positions;
672 for (
int u=0;u<numParticles;u++){
676 posXid=
back_posX(output[2*u],applyRecentering)+rowWeightedPosition;
677 posYid=
back_posY(output[2*u+1])+columnWeightedPosition;
679 posXid=output[2*u]+rowWeightedPosition;
680 posYid=output[2*u+1]+columnWeightedPosition;
682 ATH_MSG_VERBOSE(
" N. particle: " << u <<
" idx posX " << posXid <<
" posY " << posYid );
684 const auto & [posXid_int, coercedX]=coerceToIntRange(posXid+0.5);
685 const auto & [posYid_int, coercedY]=coerceToIntRange(posYid+0.5);
686 if (coercedX or coercedY){
687 ATH_MSG_WARNING(
"X or Y position value has been limited in range; original values are (" << posXid<<
", "<<posYid<<
")");
690 ATH_MSG_VERBOSE(
" N. particle: " << u <<
" TO INTEGER idx posX " << posXid_int <<
" posY " << posYid_int );
693 if ( not cellIdOfPositionDiscrete.
isValid()){
694 ATH_MSG_WARNING(
" Cell is outside validity region with index Y: " << posYid_int <<
" and index X: " << posXid_int <<
". Not foreseen... " );
697 double pitchY = diodeParameters.
width().
xEta();
698 double pitchX = diodeParameters.
width().
xPhi();
700 <<
" Translated weighted position : " << siLocalPositionDiscrete.
xEta() );
703 ATH_MSG_VERBOSE(
" Translated weighted position +1col +1row phi: " << siLocalPositionDiscreteOneRowMoreOneColumnMore.
xPhi()
704 <<
" Translated weighted position +1col +1row eta: " << siLocalPositionDiscreteOneRowMoreOneColumnMore.
xEta() );
707 pitchX*(posXid-(
double)posXid_int));
709 if (input.ClusterPixBarrelEC == 0){
710 if (not input.useTrackInfo){
718 siLocalPosition(siLocalPositionDiscrete.
xEta()+pitchY*(posYid-(
double)posYid_int),
719 siLocalPositionDiscrete.
xPhi()+pitchX*(posXid-(
double)posXid_int)+lorentzShift);
720 ATH_MSG_VERBOSE(
" Translated final position phi: " << siLocalPosition.
xPhi() <<
" eta: " << siLocalPosition.
xEta() );
721 const auto halfWidth{design->
width()*0.5};
722 if (siLocalPositionDiscrete.
xPhi() > halfWidth){
725 ATH_MSG_WARNING(
" Corrected out of boundary cluster from x(phi): " << siLocalPositionDiscrete.
xPhi()+pitchX*(posXid-(
double)posXid_int)
726 <<
" to: " << halfWidth-1e-6);
727 }
else if (siLocalPositionDiscrete.
xPhi() < -halfWidth) {
730 ATH_MSG_WARNING(
" Corrected out of boundary cluster from x(phi): " << siLocalPositionDiscrete.
xPhi()+pitchX*(posXid-(
double)posXid_int)
731 <<
" to: " << -halfWidth+1e-6);
733 positions.emplace_back(siLocalPosition);
743 const double tanl)
const {
744 input.useTrackInfo=
true;
747 localIntersection *= 0.250/cos(localIntersection.theta());
748 float trackDeltaX = (float)localIntersection.x();
749 float trackDeltaY = (float)localIntersection.y();
750 input.theta=std::atan2(trackDeltaY,0.250);
751 input.phi=std::atan2(trackDeltaX,0.250);
753 input.phi=std::atan(std::tan(input.phi)-tanl);
754 ATH_MSG_VERBOSE(
" From track: angle phi: " << input.phi <<
" theta: " << input.theta );
761 double & tanl)
const{
780 const PixelID& pixelID = *pixelIDp;
784 ATH_MSG_ERROR(
"Dynamic cast failed at line "<<__LINE__<<
" of NnClusterizationFactory.cxx.");
789 const std::vector<Identifier>& rdos = pCluster.
rdoList();
790 const size_t rdoSize = rdos.size();
792 const std::vector<float>& chList = pCluster.
chargeList();
793 const std::vector<int>& totList = pCluster.
totList();
794 std::vector<float> chListRecreated{};
795 chListRecreated.reserve(rdoSize);
797 std::vector<int>::const_iterator tot = totList.begin();
798 std::vector<Identifier>::const_iterator rdosBegin = rdos.begin();
799 std::vector<Identifier>::const_iterator rdosEnd = rdos.end();
800 std::vector<int> totListRecreated{};
801 totListRecreated.reserve(rdoSize);
802 std::vector<int>::const_iterator totRecreated = totListRecreated.begin();
807 for ( ; rdosBegin!= rdosEnd and tot != totList.end(); ++tot, ++rdosBegin, ++totRecreated ){
813 std::array<InDetDD::PixelDiodeTree::CellIndexType,2> diode_idx
817 std::uint32_t feValue = design->
getFE(si_param);
824 float charge = calibData->
getCharge(diode_type, moduleHash, feValue, tot0);
825 chListRecreated.push_back(
charge);
826 totListRecreated.push_back(tot0);
829 rdosBegin = rdos.begin();
830 rdosEnd = rdos.end();
832 tot = totList.begin();
833 totRecreated = totListRecreated.begin();
835 std::vector<float>::const_iterator
charge = chListRecreated.begin();
836 std::vector<float>::const_iterator chargeEnd = chListRecreated.end();
837 tot = totListRecreated.begin();
838 std::vector<int>::const_iterator totEnd = totListRecreated.end();
845 for (; (rdosBegin!= rdosEnd) and (
charge != chargeEnd) and (tot != totEnd); ++rdosBegin, ++
charge, ++tot){
851 sumOfWeightedPositions += (*charge)*siLocalPosition;
852 sumOfTot += (*charge);
854 sumOfWeightedPositions += ((double)(*tot))*siLocalPosition;
855 sumOfTot += (double)(*tot);
857 rowMin = std::min(row, rowMin);
858 rowMax = std::max(row, rowMax);
859 colMin = std::min(col, colMin);
860 colMax = std::max(col, colMax);
863 sumOfWeightedPositions /= sumOfTot;
868 if (!cellIdWeightedPosition.
isValid()){
871 int columnWeightedPosition=cellIdWeightedPosition.
etaIndex();
872 int rowWeightedPosition=cellIdWeightedPosition.
phiIndex();
873 ATH_MSG_VERBOSE(
" weighted pos row: " << rowWeightedPosition <<
" col: " << columnWeightedPosition );
874 int centralIndexX=(
m_sizeX-1)/2;
875 int centralIndexY=(
m_sizeY-1)/2;
876 if (std::abs(rowWeightedPosition-rowMin)>centralIndexX or
877 std::abs(rowWeightedPosition-rowMax)>centralIndexX){
878 ATH_MSG_VERBOSE(
" Cluster too large rowMin" << rowMin <<
" rowMax " << rowMax <<
" centralX " << centralIndexX);
881 if (std::abs(columnWeightedPosition-colMin)>centralIndexY or
882 std::abs(columnWeightedPosition-colMax)>centralIndexY){
883 ATH_MSG_VERBOSE(
" Cluster too large colMin" << colMin <<
" colMax " << colMax <<
" centralY " << centralIndexY);
886 input.matrixOfToT.reserve(
m_sizeX);
888 input.matrixOfToT.emplace_back(
m_sizeY, 0.0);
890 input.vectorOfPitchesY.assign(
m_sizeY, 0.4);
891 rdosBegin = rdos.begin();
892 charge = chListRecreated.begin();
893 chargeEnd = chListRecreated.end();
894 tot = totListRecreated.begin();
895 ATH_MSG_VERBOSE(
" Putting together the n. " << rdos.size() <<
" rdos into a matrix." );
897 input.etaModule=(int)pixelID.
eta_module(pixidentif);
898 input.ClusterPixLayer=(int)pixelID.
layer_disk(pixidentif);
899 input.ClusterPixBarrelEC=(int)pixelID.
barrel_ec(pixidentif);
900 for (;(
charge != chargeEnd) and (rdosBegin!= rdosEnd); ++rdosBegin, ++
charge, ++tot){
902 unsigned int absrow = pixelID.
phi_index(rId)-rowWeightedPosition+centralIndexX;
903 unsigned int abscol = pixelID.
eta_index(rId)-columnWeightedPosition+centralIndexY;
914 double pitchY = diodeParameters.
width().
xEta();
916 input.matrixOfToT[absrow][abscol]=*
charge;
918 input.matrixOfToT[absrow][abscol]=(double)(*tot);
921 if (
m_addIBL and (input.ClusterPixLayer==0) and (input.ClusterPixBarrelEC==0)){
922 input.matrixOfToT[absrow][abscol]*=3;
926 if ( (input.ClusterPixLayer==0) and (input.ClusterPixBarrelEC==0)){
927 input.matrixOfToT[absrow][abscol]*=3;
932 if (std::abs(pitchY-0.4)>1e-5){
933 input.vectorOfPitchesY[abscol]=pitchY;
937 ATH_MSG_VERBOSE(
" Layer number: " << input.ClusterPixLayer <<
" Barrel / endcap: " << input.ClusterPixBarrelEC );
938 input.useTrackInfo=
false;
946 float trkphicomp = my_track.dot(my_phiax);
947 float trketacomp = my_track.dot(my_etaax);
948 float trknormcomp = my_track.dot(my_normal);
949 double bowphi = std::atan2(trkphicomp,trknormcomp);
950 double boweta = std::atan2(trketacomp,trknormcomp);
952 if(bowphi > M_PI_2) bowphi -=
M_PI;
953 if(bowphi < -M_PI_2) bowphi +=
M_PI;
955 double angle = std::atan(std::tan(bowphi)-readoutside*tanl);
958 if (boweta>M_PI_2) boweta-=
M_PI;
959 if (boweta<-M_PI_2) boweta+=
M_PI;
962 input.rowWeightedPosition=rowWeightedPosition;
963 input.columnWeightedPosition=columnWeightedPosition;
964 ATH_MSG_VERBOSE(
" RowWeightedPosition: " << rowWeightedPosition <<
" ColWeightedPosition: " << columnWeightedPosition );
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
double charge(const T &p)
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
double norm_rawToT(const double input)
double norm_pitch(const double input, bool addIBL=false)
double errorHalfIntervalY(const int nParticles)
double norm_layerNumber(const double input)
double norm_thetaBS(const double input)
double norm_layerType(const double input)
double norm_ToT(const double input)
double back_posX(const double input, const bool recenter=false)
double back_posY(const double input)
double norm_phi(const double input)
double norm_phiBS(const double input)
double norm_theta(const double input)
double norm_etaModule(const double input)
double errorHalfIntervalX(const int nParticles)
This is an Identifier helper class for the Pixel subdetector.
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
static const Attributes_t empty
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
virtual HelperType helper() const
Type of helper, defaulted to 'Unimplemented'.
This is a "hash" representation of an Identifier.
int readoutSide() const
ReadoutSide.
static constexpr std::array< PixelDiodeTree::CellIndexType, 2 > makeCellIndex(T local_x_idx, T local_y_idx)
Create a 2D cell index from the indices in local-x (phi, row) and local-y (eta, column) direction.
Class used to describe the design of a module (diode segmentation and readout scheme)
virtual SiDiodesParameters parameters(const SiCellId &cellId) const
readout or diode id -> position, size
virtual int numberOfConnectedCells(const SiReadoutCellId &readoutId) const
readout id -> id of connected diodes
PixelReadoutTechnology getReadoutTechnology() const
PixelDiodeTree::DiodeProxy diodeProxyFromIdx(const std::array< PixelDiodeTree::IndexType, 2 > &idx) const
SiLocalPosition positionFromColumnRow(const int column, const int row) const
Given row and column index of a diode, return position of diode center ALTERNATIVE/PREFERED way is to...
virtual SiReadoutCellId readoutIdOfCell(const SiCellId &cellId) const
diode id -> readout id
static InDetDD::PixelDiodeType getDiodeType(const PixelDiodeTree::DiodeProxy &diode_proxy)
virtual SiCellId cellIdOfPosition(const SiLocalPosition &localPos) const
position -> id
virtual double width() const
Method to calculate average width of a module.
static unsigned int getFE(const PixelDiodeTree::DiodeProxy &diode_proxy)
Identifier for the strip or pixel cell.
int phiIndex() const
Get phi index. Equivalent to strip().
bool isValid() const
Test if its in a valid state.
int etaIndex() const
Get eta index.
Class to hold geometrical description of a silicon detector element.
virtual SiCellId cellIdFromIdentifier(const Identifier &identifier) const override final
SiCellId from Identifier.
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
Class to handle the position of the centre and the width of a diode or a cluster of diodes Version 1....
const SiLocalPosition & width() const
width of the diodes:
Class to represent a position in the natural frame of a silicon sensor, for Pixel and SCT For Pixel: ...
double xPhi() const
position along phi direction:
double xEta() const
position along eta direction:
const Amg::Vector3D & etaAxis() const
virtual const Amg::Vector3D & normal() const override final
Get reconstruction local normal axes in global frame.
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
HepGeom::Point3D< double > globalPosition(const HepGeom::Point3D< double > &localPos) const
transform a reconstruction local position into a global position (inline):
const Amg::Vector3D & phiAxis() const
const AtlasDetectorID * getIdHelper() const
Returns the id helper (inline)
std::vector< double > assembleInputRunII(NNinput &input) const
void addTrackInfoToInput(NNinput &input, const Trk::Surface &pixelSurface, const Trk::TrackParameters &trackParsAtSurface, const double tanl) const
Gaudi::Property< unsigned int > m_maxSubClusters
SG::ReadCondHandleKey< PixelChargeCalibCondData > m_chargeDataKey
std::vector< double > estimateNumberOfParticlesLWTNN(NnClusterizationFactory::InputVector &input) const
Gaudi::Property< unsigned int > m_sizeX
double correctedRMSY(double posPixels, std::vector< float > &pitches) const
ReturnType(::TTrainedNetwork::* m_calculateOutput)(const InputType &input) const
NNinput createInput(const InDet::PixelCluster &pCluster, Amg::Vector3D &beamSpotPosition, double &tanl) const
virtual StatusCode initialize() override
Gaudi::Property< double > m_correctLorShiftBarrelWithoutTracks
Gaudi::Property< std::size_t > m_outputNodesPos1
Gaudi::Property< std::vector< std::size_t > > m_outputNodesPos2
ToolHandle< ISiLorentzAngleTool > m_pixelLorentzAngleTool
Gaudi::Property< bool > m_useToT
Gaudi::Property< std::vector< std::size_t > > m_outputNodesPos3
std::vector< Amg::Vector2D > estimatePositionsLWTNN(NnClusterizationFactory::InputVector &input, NNinput &rawInput, const InDet::PixelCluster &pCluster, int numberSubClusters, std::vector< Amg::MatrixX > &errors) const
std::vector< double > assembleInputRunI(NNinput &input) const
SG::ReadCondHandleKey< LWTNNCollection > m_readKeyJSON
std::vector< Amg::Vector2D > estimatePositions(const InDet::PixelCluster &pCluster, Amg::Vector3D &beamSpotPosition, std::vector< Amg::MatrixX > &errors, int numberSubClusters) const
Gaudi::Property< std::vector< std::string > > m_nnOrder
Gaudi::Property< double > m_correctLorShiftBarrelWithTracks
Gaudi::Property< bool > m_useTTrainedNetworks
std::vector< double > estimateNumberOfParticlesTTN(const TTrainedNetworkCollection &nn_collection, const std::vector< double > &inputData) const
static constexpr std::array< unsigned int, kNNetworkTypes > m_nParticleGroup
unsigned int m_nParticleNNId
SG::ReadCondHandleKey< TTrainedNetworkCollection > m_readKeyWithoutTrack
std::vector< double >(InDet::NnClusterizationFactory::* m_assembleInput)(NNinput &input) const
std::vector< Eigen::VectorXd > InputVector
NnClusterizationFactory(const std::string &name, const std::string &n, const IInterface *p)
std::vector< Amg::Vector2D > estimatePositionsTTN(const TTrainedNetworkCollection &nn_collection, const std::vector< double > &inputData, const NNinput &input, const InDet::PixelCluster &pCluster, int numberSubClusters, std::vector< Amg::MatrixX > &errors) const
Gaudi::Property< bool > m_doRunI
static const std::array< std::regex, kNNetworkTypes > m_nnNames
Gaudi::Property< bool > m_useRecenteringNNWithouTracks
static constexpr std::array< std::string_view, kNNetworkTypes > s_nnTypeNames
InputVector eigenInput(NNinput &input) const
void getErrorMatrixFromOutput(std::vector< double > &outputX, std::vector< double > &outputY, std::vector< Amg::MatrixX > &errorMatrix, int nParticles) const
Gaudi::Property< bool > m_useRecenteringNNWithTracks
std::vector< std::vector< unsigned int > > m_NNId
std::vector< Amg::Vector2D > getPositionsFromOutput(std::vector< double > &output, const NNinput &input, const InDet::PixelCluster &pCluster) const
static double correctedRMSX(double posPixels)
size_t calculateVectorDimension(const bool useTrackInfo) const
Gaudi::Property< unsigned int > m_sizeY
Gaudi::Property< bool > m_addIBL
SG::ReadCondHandleKey< TTrainedNetworkCollection > m_readKeyWithTrack
std::vector< double > estimateNumberOfParticles(const InDet::PixelCluster &pCluster, Amg::Vector3D &beamSpotPosition) const
const std::vector< int > & totList() const
const std::vector< float > & chargeList() const
virtual const InDetDD::SiDetectorElement * detectorElement() const override final
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
float getCharge(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE, float ToT) const
This is an Identifier helper class for the Pixel subdetector.
int eta_index(const Identifier &id) const
int layer_disk(const Identifier &id) const
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module) const
For a single crystal.
int barrel_ec(const Identifier &id) const
Values of different levels (failure returns 0)
IdentifierHash wafer_hash(Identifier wafer_id) const
wafer hash from id
int eta_module(const Identifier &id) const
int phi_index(const Identifier &id) const
std::vector< Double_t > calculateOutputValues(std::vector< Double_t > &input) const
DVec calculateNormalized(const DVec &input) const
const Amg::Vector3D & momentum() const
Access method for the momentum.
const Amg::Vector2D & localPosition() const
return the local position reference
Identifier identify() const
return the identifier
const std::vector< Identifier > & rdoList() const
return the List of rdo identifiers (pointers)
Abstract Base Class for tracking surfaces.
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
ParametersBase< TrackParametersDim, Charged > TrackParameters
Helper class to access parameters of a diode.