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);
79 return StatusCode::FAILURE;
82 ATH_MSG_INFO(
"Retrieving data from the following files: ");
87 return StatusCode::SUCCESS;
95 return StatusCode::SUCCESS;
102 ATH_MSG_INFO(
"allocating matrix and vector with nDoF = "<<nDoF);
124 return StatusCode::SUCCESS;
137 *
m_logStream<<
"*************************************************************\n";
138 *
m_logStream<<
"************** solving using Global method ****************\n";
139 *
m_logStream<<
"************** using ROOT ****************\n";
140 *
m_logStream<<
"*************************************************************\n";
144 clock_t starttime = clock();
152 if (
msgLvl(MSG::VERBOSE)) {
153 msg(MSG::VERBOSE)<<
"dumping matrix and vector to screen"<<
endmsg;
154 for (
int i=0;i<nDoF;i++)
155 for (
int j=0;j<nDoF;j++)
157 msg(MSG::VERBOSE)<<i<<
", "<<j<<
" : "<<(*m_bigmatrix)[i][j] <<
endmsg;
159 for (
int i=0;i<nDoF;i++)
160 msg(MSG::VERBOSE)<<i <<
" : "<<(*m_bigvector)[i]<<
endmsg;
165 double * firstderiv =
new double[
m_aNDoF];
166 for (
int iActive=0;iActive<
m_aNDoF;iActive++) {
168 firstderiv[iActive] = (*m_bigvector)[i];
169 for (
int jActive=0;jActive<
m_aNDoF;jActive++) {
171 secderiv[iActive*
m_aNDoF+jActive] = (*m_bigmatrix)[i][j];
180 TVectorD b(
m_aNDoF,firstderiv);
183 msg(MSG::DEBUG)<<
"First derivatives:"<<
endmsg;
185 msg(MSG::DEBUG)<<
"Second derivatives:"<<
endmsg;
191 TMatrixDSym ainv(c.Invert(status));
193 TVectorD
r(b.GetNrows());
195 r = c.Solve(b,status);
198 clock_t stoptime = clock();
199 double totaltime = (stoptime-starttime)/
double(CLOCKS_PER_SEC);
200 ATH_MSG_INFO(
"Time spent in solveROOT: "<<totaltime<<
" s");
203 msg(MSG::ERROR)<<
"ROOT inversion failed"<<
endmsg;
213 for (
int iAdof=0;iAdof<
m_aNDoF;iAdof++) {
216 AlignPar * alignPar=(*alignParList)[idof];
218 double sigma = alignPar->
sigma();
219 double param = -
r[iAdof] * sigma;
220 double err = std::sqrt(2.*std::fabs(ainv(iAdof,iAdof))) * sigma;
223 ATH_MSG_DEBUG(
"ainv("<<iAdof<<
")="<<ainv(iAdof,iAdof)<<
", sigma: "<<sigma);
225 alignPar->
setPar(param,err);
226 ATH_MSG_DEBUG(
"set param to "<<param<<
" for alignPar "<<alignPar);
237 *
m_logStream<<
"norm of first derivative : "<<sqrt(b.Norm2Sqr())<<
"\n";
240 double dist = sqrt( ( b - (
a *
r) ).Norm2Sqr() );
241 *
m_logStream<<
"distance to solution : "<<dist<<
"\n";
244 double chi2 =
a.Similarity(
r) * .5;
248 *
m_logStream<<
"time spent in solve : "<<totaltime<<
" s\n";
253 delete [] firstderiv;
263 *
m_logStream<<
"*************************************************************\n";
264 *
m_logStream<<
"************** solving using Global method ****************\n";
265 *
m_logStream<<
"************** using CLHEP ****************\n";
266 *
m_logStream<<
"*************************************************************\n";
270 clock_t starttime = clock();
274 for (
int i=0;i<(int)alignParList->
size();i++)
281 msg(MSG::DEBUG)<<
"dumping matrix and vector to screen"<<
endmsg;
282 for (
int i=0;i<nDoF;i++)
283 for (
int j=0;j<nDoF;j++)
285 msg(MSG::DEBUG)<<i<<
", "<<j<<
" : "<<(*m_bigmatrix)[i][j] <<
endmsg;
287 for (
int i=0;i<nDoF;i++)
288 msg(MSG::DEBUG)<<i <<
" : "<<(*m_bigvector)[i]<<
endmsg;
292 CLHEP::HepSymMatrix * d2Chi2 =
new CLHEP::HepSymMatrix(
m_aNDoF,0);
293 CLHEP::HepVector * dChi2 =
new CLHEP::HepVector(
m_aNDoF,0);
294 for (
int iActive=0;iActive<
m_aNDoF;iActive++) {
296 (*dChi2)[iActive] = (*m_bigvector)[i];
297 for (
int jActive=0;jActive<
m_aNDoF;jActive++) {
299 (*d2Chi2)[iActive][jActive] = (*m_bigmatrix)[i][j];
306 CLHEP::HepSymMatrix cov(
m_aNDoF,0);
307 CLHEP::HepVector delta(
m_aNDoF,0);
308 CLHEP::HepVector deltafull(
m_aNDoF,0);
322 msg(MSG::ERROR)<<
"CLHEP inversion status flag = "<<ierr<<
endmsg;
326 *
m_logStream<<
"CLHEP inversion status flag = "<<ierr<<
"\n";
329 delta = cov * (*dChi2);
339 CLHEP::HepSymMatrix cov2 = *d2Chi2 * .5;
344 msg(MSG::WARNING)<<
"Second CLHEP inversion status flag = "<<ierr2<<
endmsg;
346 CLHEP::HepVector delta2 = cov2 * (*dChi2) * .5;
347 for (
int i=0;i<delta.num_row(); ++i)
348 if ( fabs((delta[i] - delta2[i])/delta[i]) > 1e-5 ) {
349 msg(MSG::WARNING)<<
"Something's wrong with the matrix inversion: delta["<<i<<
"] = "<<delta[i]<<
" delta2["<<i<<
"] = "<<delta2[i]<<
endmsg;
355 *
m_logStream<<
"CLHEP inversion status flag for halfed matrix = "<<ierr2<<
"\n";
368 CLHEP::HepSymMatrix D = *d2Chi2;
369 CLHEP::HepMatrix U = CLHEP::diagonalize( &D );
377 for (
int i=0; i<
m_aNDoF-1; i++)
378 for (
int j=i+1; j<
m_aNDoF; j++)
379 if(D[j][j] < D[i][i]) {
394 CLHEP::HepVector eigenvector(
m_aNDoF);
397 *
m_logStream<<
"/------ The Eigenvalue Spectrum -------\n";
400 for(
int imode=0; imode<
m_aNDoF; ++imode) {
403 for(
int irow=0; irow<
m_aNDoF; ++irow)
404 eigenvector[irow] = U[irow][imode];
408 double eigenvalue = D[imode][imode];
411 double evdotb =
dot(*dChi2,eigenvector);
412 CLHEP::HepVector thisdelta = evdotb/eigenvalue * eigenvector;
413 deltafull += thisdelta;
418 *
m_logStream<<
"| skipping eigenvalue "<<eigenvalue<<
"\n";
423 *
m_logStream<<
"| skipping eigenvalue "<<eigenvalue<<
"\n";
432 for(
int irow=0; irow<
m_aNDoF; ++irow)
433 for(
int icol=0; icol<=irow; ++icol)
434 cov[irow][icol] += eigenvector[irow] * eigenvector[icol] / eigenvalue;
444 *
m_logStream<<
"\\----- End of Eigenvalue Spectrum -----\n";
451 clock_t stoptime = clock();
452 double totaltime = (stoptime-starttime)/
double(CLOCKS_PER_SEC);
453 ATH_MSG_INFO(
"Time spent in solveCLHEP: "<<totaltime<<
" s");
455 if(ierr==0 && status)
458 for (
int iAdof=0;iAdof<
m_aNDoF;iAdof++) {
461 AlignPar * alignPar=(*alignParList)[idof];
463 double sigma = alignPar->
sigma();
464 double param = -delta[iAdof] * sigma;
465 double err = std::sqrt(2.*std::fabs(cov[iAdof][iAdof])) * sigma;
468 ATH_MSG_DEBUG(
"cov("<<iAdof<<
")="<<cov[iAdof][iAdof]<<
", sigma: "<<sigma);
470 alignPar->
setPar(param,err);
471 ATH_MSG_DEBUG(
"set param to "<<param<<
" for alignPar "<<alignPar);
479 *
m_logStream<<
"norm of first derivative : "<<dChi2->norm()<<
"\n";
482 double dist = ( - (*d2Chi2) * deltafull + (*dChi2) ).norm();
483 *
m_logStream<<
"distance to solution : "<<dist<<
"\n";
486 double chi2 = d2Chi2->similarity(delta) * .5;
490 *
m_logStream<<
"time spent in solve : "<<totaltime<<
" s\n";
505 *
m_logStream<<
"*************************************************************\n";
506 *
m_logStream<<
"************** solving using Local method *****************\n";
507 *
m_logStream<<
"*************************************************************\n";
511 double totalChi2(0.);
515 AlignModuleList::const_iterator imod = alignModules->begin();
516 AlignModuleList::const_iterator imod_end = alignModules->end();
517 for( ; imod!=imod_end; ++imod) {
525 int thisNDoF = alignPars->
size();
527 CLHEP::HepSymMatrix d2Chi2(thisNDoF,0);
528 CLHEP::HepVector dChi2(thisNDoF,0);
529 for (
int i=0;i<thisNDoF;++i) {
530 int ipar = alignPars->
at(i)->index();
531 dChi2[i] = (*m_bigvector)[ipar];
532 for (
int j=0;j<thisNDoF;++j) {
533 int jpar = alignPars->
at(j)->index();
534 d2Chi2[i][j] = (*m_bigmatrix)[ipar][jpar];
542 ATH_MSG_INFO(
"Not enough hits in module \'"<<module->name()<<
"\': "
558 totalNDoF += thisNDoF;
560 CLHEP::HepSymMatrix cov(d2Chi2);
571 CLHEP::HepVector delta = cov * dChi2;
579 for (
int idof=0;idof<thisNDoF;++idof) {
582 double sigma = alignPar->
sigma();
583 double param = -delta[idof] * sigma;
584 double err = std::sqrt(2.*std::fabs(cov[idof][idof])) * sigma;
587 ATH_MSG_DEBUG(
"cov("<<idof<<
")="<<cov[idof][idof]<<
", sigma: "<<sigma);
590 ATH_MSG_DEBUG(
"Filling constants obtained using Local method");
591 alignPar->
setPar(param,err);
592 ATH_MSG_DEBUG(
"set param to "<<param<<
" for alignPar "<<alignPar);
599 *
m_logStream<<
"CLHEP inversion status flag = "<<ierr<<
"\n";
602 double chi2 = d2Chi2.similarity(delta) * .5;
604 *
m_logStream<<
"delta(chi2) of the alignment change : "<<
chi2<<
" / "<<thisNDoF<<
"\n";
609 *
m_logStream<<
"--------------------------------------------------------------------------------\n";
610 *
m_logStream<<
"Total delta(chi2) of the alignment change from the local method : "<<totalChi2<<
" / "<<totalNDoF<<
"\n";
625 ATH_MSG_INFO(
"Info to obtained from from Binary files");
636 int nDoF=alignParList->
size();
638 std::map<int,unsigned long long> modIndexMap;
639 float dummyVersion(0.);
640 double totalscale=0.;
645 AlVec newVector(nDoF);
646 std::map<int,unsigned long long> newModIndexMap;
652 if (
sc==StatusCode::FAILURE) {
657 msg(MSG::FATAL) <<
"vector wrong size! newVector size "<<newVector.
size()
664 modIndexMap = std::move(newModIndexMap);
665 else if (modIndexMap!=newModIndexMap) {
666 msg(MSG::FATAL)<<
"module index maps don't agree!"<<
endmsg;
685 int nDoF=modIndexMap.size();
691 if (
sc==StatusCode::SUCCESS)
692 *symBigMatrix += newMatrix;
696 throw std::logic_error(
"Unhandled matrix type");
702 if (
sc==StatusCode::SUCCESS) {
704 *spaBigMatrix += newMatrix;
706 *spaBigMatrix = newMatrix;
710 if (
sc==StatusCode::FAILURE) {
716 ATH_MSG_WARNING(
"matrix not expected format! Changing m_wSqMatrix to "<<!triang);
738 int nDoF = alignParList->
size();
745 double *val =
new double[nDoF];
746 for (
int i=0;i<nDoF;i++) {
747 val[i] = (*m_bigvector)[i];
750 TVectorD myTVector(nDoF, val);
757 int nModules = moduleList->size();
759 double *hitmapA =
new double[nModules];
760 double *hitmapB =
new double[nModules];
761 AlignModuleList::const_iterator imod = moduleList->begin();
762 AlignModuleList::const_iterator imod_end = moduleList->end();
764 for(; imod != imod_end; ++imod) {
766 hitmapA[
index] = (double)module->nHits();
767 hitmapB[
index] = (double)module->nTracks();
771 TVectorD hitmapHits(nModules, hitmapA);
772 TVectorD hitmapTracks(nModules, hitmapB);
779 TFile myFile(filename,
"recreate");
780 hitmapHits.Write(
"Hits");
781 hitmapTracks.Write(
"Tracks");
782 myTMatrix->Write(
"Matrix");
783 myTVector.Write(
"Vector");
786 scale.Write(
"Scale");
789 double *moduleInfoA =
new double[nDoF];
790 double *dofInfoA =
new double[nDoF];
792 if (
sizeof(
unsigned long long) !=
sizeof(
double))
793 ATH_MSG_ERROR(
"Module Identifiers will not be saved. sizeof(double)!=sizeof(ulonglong)");
797 for (
int i=0;i<(int)alignPars->
size();i++) {
800 uint64_t
id = (*alignPars)[i]->alignModule()->identify().get_compact();
801 memcpy(&target, &
id,
sizeof(target));
802 moduleInfoA[i]=target;
804 uint64_t dof = (*alignPars)[i]->paramType();
805 memcpy(&target, &dof,
sizeof(target));
809 TVectorD moduleIDs(nDoF, moduleInfoA) ;
810 TVectorD moduleDoFs(nDoF,dofInfoA);
811 delete [] moduleInfoA;
812 moduleIDs.Write(
"ModuleID");
813 moduleDoFs.Write(
"dof");
828 int nDoF=alignParList->
size();
831 std::map<int,unsigned long long> modIndexMap;
832 std::map<int,unsigned long long> DoFMap;
833 double totalscale=0.;
841 int nModules = moduleList->size();
843 TVectorD TotalHits(nModules);
844 TVectorD TotalTracks(nModules);
846 int numberOfReadErrors = 0;
848 struct rusage myusage{};
849 int itworked = getrusage(RUSAGE_SELF,&myusage);
853 long intialMemUse = myusage.ru_maxrss;
855 for (
int ifile = 0; ifile < (int)
m_inputTFiles.size(); ifile++) {
863 itworked = getrusage(RUSAGE_SELF,&myusage);
865 ATH_MSG_DEBUG(
"Memory usage [MB], total " << myusage.ru_maxrss/1024 <<
", increase " << (myusage.ru_maxrss-intialMemUse)/1024);
869 if ( myFile->IsZombie() || !(myFile->IsOpen()) ) {
870 ++numberOfReadErrors;
875 std::map<int,unsigned long long> newModIndexMap;
877 TVectorD* myModuleIDs;
878 myModuleIDs = (TVectorD*)myFile->Get(
"ModuleID");
880 ++numberOfReadErrors;
885 for (
int i(0); i<myModuleIDs->GetNrows(); ++i){
887 double source = (*myModuleIDs)(i);
889 memcpy(&target, &source,
sizeof(target));
890 newModIndexMap[i]=target;
896 std::map<int,unsigned long long> newDoFMap;
899 myDoFs = (TVectorD*)myFile->Get(
"dof");
901 ++numberOfReadErrors;
906 for (
int i(0); i<myDoFs->GetNrows(); ++i){
908 double source = (*myDoFs)(i);
910 memcpy(&target, &source,
sizeof(target));
917 Scale = (TVectorD*)myFile->Get(
"Scale");
919 ++numberOfReadErrors;
924 double scale=(*Scale)(0);
930 TVectorD*
vector = (TVectorD*)myFile->Get(
"Vector");
932 ++numberOfReadErrors;
942 msg(MSG::FATAL) <<
"vector wrong size! newVector size " << newVector->
size()
950 msg(MSG::FATAL) <<
"File vector wrong size! File Vector size " <<
vector->GetNrows()
958 for (
int i=0;i<nDoF;i++) {
959 (*newVector)[i] = (*vector)(i);
965 DoFMap = std::move(newDoFMap);
966 }
else if (DoFMap!=newDoFMap) {
967 msg(MSG::FATAL) <<
"module dofs don't agree!" <<
endmsg;
972 modIndexMap = newModIndexMap;
973 }
else if (modIndexMap!=newModIndexMap) {
974 msg(MSG::FATAL) <<
"module index maps don't agree!" <<
endmsg;
991 ++numberOfReadErrors;
1003 for (
int ii=0;ii<nDoF;ii++) {
1004 const TMatrixTSparseRow_const<double> myRow = (*matrix)[ii];
1005 int i = myRow.GetRowIndex();
1006 for (
int jj=0;jj<myRow.GetNindex();jj++) {
1007 int j = (myRow.GetColPtr())[jj];
1008 const double myElement= (myRow.GetDataPtr())[jj];
1012 i = (myRow.GetColPtr())[jj];
1014 (*accumMatrix)[i][j] = myElement;
1019 }
else if ( accumMatrix) {
1022 for (
int ii=0;ii<nDoF;ii++) {
1023 const TMatrixTSparseRow_const<double> myRow = (*matrix)[ii];
1024 int i = myRow.GetRowIndex();
1025 for (
int jj=0;jj<myRow.GetNindex();jj++) {
1026 int j = (myRow.GetColPtr())[jj];
1027 const double myElement= (myRow.GetDataPtr())[jj];
1031 i = (myRow.GetColPtr())[jj];
1033 (*accumMatrix)[i][j] += myElement;
1040 ++numberOfReadErrors;
1051 hits = (TVectorD*)myFile->Get(
"Hits");
1053 ++numberOfReadErrors;
1058 tracks = (TVectorD*)myFile->Get(
"Tracks");
1061 ++numberOfReadErrors;
1066 if(hits->GetNrows() != TotalHits.GetNrows() ){
1069 ++numberOfReadErrors;
1074 TotalHits += (*hits);
1075 TotalTracks += (*tracks);
1083 itworked = getrusage(RUSAGE_SELF,&myusage);
1084 ATH_MSG_DEBUG(
"Memory usage [MB], total " << myusage.ru_maxrss/1024 <<
", increase " << (myusage.ru_maxrss-intialMemUse)/1024);
1095 for (
int i=0;i<nDoF;i++) {
1096 for (
int j=0;j<=i;j++) {
1097 newMatrix[i][j] = (*accumMatrix)[i][j];
1101 *symBigMatrix += newMatrix;
1103 }
else if (spaBigMatrix) {
1105 *spaBigMatrix += *accumMatrix;
1113 AlignModuleList::const_iterator imod = moduleList->begin();
1114 AlignModuleList::const_iterator imod_end = moduleList->end();
1117 for(; imod != imod_end; ++imod, ++
index ) {
1119 module->setNHits((int)TotalHits(index));
1120 module->setNTracks((int)TotalTracks(index));
1121 totalhits += (int)TotalHits(
index);
1152 double dummyVersion(2.);
1155 std::map<int,unsigned long long> modIndexMap;
1156 std::map<int,std::string> modNameMap;
1158 for (
int i=0;i<(int)alignPars->
size();i++) {
1159 modIndexMap[i]=(*alignPars)[i]->alignModule()->identify().get_compact();
1160 modNameMap [i]=(*alignPars)[i]->alignModule()->name();
1166 StatusCode sc2 =
m_bigvector->WritePartial(
"vector.bin",
true,
m_scale,modIndexMap,dummyVersion);
1167 if (!sc1.isSuccess() || !sc2.isSuccess()) {
1168 msg(MSG::ERROR)<<
"problem writing matrix or vector"<<
endmsg;
1181 if (!sc1.isSuccess() || !sc2.isSuccess()) {
1182 msg(MSG::ERROR)<<
"problem writing matrix or vector"<<
endmsg;
1208 ATH_MSG_DEBUG(
"rescaling the matrix/vector and applying the soft-mode-cut");
1211 int nDoF = alignParList->
size();
1217 for (
int i=0;i<nDoF;i++) {
1219 double sigma_i = (*alignParList)[i]->sigma();
1220 double softCut = 2 * pow( (*alignParList)[i]->softCut() , -2 );
1221 (*m_bigvector)[i] *= sigma_i;
1223 for (
int j=0;j<=i;j++) {
1225 if ((*chkMatrix)[i][j] != 0.) {
1226 double sigma_j = (*alignParList)[j]->sigma();
1227 (*m_bigmatrix)[i][j] *= sigma_i * sigma_j;
1237 (*alignParList)[i]->setFirstDeriv((*
m_bigvector)[i]/sigma_i);
1238 (*alignParList)[i]->setSecndDeriv((*
m_bigmatrix)[i][i]/sigma_i/sigma_i);
1244 for (
const datamap::value_type& p : *
m_bigmatrix->ptrMap()) {
1245 int i = p.first.first;
1246 int j = p.first.second;
1249 double sigma_i = (*alignParList)[i]->sigma();
1250 double sigma_j = (*alignParList)[j]->sigma();
1252 (*m_bigmatrix)[i][j] *= sigma_i * sigma_j;
1257 for (
int i=0;i<nDoF;i++) {
1259 double sigma_i = (*alignParList)[i]->sigma();
1260 (*m_bigvector)[i] *= sigma_i;
1262 double softCut = 2 * pow( (*alignParList)[i]->softCut() , -2 );
1266 (*alignParList)[i]->setFirstDeriv((*
m_bigvector)[i]/sigma_i);
1267 (*alignParList)[i]->setSecndDeriv((*
m_bigmatrix)[i][i]/sigma_i/sigma_i);
1271 unsigned long long OldPixelIdentifier = 37769216;
1272 unsigned long long IBLIdentifier = 33574912;
1274 unsigned long long SCT_ECA_8_Identifier = 218116096;
1275 std::string SCT_ECA_8_Name =
"SCT/EndcapA/Disk_8";
1280 ATH_MSG_INFO(
"Javi: Printing (*alignParList)[i]->alignModule()->identify32()");
1283 for(
int i=0;i<nDoF;i++)
1286 ATH_MSG_DEBUG((*alignParList)[i]->alignModule()->identify32());
1292 const auto & theParameterList = *alignParList;
1293 const auto & thisIdentifier = theParameterList[i]->alignModule()->identify32();
1294 const auto & thisName = theParameterList[i]->alignModule()->name();
1295 const auto & thisParameterType = theParameterList[i]->paramType();
1296 const bool oldPixel = (thisIdentifier == OldPixelIdentifier);
1297 const bool ibl = (thisIdentifier == IBLIdentifier);
1298 const bool SCTECA8 = (thisIdentifier == SCT_ECA_8_Identifier);
1299 const bool SCTECA8_n = (thisName.find(SCT_ECA_8_Name)!= std::string::npos);
1303 {
ATH_MSG_INFO(
"SCT ECA Last Disk DoF have been skipped in the solving because DeactivateSCT_ECA_LastDisk is set to True");
1306 {
ATH_MSG_INFO(
"SCT ECA Last Disk DoF have been skipped in the solving because DeactivateSCT_ECA_LastDisk is set to True");
1312 {
ATH_MSG_INFO(
"Pixel DoF have been skipped in the solving because AlignIBLbutNotPixel is set to True");
1317 {
ATH_MSG_INFO(
"IBL DoF have been skipped in the solving because AlignPixelbutNotIBL is set to True");
1323 if ( oldPixel and (thisParameterType == 0))
1324 {
ATH_MSG_INFO(
"Pixel Tx DoF has been skipped in the solving because Remove_Pixel_Tx is set to True");
1328 if ( oldPixel and (thisParameterType == 1))
1329 {
ATH_MSG_INFO(
"Pixel Ty DoF has been skipped in the solving because Remove_Pixel_Ty is set to True");
1333 if (oldPixel and (thisParameterType == 2))
1334 {
ATH_MSG_INFO(
"Pixel Tz DoF has been skipped in the solving because Remove_Pixel_Tz is set to True");
1338 if (oldPixel and (thisParameterType == 3))
1339 {
ATH_MSG_INFO(
"Pixel Rx DoF has been skipped in the solving because Remove_Pixel_Rx is set to True");
1343 if (oldPixel and (thisParameterType == 4))
1344 {
ATH_MSG_INFO(
"Pixel Ry DoF has been skipped in the solving because Remove_Pixel_Ry is set to True");
1348 if (oldPixel and (thisParameterType == 5))
1349 {
ATH_MSG_INFO(
"Pixel Rz DoF has been skipped in the solving because Remove_Pixel_Rz is set to True");
1354 if (ibl and (thisParameterType == 0))
1355 {
ATH_MSG_INFO(
"IBL Tx DoF has been skipped in the solving because Remove_IBL_Tx is set to True");
1359 if (ibl and (thisParameterType == 1))
1360 {
ATH_MSG_INFO(
"IBL Ty DoF has been skipped in the solving because Remove_IBL_Ty is set to True");
1364 if (ibl and (thisParameterType == 2))
1365 {
ATH_MSG_INFO(
"IBL Tz DoF has been skipped in the solving because Remove_IBL_Tz is set to True");
1369 if (ibl and (thisParameterType == 3))
1370 {
ATH_MSG_INFO(
"IBL Rx DoF has been skipped in the solving because Remove_IBL_Rx is set to True");
1374 if (ibl and (thisParameterType == 4))
1375 {
ATH_MSG_INFO(
"IBL Ry DoF has been skipped in the solving because Remove_IBL_Ry is set to True");
1379 if (ibl and (thisParameterType == 5))
1380 {
ATH_MSG_INFO(
"IBL Rz DoF has been skipped in the solving because Remove_IBL_Rz is set to True");
1402 ATH_MSG_INFO(
"Spurious removal not implemented at the moment.");
1480 (*m_bigvector)[irow] += firstderiv;
1486 (*m_bigmatrix)[irow][icol] += secondderiv;
1494 AlignModuleList::const_iterator imod = alignModules->begin();
1495 AlignModuleList::const_iterator imod_end = alignModules->end();
1496 for( ; imod!=imod_end; ++imod) {
1500 int thisNDoF = alignPars->
size();
1503 CLHEP::HepSymMatrix * covsub =
nullptr;
1505 covsub =
new CLHEP::HepSymMatrix(thisNDoF,0);
1506 for (
int i=0;i<thisNDoF;++i) {
1507 int ipar = alignPars->
at(i)->index();
1508 double sigma_i = alignPars->
at(i)->sigma();
1515 for (
int j=0;j<=i;++j) {
1516 int jpar = alignPars->
at(j)->index();
1517 double sigma_j = alignPars->
at(j)->sigma();
1524 (*covsub)[i][j] = (*cov)[iActive][jActive] * sigma_i * sigma_j;
1533 os <<
"--------------------------------------------------------------------------------" << std::endl;
1539 CLHEP::HepSymMatrix * cov =
nullptr;
1541 int nsize = cov0->GetNrows();
1542 cov =
new CLHEP::HepSymMatrix(nsize,0);
1544 for(
int i=0; i<nsize; i++)
1545 for(
int j=0; j<=i; j++)
1546 (*cov)[i][j] = (*cov0)[i][j];
1577 os <<
"--------------------------------------------------------------------------------" << std::endl;
1578 os <<
"Alignment parameters for module: " << module->name() << std::endl;
1579 os <<
"Number of tracks passing: " << module->nTracks() << std::endl;
1581 os <<
"Number of hits too small: "<<module->nHits()<<
" < "<<
m_minNumHits<<
" Skipping the module\n";
1585 os <<
"Number of tracks too small: "<<module->nTracks()<<
" < "<<
m_minNumTrks<<
" Skipping the module\n";
1588 os <<
"Number of hits seen: " << module->nHits() << std::endl;
1589 os <<
"Number of tracks seen: " << module->nTracks() << std::endl;
1592 int thisNDoF = alignPars->
size();
1594 if(alignPars->
empty())
1595 os <<
"No active parameters" << std::endl;
1601 for ( ; ipar != ipar_end; ++ipar) {
1603 os << std::format(
"{:<10}{:<12.5g} +/- {:<12.5g}\n",
1611 CLHEP::HepSymMatrix corrsub(thisNDoF,0);
1612 for(
int irow=0; irow<thisNDoF; ++irow)
1613 for(
int icol=0; icol<=irow; ++icol)
1614 corrsub[irow][icol] = (*cov)[irow][icol] / sqrt((*cov)[irow][irow] * (*cov)[icol][icol]);
1615 os <<
"Local correlation matrix: " << corrsub << std::flush;
1631 *
m_logStream<<
"*************************************************************\n";
1632 *
m_logStream<<
"************** solving using Global method ****************\n";
1633 *
m_logStream<<
"************** using LAPACK ****************\n";
1634 *
m_logStream<<
"*************************************************************\n";
1640 for (
int iActive=0;iActive<
m_aNDoF;iActive++) {
1642 (*aBetterVec)[iActive] = (*m_bigvector)[i];
1643 for (
int jActive=0;jActive<
m_aNDoF;jActive++) {
1645 (*aBetterMat)[iActive][jActive] = (*m_bigmatrix)[i][j];
1652 ATH_MSG_WARNING(
"Scaling requested but scale not set. Not scaling matrix and vector.");
1659 ATH_MSG_DEBUG(
"Now Solving alignment using lapack diagonalization routine dspev...");
1662 const double tol = 1.e-20;
1664 double determ = (*aBetterMat).determinant();
1666 if (fabs(determ) < tol)
1673 d2Chi2 =
new AlSymMat(*aBetterMat);
1675 clock_t starttime = clock();
1683 int info = (*aBetterMat).diagonalize(jobz,w,
z);
1688 clock_t stoptime = clock();
1689 double time_diag = (stoptime-starttime)/
double(CLOCKS_PER_SEC);
1690 ATH_MSG_INFO(
" - time spent diagonalizing the matrix: "<<time_diag<<
" s");
1692 double time_solve = 0.;
1694 starttime = clock();
1697 time_solve = (stoptime-starttime)/
double(CLOCKS_PER_SEC);
1698 ATH_MSG_INFO(
" - time spent solving the system: "<<time_solve<<
" s");
1700 *
m_logStream<<
"time spent for diagonalization: "<<time_diag<<
" s\n";
1701 *
m_logStream<<
"time spent for post-solving: "<<time_solve<<
" s\n";
1705 ATH_MSG_ERROR(
"Problem in diagonalization. Solving skipped.");
1707 *
m_logStream<<
"time spent for diagonalization: "<<time_diag<<
" s\n";
1711 *
m_logStream<<
"total time spent in solve: "<<time_diag+time_solve<<
" s\n";
1736 const double tol = 1.e-20;
1739 if (std::fabs(determ) < tol)
1745 if (fillvecmods==0) {
1750 if (
msgLvl(MSG::DEBUG)) {
1757 return StatusCode::SUCCESS;
1759 else if (fillvecmods==2)
1760 return StatusCode::FAILURE;
1816 return StatusCode::SUCCESS;
1824 if(
z.ncol() !=
size) {
1825 msg(MSG::ERROR)<<
"Eigenvector matrix has incorrect size : "<<
z.ncol()<<
" != "<<
size<<
endmsg;
1840 ATH_MSG_INFO(
"writing the eigenvectors in a matrix: "<<
z.nrow() <<
"x" <<
z.ncol());
1851 if (
sc!=StatusCode::SUCCESS)
1852 msg(MSG::ERROR)<<
"Problem writing eigenvector matrix"<<
endmsg;
1858 ATH_MSG_INFO(
"writing the eigenvectors in a vector: "<< w.size());
1864 if (
sc!=StatusCode::SUCCESS)
1865 msg(MSG::ERROR)<<
"Problem writing eigenvector matrix"<<
endmsg;
1868 sc =
z.Write(
"eigenvectors.txt",
false);
1869 if (
sc!=StatusCode::SUCCESS)
1870 msg(MSG::ERROR)<<
"Problem writing eigenvector matrix to text file"<<
endmsg;
1871 sc = w.WriteEigenvalueVec(
"eigenvalues.txt",
false);
1872 if (
sc!=StatusCode::SUCCESS)
1873 msg(MSG::ERROR)<<
"Problem writing eigenvalue vector to text file"<<
endmsg;
1879 const double eigenvalue_threshold = 1e-19;
1884 ATH_MSG_INFO(
" Starting the automatic Weak Mode Removal method");
1891 ATH_MSG_DEBUG(
"AlignPull vector size is: "<< (*AlignPull).size());
1894 bool wm_stop =
false;
1899 for(
int i=0; i<
size; i++) {
1901 (*Align_db)[i] = (-D[i]/w[i]);
1903 ATH_MSG_WARNING(
"postSolvingLapack: Scaling requested but scale not set. Not scaling matrix and vector.");
1905 (*Align_error_db)[i] = sqrt(1.0/w[i]/
m_scale);
1908 if (w[i]<eigenvalue_threshold) {
1910 <<
" removed as eigenvalue lower than the threshold " << eigenvalue_threshold
1912 (*AlignPull)[i] = 0.0;
1916 (*AlignPull)[i] = (*Align_db)[i] / (*Align_error_db)[i];
1918 ATH_MSG_DEBUG(i <<
". AlignPar: " << (*Align_db)[i] <<
" +- " << (*Align_error_db)[i]
1919 <<
" (pull: " << (*AlignPull)[i] <<
") ; w[i]: " << w[i]);
1932 <<
" removed as pull is lower than " <<
m_pullcut <<
": "
1933 << (*AlignPull)[i]);
1954 <<
" removed as diff between eigenvalues, " << w[i] <<
" and " << w[i+1]
1974 if ( fabs((*Align_db)[i]) >
m_Align_db_step*fabs((*Align_db)[i+1]) ) {
1976 <<
" removed as diff between corrections, " << w[i] <<
" and " << w[i+1]
1977 <<
", is greater than "
1991 delete Align_error_db;
1994 Align_error_db =
nullptr;
1995 AlignPull =
nullptr;
2047 CLHEP::HepSymMatrix * cov =
nullptr;
2051 cov =
new CLHEP::HepSymMatrix(
size,0);
2054 *
m_logStream<<
"/------ The Eigenvalue Spectrum -------\n";
2056 for (
int i=0;i<
size;i++) {
2058 for(
int j=0;j<
size;j++)
2059 thisdelta[j] =
z[i][j] * (-D[i]/w[i]);
2060 deltafull += thisdelta;
2066 *
m_logStream<<
"| skipping eigenvalue "<<w[i]<<
"\n";
2071 *
m_logStream<<
"| skipping eigenvalue "<<w[i]<<
"\n";
2078 for(
int j=0;j<
size;j++) {
2079 errSq[j] +=
z[i][j] *
z[i][j] / w[i];
2081 for(
int k=0;k<=j;k++)
2082 (*cov)[j][k] +=
z[i][j] *
z[i][k] / w[i];
2089 *
m_logStream<<
"\\----- End of Eigenvalue Spectrum -----\n";
2096 for(
int i=0; i<
size; i++) {
2098 double param = delta[i];
2099 double err = sqrt(2.*std::fabs(errSq[i]));
2102 AlignPar * alignPar=(*alignParList)[idof];
2105 double sigma = alignPar->
sigma();
2115 ATH_MSG_DEBUG(
"cov("<<i<<
")="<<errSq[i]<<
", sigma: "<<sigma);
2117 alignPar->
setPar(param, err);
2118 ATH_MSG_DEBUG(
"set param to "<<param<<
" for alignPar "<<alignPar);
2126 double norm1st = dChi2->
norm();
2129 *
m_logStream<<
"norm of first derivative : "<<norm1st<<
"\n";
2133 double dist = ( (*d2Chi2) * deltafull + (*dChi2) ).norm();
2136 *
m_logStream<<
"distance to solution : "<<dist<<
"\n";
2139 double chi2 = delta * (*d2Chi2) * delta * .5;
2154 *
m_logStream<<
"*************************************************************\n";
2155 *
m_logStream<<
"************** solving using Global method ****************\n";
2156 *
m_logStream<<
"************** using SparseEigen ****************\n";
2157 *
m_logStream<<
"*************************************************************\n";
2161 clock_t starttime = clock();
2166 bool isCopy =
false;
2168 ATH_MSG_INFO(
"Converting Matrix Format for fast solving");
2173 ATH_MSG_INFO(
"Matrix format native to the fast solving");
2177 ATH_MSG_ERROR(
"Cannot cast to neither AlSymMat nor AlSpaMat");
2185 const AlSpaMat * chkMatrix = ABetterMat;
2191 for (
int iActive=0;iActive<
m_aNDoF;iActive++) {
2193 (*aBetterVec)[iActive] = (*m_bigvector)[i];
2194 for (
int jActive=0;jActive<
m_aNDoF;jActive++) {
2197 if ( (*chkMatrix)[iActive][jActive] != 0. )
2198 (*aBetterMat)[iActive][jActive]=(*ABetterMat)[i][j];
2203 AlVec origVec(*aBetterVec);
2208 int info = (*aBetterMat).SolveWithEigen(*aBetterVec);
2216 ATH_MSG_ERROR(
"SolveWithEigen error code (0 if OK) = "<<info );
2218 *
m_logStream<<
"SolveWithEigen error code (0 if OK) = "<<info<<
"\n";
2223 ABetterMat =
nullptr;
2226 clock_t stoptime = clock();
2227 double totaltime = (stoptime-starttime)/
double(CLOCKS_PER_SEC);
2228 ATH_MSG_INFO(
"Time spent in SolveWithEigen: "<<totaltime<<
" s");
2233 for(
int i=0; i<
m_aNDoF; i++) {
2235 double param = -(*aBetterVec)[i];
2239 AlignPar * alignPar=(*alignParList)[idof];
2242 double sigma = alignPar->
sigma();
2248 alignPar->
setPar(param, err);
2249 ATH_MSG_DEBUG(
"set param to "<<param<<
" for alignPar "<<alignPar);
2254 CLHEP::HepSymMatrix * cov =
nullptr;
2261 double dist = ( (*aBetterMat) * (*aBetterVec) - origVec ).norm();
2262 *
m_logStream<<
"distance to solution : "<<dist<<
"\n";
2265 double chi2 = (*aBetterVec) * (*aBetterMat) * (*aBetterVec) * .5;
2269 *
m_logStream<<
"time spent in solve : "<<totaltime<<
" s\n";
2289 int nModules = moduleList->size();
2291 AlMat hitmap(nModules,2);
2292 AlignModuleList::const_iterator imod = moduleList->begin();
2293 AlignModuleList::const_iterator imod_end = moduleList->end();
2295 for(; imod != imod_end; ++imod) {
2297 hitmap[
index][0] =
module->nHits();
2298 hitmap[
index][1] =
module->nTracks();
2306 StatusCode
sc = hitmap.
Write(
"hitmap.bin",
true);
2308 if (
sc!=StatusCode::SUCCESS)
2312 sc = hitmap.
Write(
"hitmap.txt",
false, 0);
2313 if (
sc!=StatusCode::SUCCESS)
2314 ATH_MSG_ERROR(
"Problem writing hitmap matrix to text file");
2326 int nModules = moduleList->size();
2328 AlMat hitmap(nModules,2);
2330 for(
int imap=0;imap<nFiles; imap++) {
2331 AlMat nextmap(nModules,2);
2340 if(nextmap.
nrow()!=nModules || nextmap.
ncol()!=2) {
2342 <<nextmap.
nrow()<<
" x "<<nextmap.
ncol()<<
"), should be ("<<nModules<<
" x 2). Skipping.");
2349 AlignModuleList::const_iterator imod = moduleList->begin();
2350 AlignModuleList::const_iterator imod_end = moduleList->end();
2353 for(; imod != imod_end; ++imod) {
2357 module->setNHits((int)hitmap[index][0]);
2358 module->setNTracks((int)hitmap[index][1]);
2359 totalhits += (int)hitmap[
index][0];
2367 ATH_MSG_INFO(
"Hitmap accumulated from "<<nFiles<<
" files with total of "<<totalhits<<
" hits.");
class TMatrixTSparse< double > TMatrixDSparse
#define ATH_MSG_WARNING(x)
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
const datamap * ptrMap() const
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)