11#include "GaudiKernel/StatusCode.h"
12#include "GaudiKernel/MsgStream.h"
14#include "GaudiKernel/AlgTool.h"
28#include "CLHEP/Matrix/Matrix.h"
29#include "CLHEP/Matrix/SymMatrix.h"
30#include "CLHEP/Matrix/Vector.h"
33#include <TMatrixDSym.h>
34#include <TMatrixDSparse.h>
49#include <sys/resource.h>
55 const IInterface* parent)
59 declareInterface<IMatrixTool>(
this);
76 return StatusCode::FAILURE;
79 ATH_MSG_INFO(
"Retrieving data from the following files: ");
84 return StatusCode::SUCCESS;
92 return StatusCode::SUCCESS;
99 ATH_MSG_INFO(
"allocating matrix and vector with nDoF = "<<nDoF);
121 return StatusCode::SUCCESS;
134 *
m_logStream<<
"*************************************************************\n";
135 *
m_logStream<<
"************** solving using Global method ****************\n";
136 *
m_logStream<<
"************** using ROOT ****************\n";
137 *
m_logStream<<
"*************************************************************\n";
141 clock_t starttime = clock();
149 if (
msgLvl(MSG::VERBOSE)) {
150 msg(MSG::VERBOSE)<<
"dumping matrix and vector to screen"<<
endmsg;
151 for (
int i=0;i<nDoF;i++)
152 for (
int j=0;j<nDoF;j++)
153 msg(MSG::VERBOSE)<<i<<
", "<<j<<
" : "<<(*m_bigmatrix)[i][j] <<
endmsg;
155 for (
int i=0;i<nDoF;i++)
156 msg(MSG::VERBOSE)<<i <<
" : "<<(*m_bigvector)[i]<<
endmsg;
161 double * firstderiv =
new double[
m_aNDoF];
162 for (
int iActive=0;iActive<
m_aNDoF;iActive++) {
164 firstderiv[iActive] = (*m_bigvector)[i];
165 for (
int jActive=0;jActive<
m_aNDoF;jActive++) {
167 secderiv[iActive*
m_aNDoF+jActive] = (*m_bigmatrix)[i][j];
176 TVectorD b(
m_aNDoF,firstderiv);
179 msg(MSG::DEBUG)<<
"First derivatives:"<<
endmsg;
181 msg(MSG::DEBUG)<<
"Second derivatives:"<<
endmsg;
187 TMatrixDSym ainv(c.Invert(status));
189 TVectorD
r(b.GetNrows());
191 r = c.Solve(b,status);
194 clock_t stoptime = clock();
195 double totaltime = (stoptime-starttime)/
double(CLOCKS_PER_SEC);
196 ATH_MSG_INFO(
"Time spent in solveROOT: "<<totaltime<<
" s");
199 msg(MSG::ERROR)<<
"ROOT inversion failed"<<
endmsg;
209 for (
int iAdof=0;iAdof<
m_aNDoF;iAdof++) {
212 AlignPar * alignPar=(*alignParList)[idof];
214 double sigma = alignPar->
sigma();
215 double param = -
r[iAdof] * sigma;
216 double err = std::sqrt(2.*std::fabs(ainv(iAdof,iAdof))) * sigma;
219 ATH_MSG_DEBUG(
"ainv("<<iAdof<<
")="<<ainv(iAdof,iAdof)<<
", sigma: "<<sigma);
221 alignPar->
setPar(param,err);
222 ATH_MSG_DEBUG(
"set param to "<<param<<
" for alignPar "<<alignPar);
233 *
m_logStream<<
"norm of first derivative : "<<sqrt(b.Norm2Sqr())<<
"\n";
236 double dist = sqrt( ( b - (
a *
r) ).Norm2Sqr() );
237 *
m_logStream<<
"distance to solution : "<<dist<<
"\n";
240 double chi2 =
a.Similarity(
r) * .5;
244 *
m_logStream<<
"time spent in solve : "<<totaltime<<
" s\n";
249 delete [] firstderiv;
259 *
m_logStream<<
"*************************************************************\n";
260 *
m_logStream<<
"************** solving using Global method ****************\n";
261 *
m_logStream<<
"************** using CLHEP ****************\n";
262 *
m_logStream<<
"*************************************************************\n";
266 clock_t starttime = clock();
270 for (
int i=0;i<(int)alignParList->
size();i++)
277 msg(MSG::DEBUG)<<
"dumping matrix and vector to screen"<<
endmsg;
278 for (
int i=0;i<nDoF;i++)
279 for (
int j=0;j<nDoF;j++)
280 msg(MSG::DEBUG)<<i<<
", "<<j<<
" : "<<(*m_bigmatrix)[i][j] <<
endmsg;
282 for (
int i=0;i<nDoF;i++)
283 msg(MSG::DEBUG)<<i <<
" : "<<(*m_bigvector)[i]<<
endmsg;
287 CLHEP::HepSymMatrix * d2Chi2 =
new CLHEP::HepSymMatrix(
m_aNDoF,0);
288 CLHEP::HepVector * dChi2 =
new CLHEP::HepVector(
m_aNDoF,0);
289 for (
int iActive=0;iActive<
m_aNDoF;iActive++) {
291 (*dChi2)[iActive] = (*m_bigvector)[i];
292 for (
int jActive=0;jActive<
m_aNDoF;jActive++) {
294 (*d2Chi2)[iActive][jActive] = (*m_bigmatrix)[i][j];
301 CLHEP::HepSymMatrix cov(
m_aNDoF,0);
302 CLHEP::HepVector delta(
m_aNDoF,0);
303 CLHEP::HepVector deltafull(
m_aNDoF,0);
317 msg(MSG::ERROR)<<
"CLHEP inversion status flag = "<<ierr<<
endmsg;
321 *
m_logStream<<
"CLHEP inversion status flag = "<<ierr<<
"\n";
324 delta = cov * (*dChi2);
334 CLHEP::HepSymMatrix cov2 = *d2Chi2 * .5;
339 msg(MSG::WARNING)<<
"Second CLHEP inversion status flag = "<<ierr2<<
endmsg;
341 CLHEP::HepVector delta2 = cov2 * (*dChi2) * .5;
342 for (
int i=0;i<delta.num_row(); ++i)
343 if ( fabs((delta[i] - delta2[i])/delta[i]) > 1e-5 ) {
344 msg(MSG::WARNING)<<
"Something's wrong with the matrix inversion: delta["<<i<<
"] = "<<delta[i]<<
" delta2["<<i<<
"] = "<<delta2[i]<<
endmsg;
350 *
m_logStream<<
"CLHEP inversion status flag for halfed matrix = "<<ierr2<<
"\n";
363 CLHEP::HepSymMatrix D = *d2Chi2;
364 CLHEP::HepMatrix U = CLHEP::diagonalize( &D );
372 for (
int i=0; i<
m_aNDoF-1; i++)
373 for (
int j=i+1; j<
m_aNDoF; j++)
374 if(D[j][j] < D[i][i]) {
389 CLHEP::HepVector eigenvector(
m_aNDoF);
392 *
m_logStream<<
"/------ The Eigenvalue Spectrum -------\n";
395 for(
int imode=0; imode<
m_aNDoF; ++imode) {
398 for(
int irow=0; irow<
m_aNDoF; ++irow)
399 eigenvector[irow] = U[irow][imode];
403 double eigenvalue = D[imode][imode];
406 double evdotb =
dot(*dChi2,eigenvector);
407 CLHEP::HepVector thisdelta = evdotb/eigenvalue * eigenvector;
408 deltafull += thisdelta;
413 *
m_logStream<<
"| skipping eigenvalue "<<eigenvalue<<
"\n";
418 *
m_logStream<<
"| skipping eigenvalue "<<eigenvalue<<
"\n";
427 for(
int irow=0; irow<
m_aNDoF; ++irow)
428 for(
int icol=0; icol<=irow; ++icol)
429 cov[irow][icol] += eigenvector[irow] * eigenvector[icol] / eigenvalue;
439 *
m_logStream<<
"\\----- End of Eigenvalue Spectrum -----\n";
446 clock_t stoptime = clock();
447 double totaltime = (stoptime-starttime)/
double(CLOCKS_PER_SEC);
448 ATH_MSG_INFO(
"Time spent in solveCLHEP: "<<totaltime<<
" s");
450 if(ierr==0 && status)
453 for (
int iAdof=0;iAdof<
m_aNDoF;iAdof++) {
456 AlignPar * alignPar=(*alignParList)[idof];
458 double sigma = alignPar->
sigma();
459 double param = -delta[iAdof] * sigma;
460 double err = std::sqrt(2.*std::fabs(cov[iAdof][iAdof])) * sigma;
463 ATH_MSG_DEBUG(
"cov("<<iAdof<<
")="<<cov[iAdof][iAdof]<<
", sigma: "<<sigma);
465 alignPar->
setPar(param,err);
466 ATH_MSG_DEBUG(
"set param to "<<param<<
" for alignPar "<<alignPar);
474 *
m_logStream<<
"norm of first derivative : "<<dChi2->norm()<<
"\n";
477 double dist = ( - (*d2Chi2) * deltafull + (*dChi2) ).norm();
478 *
m_logStream<<
"distance to solution : "<<dist<<
"\n";
481 double chi2 = d2Chi2->similarity(delta) * .5;
485 *
m_logStream<<
"time spent in solve : "<<totaltime<<
" s\n";
500 *
m_logStream<<
"*************************************************************\n";
501 *
m_logStream<<
"************** solving using Local method *****************\n";
502 *
m_logStream<<
"*************************************************************\n";
506 double totalChi2(0.);
510 AlignModuleList::const_iterator imod = alignModules->begin();
511 AlignModuleList::const_iterator imod_end = alignModules->end();
512 for( ; imod!=imod_end; ++imod) {
520 int thisNDoF = alignPars->
size();
522 CLHEP::HepSymMatrix d2Chi2(thisNDoF,0);
523 CLHEP::HepVector dChi2(thisNDoF,0);
524 for (
int i=0;i<thisNDoF;++i) {
525 int ipar = alignPars->
at(i)->index();
526 dChi2[i] = (*m_bigvector)[ipar];
527 for (
int j=0;j<thisNDoF;++j) {
528 int jpar = alignPars->
at(j)->index();
529 d2Chi2[i][j] = (*m_bigmatrix)[ipar][jpar];
537 ATH_MSG_INFO(
"Not enough hits in module \'"<<module->name()<<
"\': "
553 totalNDoF += thisNDoF;
555 CLHEP::HepSymMatrix cov(d2Chi2);
566 CLHEP::HepVector delta = cov * dChi2;
574 for (
int idof=0;idof<thisNDoF;++idof) {
577 double sigma = alignPar->
sigma();
578 double param = -delta[idof] * sigma;
579 double err = std::sqrt(2.*std::fabs(cov[idof][idof])) * sigma;
582 ATH_MSG_DEBUG(
"cov("<<idof<<
")="<<cov[idof][idof]<<
", sigma: "<<sigma);
585 ATH_MSG_DEBUG(
"Filling constants obtained using Local method");
586 alignPar->
setPar(param,err);
587 ATH_MSG_DEBUG(
"set param to "<<param<<
" for alignPar "<<alignPar);
594 *
m_logStream<<
"CLHEP inversion status flag = "<<ierr<<
"\n";
597 double chi2 = d2Chi2.similarity(delta) * .5;
599 *
m_logStream<<
"delta(chi2) of the alignment change : "<<
chi2<<
" / "<<thisNDoF<<
"\n";
604 *
m_logStream<<
"--------------------------------------------------------------------------------\n";
605 *
m_logStream<<
"Total delta(chi2) of the alignment change from the local method : "<<totalChi2<<
" / "<<totalNDoF<<
"\n";
620 ATH_MSG_INFO(
"Info to obtained from from Binary files");
631 int nDoF=alignParList->
size();
633 std::map<int,unsigned long long> modIndexMap;
634 float dummyVersion(0.);
635 double totalscale=0.;
640 AlVec newVector(nDoF);
641 std::map<int,unsigned long long> newModIndexMap;
647 if (
sc==StatusCode::FAILURE) {
652 msg(MSG::FATAL) <<
"vector wrong size! newVector size "<<newVector.
size()
659 modIndexMap = std::move(newModIndexMap);
660 else if (modIndexMap!=newModIndexMap) {
661 msg(MSG::FATAL)<<
"module index maps don't agree!"<<
endmsg;
680 int nDoF=modIndexMap.size();
686 if (
sc==StatusCode::SUCCESS)
687 *symBigMatrix += newMatrix;
691 throw std::logic_error(
"Unhandled matrix type");
697 if (
sc==StatusCode::SUCCESS) {
699 *spaBigMatrix += newMatrix;
701 *spaBigMatrix = newMatrix;
705 if (
sc==StatusCode::FAILURE) {
711 ATH_MSG_WARNING(
"matrix not expected format! Changing m_wSqMatrix to "<<!triang);
733 int nDoF = alignParList->
size();
745 int nModules = moduleList->size();
746 std::vector<double> hitmapA(nModules);
747 std::vector<double> hitmapB(nModules);
750 for(std::size_t
index{};
const auto *
module : *moduleList) {
751 hitmapA[index] = static_cast<double>(module->nHits());
752 hitmapB[
index] =
static_cast<double>(
module->nTracks());
756 TVectorD hitmapHits(nModules, hitmapA.data());
757 TVectorD hitmapTracks(nModules, hitmapB.data());
759 TFile myFile(filename,
"recreate");
760 hitmapHits.Write(
"Hits");
761 hitmapTracks.Write(
"Tracks");
762 myTMatrix->Write(
"Matrix");
763 myTVector.Write(
"Vector");
765 TVectorD scale(1, &m_scale) ;
766 scale.Write(
"Scale");
769 double *moduleInfoA =
new double[nDoF];
770 double *dofInfoA =
new double[nDoF];
772 if (
sizeof(
unsigned long long) !=
sizeof(
double))
773 ATH_MSG_ERROR(
"Module Identifiers will not be saved. sizeof(double)!=sizeof(ulonglong)");
777 for (
int i=0;i<(int)alignPars->
size();i++) {
780 uint64_t
id = (*alignPars)[i]->alignModule()->identify().get_compact();
781 memcpy(&target, &
id,
sizeof(target));
782 moduleInfoA[i]=target;
783 uint64_t dof = (*alignPars)[i]->paramType();
784 memcpy(&target, &dof,
sizeof(target));
788 TVectorD moduleIDs(nDoF, moduleInfoA) ;
789 TVectorD moduleDoFs(nDoF,dofInfoA);
790 delete [] moduleInfoA;
791 moduleIDs.Write(
"ModuleID");
792 moduleDoFs.Write(
"dof");
807 int nDoF=alignParList->
size();
810 std::map<int,unsigned long long> modIndexMap;
811 std::map<int,unsigned long long> DoFMap;
812 double totalscale=0.;
817 std::unique_ptr<AlSpaMat> accumMatrix;
820 int nModules = moduleList->size();
822 TVectorD TotalHits(nModules);
823 TVectorD TotalTracks(nModules);
825 int numberOfReadErrors = 0;
827 struct rusage myusage{};
828 int itworked = getrusage(RUSAGE_SELF,&myusage);
832 long intialMemUse = myusage.ru_maxrss;
834 for (
int ifile = 0; ifile < (int)
m_inputTFiles.size(); ifile++) {
842 itworked = getrusage(RUSAGE_SELF,&myusage);
844 ATH_MSG_DEBUG(
"Memory usage [MB], total " << myusage.ru_maxrss/1024 <<
", increase " << (myusage.ru_maxrss-intialMemUse)/1024);
848 if ( myFile->IsZombie() || !(myFile->IsOpen()) ) {
849 ++numberOfReadErrors;
854 std::map<int,unsigned long long> newModIndexMap;
856 TVectorD* myModuleIDs;
857 myModuleIDs = (TVectorD*)myFile->Get(
"ModuleID");
859 ++numberOfReadErrors;
864 for (
int i(0); i<myModuleIDs->GetNrows(); ++i){
866 double source = (*myModuleIDs)(i);
868 memcpy(&target, &source,
sizeof(target));
869 newModIndexMap[i]=target;
875 std::map<int,unsigned long long> newDoFMap;
878 myDoFs = (TVectorD*)myFile->Get(
"dof");
880 ++numberOfReadErrors;
885 for (
int i(0); i<myDoFs->GetNrows(); ++i){
887 double source = (*myDoFs)(i);
889 memcpy(&target, &source,
sizeof(target));
896 Scale = (TVectorD*)myFile->Get(
"Scale");
898 ++numberOfReadErrors;
903 double scale=(*Scale)(0);
909 TVectorD*
vector = (TVectorD*)myFile->Get(
"Vector");
911 ++numberOfReadErrors;
916 auto newVector = std::make_unique<AlVec>(nDoF);
921 msg(MSG::FATAL) <<
"vector wrong size! newVector size " << newVector->size()
928 msg(MSG::FATAL) <<
"File vector wrong size! File Vector size " <<
vector->GetNrows()
935 for (
int i=0;i<nDoF;i++) {
936 (*newVector)[i] = (*vector)(i);
942 DoFMap = std::move(newDoFMap);
943 }
else if (DoFMap!=newDoFMap) {
945 msg(MSG::FATAL) <<
"module dofs don't agree!" <<
endmsg;
950 modIndexMap = std::move(newModIndexMap);
951 }
else if (modIndexMap!=newModIndexMap) {
953 msg(MSG::FATAL) <<
"module index maps don't agree!" <<
endmsg;
968 ++numberOfReadErrors;
976 accumMatrix = std::make_unique<AlSpaMat>(nDoF);
977 ATH_MSG_DEBUG(
"Matrix size b4 "<< accumMatrix->ptrMap()->size() );
980 for (
int ii=0;ii<nDoF;ii++) {
981 const TMatrixTSparseRow_const<double> myRow = (*matrix)[ii];
982 int i = myRow.GetRowIndex();
983 for (
int jj=0;jj<myRow.GetNindex();jj++) {
984 int j = (myRow.GetColPtr())[jj];
985 const double myElement= (myRow.GetDataPtr())[jj];
989 i = (myRow.GetColPtr())[jj];
991 (*accumMatrix)[i][j] = myElement;
994 ATH_MSG_DEBUG(
"Matrix size AF "<< accumMatrix->ptrMap()->size() );
996 }
else if ( accumMatrix) {
997 ATH_MSG_DEBUG(
"Matrix size b4 "<< accumMatrix->ptrMap()->size() );
999 for (
int ii=0;ii<nDoF;ii++) {
1000 const TMatrixTSparseRow_const<double> myRow = (*matrix)[ii];
1001 int i = myRow.GetRowIndex();
1002 for (
int jj=0;jj<myRow.GetNindex();jj++) {
1003 int j = (myRow.GetColPtr())[jj];
1004 const double myElement= (myRow.GetDataPtr())[jj];
1008 i = (myRow.GetColPtr())[jj];
1010 (*accumMatrix)[i][j] += myElement;
1013 ATH_MSG_DEBUG(
"Matrix size AF "<< accumMatrix->ptrMap()->size() );
1017 ++numberOfReadErrors;
1028 hits = (TVectorD*)myFile->Get(
"Hits");
1030 ++numberOfReadErrors;
1035 tracks = (TVectorD*)myFile->Get(
"Tracks");
1038 ++numberOfReadErrors;
1043 if(hits->GetNrows() != TotalHits.GetNrows() ){
1046 ++numberOfReadErrors;
1051 TotalHits += (*hits);
1052 TotalTracks += (*tracks);
1062 ATH_MSG_DEBUG(
"Memory usage [MB], total " << myusage.ru_maxrss/1024 <<
", increase " << (myusage.ru_maxrss-intialMemUse)/1024);
1073 for (
int i=0;i<nDoF;i++) {
1074 for (
int j=0;j<=i;j++) {
1075 newMatrix[i][j] = (*accumMatrix)[i][j];
1079 *symBigMatrix += newMatrix;
1080 }
else if (spaBigMatrix) {
1081 ATH_MSG_DEBUG(
"should reassign matrix "<< spaBigMatrix->ptrMap()->size() );
1082 *spaBigMatrix += *accumMatrix;
1083 ATH_MSG_DEBUG(
"?????? "<< spaBigMatrix->ptrMap()->size() );
1089 AlignModuleList::const_iterator imod = moduleList->begin();
1090 AlignModuleList::const_iterator imod_end = moduleList->end();
1093 for(; imod != imod_end; ++imod, ++
index ) {
1095 module->setNHits((int)TotalHits(index));
1096 module->setNTracks((int)TotalTracks(index));
1097 totalhits += (int)TotalHits(
index);
1128 double dummyVersion(2.);
1131 std::map<int,unsigned long long> modIndexMap;
1132 std::map<int,std::string> modNameMap;
1134 for (
int i=0;i<(int)alignPars->
size();i++) {
1135 modIndexMap[i]=(*alignPars)[i]->alignModule()->identify().get_compact();
1136 modNameMap [i]=(*alignPars)[i]->alignModule()->name();
1142 StatusCode sc2 =
m_bigvector->WritePartial(
"vector.bin",
true,
m_scale,modIndexMap,dummyVersion);
1143 if (!sc1.isSuccess() || !sc2.isSuccess()) {
1144 msg(MSG::ERROR)<<
"problem writing matrix or vector"<<
endmsg;
1157 if (!sc1.isSuccess() || !sc2.isSuccess()) {
1158 msg(MSG::ERROR)<<
"problem writing matrix or vector"<<
endmsg;
1184 ATH_MSG_DEBUG(
"rescaling the matrix/vector and applying the soft-mode-cut");
1187 int nDoF = alignParList->
size();
1193 for (
int i=0;i<nDoF;i++) {
1195 double sigma_i = (*alignParList)[i]->sigma();
1196 double softCut = 2 * pow( (*alignParList)[i]->softCut() , -2 );
1197 (*m_bigvector)[i] *= sigma_i;
1199 for (
int j=0;j<=i;j++) {
1201 if ((*chkMatrix)[i][j] != 0.) {
1202 double sigma_j = (*alignParList)[j]->sigma();
1203 (*m_bigmatrix)[i][j] *= sigma_i * sigma_j;
1213 (*alignParList)[i]->setFirstDeriv((*
m_bigvector)[i]/sigma_i);
1214 (*alignParList)[i]->setSecndDeriv((*
m_bigmatrix)[i][i]/sigma_i/sigma_i);
1220 for (
const datamap::value_type& p : *
m_bigmatrix->ptrMap()) {
1221 int i = p.first.first;
1222 int j = p.first.second;
1225 double sigma_i = (*alignParList)[i]->sigma();
1226 double sigma_j = (*alignParList)[j]->sigma();
1228 (*m_bigmatrix)[i][j] *= sigma_i * sigma_j;
1233 for (
int i=0;i<nDoF;i++) {
1235 double sigma_i = (*alignParList)[i]->sigma();
1236 (*m_bigvector)[i] *= sigma_i;
1238 double softCut = 2 * pow( (*alignParList)[i]->softCut() , -2 );
1242 (*alignParList)[i]->setFirstDeriv((*
m_bigvector)[i]/sigma_i);
1243 (*alignParList)[i]->setSecndDeriv((*
m_bigmatrix)[i][i]/sigma_i/sigma_i);
1247 unsigned long long OldPixelIdentifier = 37769216;
1248 unsigned long long IBLIdentifier = 33574912;
1250 unsigned long long SCT_ECA_8_Identifier = 218116096;
1251 std::string SCT_ECA_8_Name =
"SCT/EndcapA/Disk_8";
1256 ATH_MSG_INFO(
"Javi: Printing (*alignParList)[i]->alignModule()->identify32()");
1259 for(
int i=0;i<nDoF;i++)
1262 ATH_MSG_DEBUG((*alignParList)[i]->alignModule()->identify32());
1268 const auto & theParameterList = *alignParList;
1269 const auto & thisIdentifier = theParameterList[i]->alignModule()->identify32();
1270 const auto & thisName = theParameterList[i]->alignModule()->name();
1271 const auto & thisParameterType = theParameterList[i]->paramType();
1272 const bool oldPixel = (thisIdentifier == OldPixelIdentifier);
1273 const bool ibl = (thisIdentifier == IBLIdentifier);
1274 const bool SCTECA8 = (thisIdentifier == SCT_ECA_8_Identifier);
1275 const bool SCTECA8_n = (thisName.find(SCT_ECA_8_Name)!= std::string::npos);
1279 {
ATH_MSG_INFO(
"SCT ECA Last Disk DoF have been skipped in the solving because DeactivateSCT_ECA_LastDisk is set to True");
1282 {
ATH_MSG_INFO(
"SCT ECA Last Disk DoF have been skipped in the solving because DeactivateSCT_ECA_LastDisk is set to True");
1288 {
ATH_MSG_INFO(
"Pixel DoF have been skipped in the solving because AlignIBLbutNotPixel is set to True");
1293 {
ATH_MSG_INFO(
"IBL DoF have been skipped in the solving because AlignPixelbutNotIBL is set to True");
1299 if ( oldPixel and (thisParameterType == 0))
1300 {
ATH_MSG_INFO(
"Pixel Tx DoF has been skipped in the solving because Remove_Pixel_Tx is set to True");
1304 if ( oldPixel and (thisParameterType == 1))
1305 {
ATH_MSG_INFO(
"Pixel Ty DoF has been skipped in the solving because Remove_Pixel_Ty is set to True");
1309 if (oldPixel and (thisParameterType == 2))
1310 {
ATH_MSG_INFO(
"Pixel Tz DoF has been skipped in the solving because Remove_Pixel_Tz is set to True");
1314 if (oldPixel and (thisParameterType == 3))
1315 {
ATH_MSG_INFO(
"Pixel Rx DoF has been skipped in the solving because Remove_Pixel_Rx is set to True");
1319 if (oldPixel and (thisParameterType == 4))
1320 {
ATH_MSG_INFO(
"Pixel Ry DoF has been skipped in the solving because Remove_Pixel_Ry is set to True");
1324 if (oldPixel and (thisParameterType == 5))
1325 {
ATH_MSG_INFO(
"Pixel Rz DoF has been skipped in the solving because Remove_Pixel_Rz is set to True");
1330 if (ibl and (thisParameterType == 0))
1331 {
ATH_MSG_INFO(
"IBL Tx DoF has been skipped in the solving because Remove_IBL_Tx is set to True");
1335 if (ibl and (thisParameterType == 1))
1336 {
ATH_MSG_INFO(
"IBL Ty DoF has been skipped in the solving because Remove_IBL_Ty is set to True");
1340 if (ibl and (thisParameterType == 2))
1341 {
ATH_MSG_INFO(
"IBL Tz DoF has been skipped in the solving because Remove_IBL_Tz is set to True");
1345 if (ibl and (thisParameterType == 3))
1346 {
ATH_MSG_INFO(
"IBL Rx DoF has been skipped in the solving because Remove_IBL_Rx is set to True");
1350 if (ibl and (thisParameterType == 4))
1351 {
ATH_MSG_INFO(
"IBL Ry DoF has been skipped in the solving because Remove_IBL_Ry is set to True");
1355 if (ibl and (thisParameterType == 5))
1356 {
ATH_MSG_INFO(
"IBL Rz DoF has been skipped in the solving because Remove_IBL_Rz is set to True");
1378 ATH_MSG_INFO(
"Spurious removal not implemented at the moment.");
1456 (*m_bigvector)[irow] += firstderiv;
1462 (*m_bigmatrix)[irow][icol] += secondderiv;
1470 AlignModuleList::const_iterator imod = alignModules->begin();
1471 AlignModuleList::const_iterator imod_end = alignModules->end();
1472 for( ; imod!=imod_end; ++imod) {
1476 int thisNDoF = alignPars->
size();
1479 std::unique_ptr<CLHEP::HepSymMatrix> covsub;;
1481 covsub = std::make_unique<CLHEP::HepSymMatrix>(thisNDoF,0);
1482 for (
int i=0;i<thisNDoF;++i) {
1483 int ipar = alignPars->
at(i)->index();
1484 double sigma_i = alignPars->
at(i)->sigma();
1491 for (
int j=0;j<=i;++j) {
1492 int jpar = alignPars->
at(j)->index();
1493 double sigma_j = alignPars->
at(j)->sigma();
1500 (*covsub)[i][j] = (*cov)[iActive][jActive] * sigma_i * sigma_j;
1508 os <<
"--------------------------------------------------------------------------------" << std::endl;
1514 std::unique_ptr<CLHEP::HepSymMatrix> cov;
1516 int nsize = cov0->GetNrows();
1517 cov = std::make_unique<CLHEP::HepSymMatrix>(nsize,0);
1519 for(
int i=0; i<nsize; i++)
1520 for(
int j=0; j<=i; j++)
1521 (*cov)[i][j] = (*cov0)[i][j];
1531 os <<
"--------------------------------------------------------------------------------" << std::endl;
1532 os <<
"Alignment parameters for module: " << module->name() << std::endl;
1533 os <<
"Number of tracks passing: " << module->nTracks() << std::endl;
1535 os <<
"Number of hits too small: "<<module->nHits()<<
" < "<<
m_minNumHits<<
" Skipping the module\n";
1539 os <<
"Number of tracks too small: "<<module->nTracks()<<
" < "<<
m_minNumTrks<<
" Skipping the module\n";
1542 os <<
"Number of hits seen: " << module->nHits() << std::endl;
1543 os <<
"Number of tracks seen: " << module->nTracks() << std::endl;
1546 int thisNDoF = alignPars->
size();
1548 if(alignPars->
empty())
1549 os <<
"No active parameters" << std::endl;
1555 for ( ; ipar != ipar_end; ++ipar) {
1557 os << std::format(
"{:<10}{:<12.5g} +/- {:<12.5g}\n",
1565 CLHEP::HepSymMatrix corrsub(thisNDoF,0);
1566 for(
int irow=0; irow<thisNDoF; ++irow)
1567 for(
int icol=0; icol<=irow; ++icol)
1568 corrsub[irow][icol] = (*cov)[irow][icol] / sqrt((*cov)[irow][irow] * (*cov)[icol][icol]);
1569 os <<
"Local correlation matrix: " << corrsub << std::flush;
1585 *
m_logStream<<
"*************************************************************\n";
1586 *
m_logStream<<
"************** solving using Global method ****************\n";
1587 *
m_logStream<<
"************** using LAPACK ****************\n";
1588 *
m_logStream<<
"*************************************************************\n";
1594 for (
int iActive=0;iActive<
m_aNDoF;iActive++) {
1596 (*aBetterVec)[iActive] = (*m_bigvector)[i];
1597 for (
int jActive=0;jActive<
m_aNDoF;jActive++) {
1599 (*aBetterMat)[iActive][jActive] = (*m_bigmatrix)[i][j];
1606 ATH_MSG_WARNING(
"Scaling requested but scale not set. Not scaling matrix and vector.");
1613 ATH_MSG_DEBUG(
"Now Solving alignment using lapack diagonalization routine dspev...");
1616 const double tol = 1.e-20;
1618 double determ = (*aBetterMat).determinant();
1620 if (fabs(determ) < tol)
1625 std::unique_ptr<AlSymMat> d2Chi2 ;
1627 d2Chi2 = std::make_unique<AlSymMat>(*aBetterMat);
1629 clock_t starttime = clock();
1637 int info = (*aBetterMat).diagonalize(jobz,w,
z);
1642 clock_t stoptime = clock();
1643 double time_diag = (stoptime-starttime)/
double(CLOCKS_PER_SEC);
1644 ATH_MSG_INFO(
" - time spent diagonalizing the matrix: "<<time_diag<<
" s");
1646 double time_solve = 0.;
1648 starttime = clock();
1651 time_solve = (stoptime-starttime)/
double(CLOCKS_PER_SEC);
1652 ATH_MSG_INFO(
" - time spent solving the system: "<<time_solve<<
" s");
1654 *
m_logStream<<
"time spent for diagonalization: "<<time_diag<<
" s\n";
1655 *
m_logStream<<
"time spent for post-solving: "<<time_solve<<
" s\n";
1659 ATH_MSG_ERROR(
"Problem in diagonalization. Solving skipped.");
1661 *
m_logStream<<
"time spent for diagonalization: "<<time_diag<<
" s\n";
1665 *
m_logStream<<
"total time spent in solve: "<<time_diag+time_solve<<
" s\n";
1689 const double tol = 1.e-20;
1692 if (std::fabs(determ) < tol)
1698 if (fillvecmods==0) {
1703 if (
msgLvl(MSG::DEBUG)) {
1710 return StatusCode::SUCCESS;
1712 else if (fillvecmods==2)
1713 return StatusCode::FAILURE;
1769 return StatusCode::SUCCESS;
1777 if(
z.ncol() !=
size) {
1778 msg(MSG::ERROR)<<
"Eigenvector matrix has incorrect size : "<<
z.ncol()<<
" != "<<
size<<
endmsg;
1793 ATH_MSG_INFO(
"writing the eigenvectors in a matrix: "<<
z.nrow() <<
"x" <<
z.ncol());
1804 if (
sc!=StatusCode::SUCCESS)
1805 msg(MSG::ERROR)<<
"Problem writing eigenvector matrix"<<
endmsg;
1811 ATH_MSG_INFO(
"writing the eigenvectors in a vector: "<< w.size());
1817 if (
sc!=StatusCode::SUCCESS)
1818 msg(MSG::ERROR)<<
"Problem writing eigenvector matrix"<<
endmsg;
1821 sc =
z.Write(
"eigenvectors.txt",
false);
1822 if (
sc!=StatusCode::SUCCESS)
1823 msg(MSG::ERROR)<<
"Problem writing eigenvector matrix to text file"<<
endmsg;
1824 sc = w.WriteEigenvalueVec(
"eigenvalues.txt",
false);
1825 if (
sc!=StatusCode::SUCCESS)
1826 msg(MSG::ERROR)<<
"Problem writing eigenvalue vector to text file"<<
endmsg;
1832 const double eigenvalue_threshold = 1e-19;
1837 ATH_MSG_INFO(
" Starting the automatic Weak Mode Removal method");
1844 ATH_MSG_DEBUG(
"AlignPull vector size is: "<< (*AlignPull).size());
1847 bool wm_stop =
false;
1852 for(
int i=0; i<
size; i++) {
1854 (*Align_db)[i] = (-D[i]/w[i]);
1856 ATH_MSG_WARNING(
"postSolvingLapack: Scaling requested but scale not set. Not scaling matrix and vector.");
1858 (*Align_error_db)[i] = sqrt(1.0/w[i]/
m_scale);
1861 if (w[i]<eigenvalue_threshold) {
1863 <<
" removed as eigenvalue lower than the threshold " << eigenvalue_threshold
1865 (*AlignPull)[i] = 0.0;
1869 (*AlignPull)[i] = (*Align_db)[i] / (*Align_error_db)[i];
1871 ATH_MSG_DEBUG(i <<
". AlignPar: " << (*Align_db)[i] <<
" +- " << (*Align_error_db)[i]
1872 <<
" (pull: " << (*AlignPull)[i] <<
") ; w[i]: " << w[i]);
1885 <<
" removed as pull is lower than " <<
m_pullcut <<
": "
1886 << (*AlignPull)[i]);
1907 <<
" removed as diff between eigenvalues, " << w[i] <<
" and " << w[i+1]
1927 if ( fabs((*Align_db)[i]) >
m_Align_db_step*fabs((*Align_db)[i+1]) ) {
1929 <<
" removed as diff between corrections, " << w[i] <<
" and " << w[i+1]
1930 <<
", is greater than "
1944 delete Align_error_db;
1947 Align_error_db =
nullptr;
1948 AlignPull =
nullptr;
2000 std::unique_ptr<CLHEP::HepSymMatrix> cov;
2004 cov = std::make_unique<CLHEP::HepSymMatrix>(
size,0);
2007 *
m_logStream<<
"/------ The Eigenvalue Spectrum -------\n";
2009 for (
int i=0;i<
size;i++) {
2011 for(
int j=0;j<
size;j++)
2012 thisdelta[j] =
z[i][j] * (-D[i]/w[i]);
2013 deltafull += thisdelta;
2019 *
m_logStream<<
"| skipping eigenvalue "<<w[i]<<
"\n";
2024 *
m_logStream<<
"| skipping eigenvalue "<<w[i]<<
"\n";
2031 for(
int j=0;j<
size;j++) {
2032 errSq[j] +=
z[i][j] *
z[i][j] / w[i];
2034 for(
int k=0;k<=j;k++)
2035 (*cov)[j][k] +=
z[i][j] *
z[i][k] / w[i];
2042 *
m_logStream<<
"\\----- End of Eigenvalue Spectrum -----\n";
2049 for(
int i=0; i<
size; i++) {
2051 double param = delta[i];
2052 double err = sqrt(2.*std::fabs(errSq[i]));
2055 AlignPar * alignPar=(*alignParList)[idof];
2058 double sigma = alignPar->
sigma();
2068 ATH_MSG_DEBUG(
"cov("<<i<<
")="<<errSq[i]<<
", sigma: "<<sigma);
2070 alignPar->
setPar(param, err);
2071 ATH_MSG_DEBUG(
"set param to "<<param<<
" for alignPar "<<alignPar);
2079 double norm1st = dChi2->
norm();
2082 *
m_logStream<<
"norm of first derivative : "<<norm1st<<
"\n";
2086 double dist = ( (*d2Chi2) * deltafull + (*dChi2) ).norm();
2089 *
m_logStream<<
"distance to solution : "<<dist<<
"\n";
2092 double chi2 = delta * (*d2Chi2) * delta * .5;
2106 *
m_logStream<<
"*************************************************************\n";
2107 *
m_logStream<<
"************** solving using Global method ****************\n";
2108 *
m_logStream<<
"************** using SparseEigen ****************\n";
2109 *
m_logStream<<
"*************************************************************\n";
2113 clock_t starttime = clock();
2118 bool isCopy =
false;
2120 ATH_MSG_INFO(
"Converting Matrix Format for fast solving");
2125 ATH_MSG_INFO(
"Matrix format native to the fast solving");
2129 ATH_MSG_ERROR(
"Cannot cast to neither AlSymMat nor AlSpaMat");
2137 const AlSpaMat * chkMatrix = ABetterMat;
2143 for (
int iActive=0;iActive<
m_aNDoF;iActive++) {
2145 (*aBetterVec)[iActive] = (*m_bigvector)[i];
2146 for (
int jActive=0;jActive<
m_aNDoF;jActive++) {
2149 if ( (*chkMatrix)[iActive][jActive] != 0. )
2150 (*aBetterMat)[iActive][jActive]=(*ABetterMat)[i][j];
2155 AlVec origVec(*aBetterVec);
2160 int info = (*aBetterMat).SolveWithEigen(*aBetterVec);
2168 ATH_MSG_ERROR(
"SolveWithEigen error code (0 if OK) = "<<info );
2170 *
m_logStream<<
"SolveWithEigen error code (0 if OK) = "<<info<<
"\n";
2175 ABetterMat =
nullptr;
2178 clock_t stoptime = clock();
2179 double totaltime = (stoptime-starttime)/
double(CLOCKS_PER_SEC);
2180 ATH_MSG_INFO(
"Time spent in SolveWithEigen: "<<totaltime<<
" s");
2185 for(
int i=0; i<
m_aNDoF; i++) {
2187 double param = -(*aBetterVec)[i];
2191 AlignPar * alignPar=(*alignParList)[idof];
2194 double sigma = alignPar->
sigma();
2200 alignPar->
setPar(param, err);
2201 ATH_MSG_DEBUG(
"set param to "<<param<<
" for alignPar "<<alignPar);
2206 std::unique_ptr<CLHEP::HepSymMatrix> cov;
2213 double dist = ( (*aBetterMat) * (*aBetterVec) - origVec ).norm();
2214 *
m_logStream<<
"distance to solution : "<<dist<<
"\n";
2217 double chi2 = (*aBetterVec) * (*aBetterMat) * (*aBetterVec) * .5;
2221 *
m_logStream<<
"time spent in solve : "<<totaltime<<
" s\n";
2241 int nModules = moduleList->size();
2243 AlMat hitmap(nModules,2);
2244 AlignModuleList::const_iterator imod = moduleList->begin();
2245 AlignModuleList::const_iterator imod_end = moduleList->end();
2247 for(; imod != imod_end; ++imod) {
2249 hitmap[
index][0] =
module->nHits();
2250 hitmap[
index][1] =
module->nTracks();
2258 StatusCode
sc = hitmap.
Write(
"hitmap.bin",
true);
2260 if (
sc!=StatusCode::SUCCESS)
2264 sc = hitmap.
Write(
"hitmap.txt",
false, 0);
2265 if (
sc!=StatusCode::SUCCESS)
2266 ATH_MSG_ERROR(
"Problem writing hitmap matrix to text file");
2278 int nModules = moduleList->size();
2280 AlMat hitmap(nModules,2);
2282 for(
int imap=0;imap<nFiles; imap++) {
2283 AlMat nextmap(nModules,2);
2292 if(nextmap.
nrow()!=nModules || nextmap.
ncol()!=2) {
2294 <<nextmap.
nrow()<<
" x "<<nextmap.
ncol()<<
"), should be ("<<nModules<<
" x 2). Skipping.");
2301 AlignModuleList::const_iterator imod = moduleList->begin();
2302 AlignModuleList::const_iterator imod_end = moduleList->end();
2305 for(; imod != imod_end; ++imod) {
2309 module->setNHits((int)hitmap[index][0]);
2310 module->setNTracks((int)hitmap[index][1]);
2311 totalhits += (int)hitmap[
index][0];
2319 ATH_MSG_INFO(
"Hitmap accumulated from "<<nFiles<<
" files with total of "<<totalhits<<
" hits.");
class TMatrixTSparse< double > TMatrixDSparse
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_INFO(x,...)
static const uint32_t nHits
size_t size() const
Number of registered mappings.
bool msgLvl(const MSG::Level lvl) const
DataModel_detail::const_iterator< DataVector > const_iterator
Standard const_iterator.
const T * at(size_type n) const
Access an element, as an rvalue.
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
bool empty() const noexcept
Returns true if the collection is empty.
contains the implementation of the methods of class AlMat, for handling general NxM matrices
StatusCode ReadScalaPack(const std::string &)
StatusCode Write(const std::string &, bool, unsigned int precision=6)
void SetPathBin(const std::string &)
void SetPathTxt(const std::string &)
contains the implementation for handling sparse matrices
virtual StatusCode Read(const std::string &, int &, bool &, float &) override final
contains the base implementation for handling symmertic matrices
contains the implementation for handling symmetric matrices in triangular representation
virtual StatusCode Read(const std::string &, int &, bool &, float &) override final
void SetPathBin(const std::string &)
StatusCode ReadPartial(const std::string &, double &, std::map< int, unsigned long long > &, float &)
void SetPathTxt(const std::string &)
double sigma() const
returns sigma
void setPar(double par, double err)
sets final parameter and error
double initPar() const
returns initial parameter and error
double chi2(TH1 *h0, TH1 *h1)
void Scale(TH1 *h, double d=1)
Ensure that the ATLAS eigen extensions are properly loaded.
std::vector< AlignModule * > AlignModuleList
@ z
global position (cartesian)