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 = 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);
864 ATH_MSG_DEBUG(
"Memory usage [MB], total " << myusage.ru_maxrss/1024 <<
", increase " << (myusage.ru_maxrss-intialMemUse)/1024);
868 if ( myFile->IsZombie() || !(myFile->IsOpen()) ) {
869 ++numberOfReadErrors;
874 std::map<int,unsigned long long> newModIndexMap;
876 TVectorD* myModuleIDs;
877 myModuleIDs = (TVectorD*)myFile->Get(
"ModuleID");
879 ++numberOfReadErrors;
884 for (
int i(0); i<myModuleIDs->GetNrows(); ++i){
886 double source = (*myModuleIDs)(i);
888 memcpy(&target, &source,
sizeof(target));
889 newModIndexMap[i]=target;
895 std::map<int,unsigned long long> newDoFMap;
898 myDoFs = (TVectorD*)myFile->Get(
"dof");
900 ++numberOfReadErrors;
905 for (
int i(0); i<myDoFs->GetNrows(); ++i){
907 double source = (*myDoFs)(i);
909 memcpy(&target, &source,
sizeof(target));
916 Scale = (TVectorD*)myFile->Get(
"Scale");
918 ++numberOfReadErrors;
923 double scale=(*Scale)(0);
929 TVectorD*
vector = (TVectorD*)myFile->Get(
"Vector");
931 ++numberOfReadErrors;
941 msg(MSG::FATAL) <<
"vector wrong size! newVector size " << newVector->
size()
949 msg(MSG::FATAL) <<
"File vector wrong size! File Vector size " <<
vector->GetNrows()
957 for (
int i=0;i<nDoF;i++) {
958 (*newVector)[i] = (*vector)(i);
965 }
else if (DoFMap!=newDoFMap) {
966 msg(MSG::FATAL) <<
"module dofs don't agree!" <<
endmsg;
971 modIndexMap = newModIndexMap;
972 }
else if (modIndexMap!=newModIndexMap) {
973 msg(MSG::FATAL) <<
"module index maps don't agree!" <<
endmsg;
990 ++numberOfReadErrors;
1002 for (
int ii=0;ii<nDoF;ii++) {
1003 const TMatrixTSparseRow_const<double> myRow = (*matrix)[ii];
1004 int i = myRow.GetRowIndex();
1005 for (
int jj=0;jj<myRow.GetNindex();jj++) {
1006 int j = (myRow.GetColPtr())[jj];
1007 const double myElement= (myRow.GetDataPtr())[jj];
1011 i = (myRow.GetColPtr())[jj];
1013 (*accumMatrix)[i][j] = myElement;
1018 }
else if ( accumMatrix) {
1021 for (
int ii=0;ii<nDoF;ii++) {
1022 const TMatrixTSparseRow_const<double> myRow = (*matrix)[ii];
1023 int i = myRow.GetRowIndex();
1024 for (
int jj=0;jj<myRow.GetNindex();jj++) {
1025 int j = (myRow.GetColPtr())[jj];
1026 const double myElement= (myRow.GetDataPtr())[jj];
1030 i = (myRow.GetColPtr())[jj];
1032 (*accumMatrix)[i][j] += myElement;
1039 ++numberOfReadErrors;
1050 hits = (TVectorD*)myFile->Get(
"Hits");
1052 ++numberOfReadErrors;
1057 tracks = (TVectorD*)myFile->Get(
"Tracks");
1060 ++numberOfReadErrors;
1065 if(hits->GetNrows() != TotalHits.GetNrows() ){
1068 ++numberOfReadErrors;
1073 TotalHits += (*hits);
1074 TotalTracks += (*tracks);
1082 itworked = getrusage(RUSAGE_SELF,&myusage);
1083 ATH_MSG_DEBUG(
"Memory usage [MB], total " << myusage.ru_maxrss/1024 <<
", increase " << (myusage.ru_maxrss-intialMemUse)/1024);
1094 for (
int i=0;i<nDoF;i++) {
1095 for (
int j=0;j<=i;j++) {
1096 newMatrix[i][j] = (*accumMatrix)[i][j];
1100 *symBigMatrix += newMatrix;
1102 }
else if (spaBigMatrix) {
1104 *spaBigMatrix += *accumMatrix;
1112 AlignModuleList::const_iterator imod = moduleList->begin();
1113 AlignModuleList::const_iterator imod_end = moduleList->end();
1116 for(; imod != imod_end; ++imod, ++
index ) {
1118 module->setNHits((int)TotalHits(index));
1119 module->setNTracks((int)TotalTracks(index));
1120 totalhits += (int)TotalHits(
index);
1151 double dummyVersion(2.);
1154 std::map<int,unsigned long long> modIndexMap;
1155 std::map<int,std::string> modNameMap;
1157 for (
int i=0;i<(int)alignPars->
size();i++) {
1158 modIndexMap[i]=(*alignPars)[i]->alignModule()->identify().get_compact();
1159 modNameMap [i]=(*alignPars)[i]->alignModule()->name();
1165 StatusCode sc2 =
m_bigvector->WritePartial(
"vector.bin",
true,
m_scale,modIndexMap,dummyVersion);
1166 if (!sc1.isSuccess() || !sc2.isSuccess()) {
1167 msg(MSG::ERROR)<<
"problem writing matrix or vector"<<
endmsg;
1180 if (!sc1.isSuccess() || !sc2.isSuccess()) {
1181 msg(MSG::ERROR)<<
"problem writing matrix or vector"<<
endmsg;
1207 ATH_MSG_DEBUG(
"rescaling the matrix/vector and applying the soft-mode-cut");
1210 int nDoF = alignParList->
size();
1216 for (
int i=0;i<nDoF;i++) {
1218 double sigma_i = (*alignParList)[i]->sigma();
1219 double softCut = 2 * pow( (*alignParList)[i]->softCut() , -2 );
1220 (*m_bigvector)[i] *= sigma_i;
1222 for (
int j=0;j<=i;j++) {
1224 if ((*chkMatrix)[i][j] != 0.) {
1225 double sigma_j = (*alignParList)[j]->sigma();
1226 (*m_bigmatrix)[i][j] *= sigma_i * sigma_j;
1236 (*alignParList)[i]->setFirstDeriv((*
m_bigvector)[i]/sigma_i);
1237 (*alignParList)[i]->setSecndDeriv((*
m_bigmatrix)[i][i]/sigma_i/sigma_i);
1243 for (
const datamap::value_type& p : *
m_bigmatrix->ptrMap()) {
1244 int i = p.first.first;
1245 int j = p.first.second;
1248 double sigma_i = (*alignParList)[i]->sigma();
1249 double sigma_j = (*alignParList)[j]->sigma();
1251 (*m_bigmatrix)[i][j] *= sigma_i * sigma_j;
1256 for (
int i=0;i<nDoF;i++) {
1258 double sigma_i = (*alignParList)[i]->sigma();
1259 (*m_bigvector)[i] *= sigma_i;
1261 double softCut = 2 * pow( (*alignParList)[i]->softCut() , -2 );
1265 (*alignParList)[i]->setFirstDeriv((*
m_bigvector)[i]/sigma_i);
1266 (*alignParList)[i]->setSecndDeriv((*
m_bigmatrix)[i][i]/sigma_i/sigma_i);
1270 unsigned long long OldPixelIdentifier = 37769216;
1271 unsigned long long IBLIdentifier = 33574912;
1273 unsigned long long SCT_ECA_8_Identifier = 218116096;
1274 std::string SCT_ECA_8_Name =
"SCT/EndcapA/Disk_8";
1279 ATH_MSG_INFO(
"Javi: Printing (*alignParList)[i]->alignModule()->identify32()");
1282 for(
int i=0;i<nDoF;i++)
1285 ATH_MSG_DEBUG((*alignParList)[i]->alignModule()->identify32());
1291 const auto & theParameterList = *alignParList;
1292 const auto & thisIdentifier = theParameterList[i]->alignModule()->identify32();
1293 const auto & thisName = theParameterList[i]->alignModule()->name();
1294 const auto & thisParameterType = theParameterList[i]->paramType();
1295 const bool oldPixel = (thisIdentifier == OldPixelIdentifier);
1296 const bool ibl = (thisIdentifier == IBLIdentifier);
1297 const bool SCTECA8 = (thisIdentifier == SCT_ECA_8_Identifier);
1298 const bool SCTECA8_n = (thisName.find(SCT_ECA_8_Name)!= std::string::npos);
1302 {
ATH_MSG_INFO(
"SCT ECA Last Disk DoF have been skipped in the solving because DeactivateSCT_ECA_LastDisk is set to True");
1305 {
ATH_MSG_INFO(
"SCT ECA Last Disk DoF have been skipped in the solving because DeactivateSCT_ECA_LastDisk is set to True");
1311 {
ATH_MSG_INFO(
"Pixel DoF have been skipped in the solving because AlignIBLbutNotPixel is set to True");
1316 {
ATH_MSG_INFO(
"IBL DoF have been skipped in the solving because AlignPixelbutNotIBL is set to True");
1322 if ( oldPixel and (thisParameterType == 0))
1323 {
ATH_MSG_INFO(
"Pixel Tx DoF has been skipped in the solving because Remove_Pixel_Tx is set to True");
1327 if ( oldPixel and (thisParameterType == 1))
1328 {
ATH_MSG_INFO(
"Pixel Ty DoF has been skipped in the solving because Remove_Pixel_Ty is set to True");
1332 if (oldPixel and (thisParameterType == 2))
1333 {
ATH_MSG_INFO(
"Pixel Tz DoF has been skipped in the solving because Remove_Pixel_Tz is set to True");
1337 if (oldPixel and (thisParameterType == 3))
1338 {
ATH_MSG_INFO(
"Pixel Rx DoF has been skipped in the solving because Remove_Pixel_Rx is set to True");
1342 if (oldPixel and (thisParameterType == 4))
1343 {
ATH_MSG_INFO(
"Pixel Ry DoF has been skipped in the solving because Remove_Pixel_Ry is set to True");
1347 if (oldPixel and (thisParameterType == 5))
1348 {
ATH_MSG_INFO(
"Pixel Rz DoF has been skipped in the solving because Remove_Pixel_Rz is set to True");
1353 if (ibl and (thisParameterType == 0))
1354 {
ATH_MSG_INFO(
"IBL Tx DoF has been skipped in the solving because Remove_IBL_Tx is set to True");
1358 if (ibl and (thisParameterType == 1))
1359 {
ATH_MSG_INFO(
"IBL Ty DoF has been skipped in the solving because Remove_IBL_Ty is set to True");
1363 if (ibl and (thisParameterType == 2))
1364 {
ATH_MSG_INFO(
"IBL Tz DoF has been skipped in the solving because Remove_IBL_Tz is set to True");
1368 if (ibl and (thisParameterType == 3))
1369 {
ATH_MSG_INFO(
"IBL Rx DoF has been skipped in the solving because Remove_IBL_Rx is set to True");
1373 if (ibl and (thisParameterType == 4))
1374 {
ATH_MSG_INFO(
"IBL Ry DoF has been skipped in the solving because Remove_IBL_Ry is set to True");
1378 if (ibl and (thisParameterType == 5))
1379 {
ATH_MSG_INFO(
"IBL Rz DoF has been skipped in the solving because Remove_IBL_Rz is set to True");
1401 ATH_MSG_INFO(
"Spurious removal not implemented at the moment.");
1479 (*m_bigvector)[irow] += firstderiv;
1485 (*m_bigmatrix)[irow][icol] += secondderiv;
1493 AlignModuleList::const_iterator imod = alignModules->begin();
1494 AlignModuleList::const_iterator imod_end = alignModules->end();
1495 for( ; imod!=imod_end; ++imod) {
1499 int thisNDoF = alignPars->
size();
1502 CLHEP::HepSymMatrix * covsub =
nullptr;
1504 covsub =
new CLHEP::HepSymMatrix(thisNDoF,0);
1505 for (
int i=0;i<thisNDoF;++i) {
1506 int ipar = alignPars->
at(i)->index();
1507 double sigma_i = alignPars->
at(i)->sigma();
1514 for (
int j=0;j<=i;++j) {
1515 int jpar = alignPars->
at(j)->index();
1516 double sigma_j = alignPars->
at(j)->sigma();
1523 (*covsub)[i][j] = (*cov)[iActive][jActive] * sigma_i * sigma_j;
1532 os <<
"--------------------------------------------------------------------------------" << std::endl;
1538 CLHEP::HepSymMatrix * cov =
nullptr;
1540 int nsize = cov0->GetNrows();
1541 cov =
new CLHEP::HepSymMatrix(nsize,0);
1543 for(
int i=0; i<nsize; i++)
1544 for(
int j=0; j<=i; j++)
1545 (*cov)[i][j] = (*cov0)[i][j];
1576 os <<
"--------------------------------------------------------------------------------" << std::endl;
1577 os <<
"Alignment parameters for module: " << module->name() << std::endl;
1578 os <<
"Number of tracks passing: " << module->nTracks() << std::endl;
1580 os <<
"Number of hits too small: "<<module->nHits()<<
" < "<<
m_minNumHits<<
" Skipping the module\n";
1584 os <<
"Number of tracks too small: "<<module->nTracks()<<
" < "<<
m_minNumTrks<<
" Skipping the module\n";
1587 os <<
"Number of hits seen: " << module->nHits() << std::endl;
1588 os <<
"Number of tracks seen: " << module->nTracks() << std::endl;
1591 int thisNDoF = alignPars->
size();
1593 if(alignPars->
empty())
1594 os <<
"No active parameters" << std::endl;
1600 for ( ; ipar != ipar_end; ++ipar) {
1602 os << std::format(
"{:<10}{:<12.5g} +/- {:<12.5g}\n",
1610 CLHEP::HepSymMatrix corrsub(thisNDoF,0);
1611 for(
int irow=0; irow<thisNDoF; ++irow)
1612 for(
int icol=0; icol<=irow; ++icol)
1613 corrsub[irow][icol] = (*cov)[irow][icol] / sqrt((*cov)[irow][irow] * (*cov)[icol][icol]);
1614 os <<
"Local correlation matrix: " << corrsub << std::flush;
1630 *
m_logStream<<
"*************************************************************\n";
1631 *
m_logStream<<
"************** solving using Global method ****************\n";
1632 *
m_logStream<<
"************** using LAPACK ****************\n";
1633 *
m_logStream<<
"*************************************************************\n";
1639 for (
int iActive=0;iActive<
m_aNDoF;iActive++) {
1641 (*aBetterVec)[iActive] = (*m_bigvector)[i];
1642 for (
int jActive=0;jActive<
m_aNDoF;jActive++) {
1644 (*aBetterMat)[iActive][jActive] = (*m_bigmatrix)[i][j];
1651 ATH_MSG_WARNING(
"Scaling requested but scale not set. Not scaling matrix and vector.");
1658 ATH_MSG_DEBUG(
"Now Solving alignment using lapack diagonalization routine dspev...");
1661 const double tol = 1.e-20;
1663 double determ = (*aBetterMat).determinant();
1665 if (fabs(determ) < tol)
1672 d2Chi2 =
new AlSymMat(*aBetterMat);
1674 clock_t starttime = clock();
1682 int info = (*aBetterMat).diagonalize(jobz,w,
z);
1687 clock_t stoptime = clock();
1688 double time_diag = (stoptime-starttime)/
double(CLOCKS_PER_SEC);
1689 ATH_MSG_INFO(
" - time spent diagonalizing the matrix: "<<time_diag<<
" s");
1691 double time_solve = 0.;
1693 starttime = clock();
1696 time_solve = (stoptime-starttime)/
double(CLOCKS_PER_SEC);
1697 ATH_MSG_INFO(
" - time spent solving the system: "<<time_solve<<
" s");
1699 *
m_logStream<<
"time spent for diagonalization: "<<time_diag<<
" s\n";
1700 *
m_logStream<<
"time spent for post-solving: "<<time_solve<<
" s\n";
1704 ATH_MSG_ERROR(
"Problem in diagonalization. Solving skipped.");
1706 *
m_logStream<<
"time spent for diagonalization: "<<time_diag<<
" s\n";
1710 *
m_logStream<<
"total time spent in solve: "<<time_diag+time_solve<<
" s\n";
1735 const double tol = 1.e-20;
1738 if (std::fabs(determ) < tol)
1744 if (fillvecmods==0) {
1749 if (
msgLvl(MSG::DEBUG)) {
1756 return StatusCode::SUCCESS;
1758 else if (fillvecmods==2)
1759 return StatusCode::FAILURE;
1815 return StatusCode::SUCCESS;
1823 if(
z.ncol() !=
size) {
1824 msg(MSG::ERROR)<<
"Eigenvector matrix has incorrect size : "<<
z.ncol()<<
" != "<<
size<<
endmsg;
1839 ATH_MSG_INFO(
"writing the eigenvectors in a matrix: "<<
z.nrow() <<
"x" <<
z.ncol());
1850 if (
sc!=StatusCode::SUCCESS)
1851 msg(MSG::ERROR)<<
"Problem writing eigenvector matrix"<<
endmsg;
1857 ATH_MSG_INFO(
"writing the eigenvectors in a vector: "<< w.size());
1863 if (
sc!=StatusCode::SUCCESS)
1864 msg(MSG::ERROR)<<
"Problem writing eigenvector matrix"<<
endmsg;
1867 sc =
z.Write(
"eigenvectors.txt",
false);
1868 if (
sc!=StatusCode::SUCCESS)
1869 msg(MSG::ERROR)<<
"Problem writing eigenvector matrix to text file"<<
endmsg;
1870 sc = w.WriteEigenvalueVec(
"eigenvalues.txt",
false);
1871 if (
sc!=StatusCode::SUCCESS)
1872 msg(MSG::ERROR)<<
"Problem writing eigenvalue vector to text file"<<
endmsg;
1878 const double eigenvalue_threshold = 1e-19;
1883 ATH_MSG_INFO(
" Starting the automatic Weak Mode Removal method");
1890 ATH_MSG_DEBUG(
"AlignPull vector size is: "<< (*AlignPull).size());
1893 bool wm_stop =
false;
1898 for(
int i=0; i<
size; i++) {
1900 (*Align_db)[i] = (-D[i]/w[i]);
1902 ATH_MSG_WARNING(
"postSolvingLapack: Scaling requested but scale not set. Not scaling matrix and vector.");
1904 (*Align_error_db)[i] = sqrt(1.0/w[i]/
m_scale);
1907 if (w[i]<eigenvalue_threshold) {
1909 <<
" removed as eigenvalue lower than the threshold " << eigenvalue_threshold
1911 (*AlignPull)[i] = 0.0;
1915 (*AlignPull)[i] = (*Align_db)[i] / (*Align_error_db)[i];
1917 ATH_MSG_DEBUG(i <<
". AlignPar: " << (*Align_db)[i] <<
" +- " << (*Align_error_db)[i]
1918 <<
" (pull: " << (*AlignPull)[i] <<
") ; w[i]: " << w[i]);
1931 <<
" removed as pull is lower than " <<
m_pullcut <<
": "
1932 << (*AlignPull)[i]);
1953 <<
" removed as diff between eigenvalues, " << w[i] <<
" and " << w[i+1]
1973 if ( fabs((*Align_db)[i]) >
m_Align_db_step*fabs((*Align_db)[i+1]) ) {
1975 <<
" removed as diff between corrections, " << w[i] <<
" and " << w[i+1]
1976 <<
", is greater than "
1990 delete Align_error_db;
1993 Align_error_db =
nullptr;
1994 AlignPull =
nullptr;
2046 CLHEP::HepSymMatrix * cov =
nullptr;
2050 cov =
new CLHEP::HepSymMatrix(
size,0);
2053 *
m_logStream<<
"/------ The Eigenvalue Spectrum -------\n";
2055 for (
int i=0;i<
size;i++) {
2057 for(
int j=0;j<
size;j++)
2058 thisdelta[j] =
z[i][j] * (-D[i]/w[i]);
2059 deltafull += thisdelta;
2065 *
m_logStream<<
"| skipping eigenvalue "<<w[i]<<
"\n";
2070 *
m_logStream<<
"| skipping eigenvalue "<<w[i]<<
"\n";
2077 for(
int j=0;j<
size;j++) {
2078 errSq[j] +=
z[i][j] *
z[i][j] / w[i];
2080 for(
int k=0;k<=j;k++)
2081 (*cov)[j][k] +=
z[i][j] *
z[i][k] / w[i];
2088 *
m_logStream<<
"\\----- End of Eigenvalue Spectrum -----\n";
2095 for(
int i=0; i<
size; i++) {
2097 double param = delta[i];
2098 double err = sqrt(2.*std::fabs(errSq[i]));
2101 AlignPar * alignPar=(*alignParList)[idof];
2104 double sigma = alignPar->
sigma();
2114 ATH_MSG_DEBUG(
"cov("<<i<<
")="<<errSq[i]<<
", sigma: "<<sigma);
2116 alignPar->
setPar(param, err);
2117 ATH_MSG_DEBUG(
"set param to "<<param<<
" for alignPar "<<alignPar);
2125 double norm1st = dChi2->
norm();
2128 *
m_logStream<<
"norm of first derivative : "<<norm1st<<
"\n";
2132 double dist = ( (*d2Chi2) * deltafull + (*dChi2) ).norm();
2135 *
m_logStream<<
"distance to solution : "<<dist<<
"\n";
2138 double chi2 = delta * (*d2Chi2) * delta * .5;
2153 *
m_logStream<<
"*************************************************************\n";
2154 *
m_logStream<<
"************** solving using Global method ****************\n";
2155 *
m_logStream<<
"************** using SparseEigen ****************\n";
2156 *
m_logStream<<
"*************************************************************\n";
2160 clock_t starttime = clock();
2165 bool isCopy =
false;
2167 ATH_MSG_INFO(
"Converting Matrix Format for fast solving");
2172 ATH_MSG_INFO(
"Matrix format native to the fast solving");
2176 ATH_MSG_ERROR(
"Cannot cast to neither AlSymMat nor AlSpaMat");
2184 const AlSpaMat * chkMatrix = ABetterMat;
2190 for (
int iActive=0;iActive<
m_aNDoF;iActive++) {
2192 (*aBetterVec)[iActive] = (*m_bigvector)[i];
2193 for (
int jActive=0;jActive<
m_aNDoF;jActive++) {
2196 if ( (*chkMatrix)[iActive][jActive] != 0. )
2197 (*aBetterMat)[iActive][jActive]=(*ABetterMat)[i][j];
2202 AlVec origVec(*aBetterVec);
2207 int info = (*aBetterMat).SolveWithEigen(*aBetterVec);
2215 ATH_MSG_ERROR(
"SolveWithEigen error code (0 if OK) = "<<info );
2217 *
m_logStream<<
"SolveWithEigen error code (0 if OK) = "<<info<<
"\n";
2222 ABetterMat =
nullptr;
2225 clock_t stoptime = clock();
2226 double totaltime = (stoptime-starttime)/
double(CLOCKS_PER_SEC);
2227 ATH_MSG_INFO(
"Time spent in SolveWithEigen: "<<totaltime<<
" s");
2232 for(
int i=0; i<
m_aNDoF; i++) {
2234 double param = -(*aBetterVec)[i];
2238 AlignPar * alignPar=(*alignParList)[idof];
2241 double sigma = alignPar->
sigma();
2247 alignPar->
setPar(param, err);
2248 ATH_MSG_DEBUG(
"set param to "<<param<<
" for alignPar "<<alignPar);
2253 CLHEP::HepSymMatrix * cov =
nullptr;
2260 double dist = ( (*aBetterMat) * (*aBetterVec) - origVec ).norm();
2261 *
m_logStream<<
"distance to solution : "<<dist<<
"\n";
2264 double chi2 = (*aBetterVec) * (*aBetterMat) * (*aBetterVec) * .5;
2268 *
m_logStream<<
"time spent in solve : "<<totaltime<<
" s\n";
2288 int nModules = moduleList->size();
2290 AlMat hitmap(nModules,2);
2291 AlignModuleList::const_iterator imod = moduleList->begin();
2292 AlignModuleList::const_iterator imod_end = moduleList->end();
2294 for(; imod != imod_end; ++imod) {
2296 hitmap[
index][0] =
module->nHits();
2297 hitmap[
index][1] =
module->nTracks();
2305 StatusCode
sc = hitmap.
Write(
"hitmap.bin",
true);
2307 if (
sc!=StatusCode::SUCCESS)
2311 sc = hitmap.
Write(
"hitmap.txt",
false, 0);
2312 if (
sc!=StatusCode::SUCCESS)
2313 ATH_MSG_ERROR(
"Problem writing hitmap matrix to text file");
2325 int nModules = moduleList->size();
2327 AlMat hitmap(nModules,2);
2329 for(
int imap=0;imap<nFiles; imap++) {
2330 AlMat nextmap(nModules,2);
2339 if(nextmap.
nrow()!=nModules || nextmap.
ncol()!=2) {
2341 <<nextmap.
nrow()<<
" x "<<nextmap.
ncol()<<
"), should be ("<<nModules<<
" x 2). Skipping.");
2348 AlignModuleList::const_iterator imod = moduleList->begin();
2349 AlignModuleList::const_iterator imod_end = moduleList->end();
2352 for(; imod != imod_end; ++imod) {
2356 module->setNHits((int)hitmap[index][0]);
2357 module->setNTracks((int)hitmap[index][1]);
2358 totalhits += (int)hitmap[
index][0];
2366 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)