ATLAS Offline Software
Loading...
Searching...
No Matches
MatrixTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5// MatrixTool.cxx
6
7// AlgTool for creating big matrix and vector, manipulation of entries, and
8// solving for alignment parameters
9// Robert Harrington, started 1/5/08 based on SiGlobalChi2Align
10
11#include "GaudiKernel/StatusCode.h"
12#include "GaudiKernel/MsgStream.h"
13
14#include "GaudiKernel/AlgTool.h"
15
21
27
28#include "CLHEP/Matrix/Matrix.h"
29#include "CLHEP/Matrix/SymMatrix.h"
30#include "CLHEP/Matrix/Vector.h"
31
32#include <TMatrixT.h>
33#include <TMatrixDSym.h>
34#include <TMatrixDSparse.h>
35#include <TVectorD.h>
36#include <TVectorT.h>
37#include <TString.h>
38#include <TFile.h>
39
40
41#include <TDecompBK.h>
42
43#include <cmath>
44#include <ctime>
45#include <algorithm>
46#include <format>
47#include <iterator>
48
49#include <sys/resource.h>
50
51namespace Trk {
52
53 //_______________________________________________________________________
54 MatrixTool::MatrixTool(const std::string& type, const std::string& name,
55 const IInterface* parent)
56 : IMatrixTool()
57 , AthAlgTool(type,name,parent)
58 {
59 declareInterface<IMatrixTool>(this);
60 }
61
62 //_______________________________________________________________________
64 {
65 delete m_bigmatrix;
66 delete m_bigvector;
67 }
68
69 //_______________________________________________________________________
71 {
72 ATH_MSG_DEBUG("initialize() of MatrixTool");
73
74 // get AlignModuleTool
75 if (m_alignModuleTool.retrieve().isSuccess())
76 ATH_MSG_INFO("Retrieved " << m_alignModuleTool);
77 else{
78 msg(MSG::FATAL) << "Could not get " << m_alignModuleTool << endmsg;
79 return StatusCode::FAILURE;
80 }
81
82 ATH_MSG_INFO("Retrieving data from the following files: ");
83 for (auto & inputVectorFile : m_inputVectorFiles) {
84 ATH_MSG_INFO(m_pathbin+inputVectorFile);
85 }
86
87 return StatusCode::SUCCESS;
88 }
89
90 //_______________________________________________________________________
92 {
93 ATH_MSG_DEBUG("finalize() of MatrixTool");
94
95 return StatusCode::SUCCESS;
96 }
97
98
99 //_______________________________________________________________________
100 StatusCode MatrixTool::allocateMatrix(int nDoF)
101 {
102 ATH_MSG_INFO("allocating matrix and vector with nDoF = "<<nDoF);
103
104 if (nullptr!=m_bigmatrix || nullptr!=m_bigvector)
105 ATH_MSG_ERROR("big matrix already allocated!");
106
107 // Decide upon the big matrix representation:
108 if( m_useSparse )
109 m_bigmatrix = new AlSpaMat(nDoF);
110 else
111 m_bigmatrix = new AlSymMat(nDoF);
112
113 m_bigvector = new AlVec(nDoF);
114
115 ATH_MSG_INFO(" After Matrix and Vector allocation");
116
117 // set paths for matrix and vector output
118 m_bigmatrix->SetPathBin(m_pathbin.value()+m_prefixName);
119 m_bigmatrix->SetPathTxt(m_pathtxt.value()+m_prefixName);
120 m_bigvector->SetPathBin(m_pathbin.value()+m_prefixName);
121 m_bigvector->SetPathTxt(m_pathtxt.value()+m_prefixName);
122
123 ATH_MSG_INFO("set path to "<<m_pathbin.value()+m_prefixName.value());
124 return StatusCode::SUCCESS;
125 }
126
127 //_______________________________________________________________________
129 {
130 }
131
132 //_______________________________________________________________________
134 {
135 ATH_MSG_INFO("solving Global using ROOT");
136 if(m_logStream) {
137 *m_logStream<<"*************************************************************\n";
138 *m_logStream<<"************** solving using Global method ****************\n";
139 *m_logStream<<"************** using ROOT ****************\n";
140 *m_logStream<<"*************************************************************\n";
141 }
142
143 // start measuring time
144 clock_t starttime = clock();
145
146 DataVector<AlignPar>* alignParList = m_alignModuleTool->alignParList1D();
147 //const AlignModuleList* alignModules = m_alignModuleTool->alignModules1D();
148
149 int nDoF=m_alignModuleTool->nAlignParameters();
150
151 // some debugging output
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++)
156 //if (std::fabs((*m_bigmatrix)[i][j])>.0001)
157 msg(MSG::VERBOSE)<<i<<", "<<j<<" : "<<(*m_bigmatrix)[i][j] <<endmsg;
158
159 for (int i=0;i<nDoF;i++)
160 msg(MSG::VERBOSE)<<i <<" : "<<(*m_bigvector)[i]<<endmsg;
161 }
162
163 // get rescaled first and second derivatives
164 double * secderiv = new double[m_aNDoF*m_aNDoF];
165 double * firstderiv = new double[m_aNDoF];
166 for (int iActive=0;iActive<m_aNDoF;iActive++) {
167 int i = m_activeIndices[iActive];
168 firstderiv[iActive] = (*m_bigvector)[i];
169 for (int jActive=0;jActive<m_aNDoF;jActive++) {
170 int j = m_activeIndices[jActive];
171 secderiv[iActive*m_aNDoF+jActive] = (*m_bigmatrix)[i][j];
172 }
173 }
174
175 // attention, the dimension of matrix a and b is m_aNDoF not nDoF,
176 // this means some alignment parameters have not been calculated
177 // if the corresponding modules did not satify the select cut
178
179 TMatrixDSym a(m_aNDoF,secderiv);
180 TVectorD b(m_aNDoF,firstderiv);
181
182 if(msgLvl(MSG::DEBUG)) {
183 msg(MSG::DEBUG)<<"First derivatives:"<<endmsg;
184 b.Print();
185 msg(MSG::DEBUG)<<"Second derivatives:"<<endmsg;
186 a.Print();
187 }
188
189 TDecompBK c(a);
190 Bool_t status;
191 TMatrixDSym ainv(c.Invert(status));
192
193 TVectorD r(b.GetNrows());
194 if(status)
195 r = c.Solve(b,status);
196
197 // stop measuring time
198 clock_t stoptime = clock();
199 double totaltime = (stoptime-starttime)/double(CLOCKS_PER_SEC);
200 ATH_MSG_INFO("Time spent in solveROOT: "<<totaltime<<" s");
201
202 if(!status) {
203 msg(MSG::ERROR)<<"ROOT inversion failed"<<endmsg;
204 if(m_logStream) {
205 *m_logStream<<"ROOT inversion failed\n";
206 *m_logStream<<"\n";
207 }
208 }
209 else {
210 ATH_MSG_INFO("ROOT inversion ok");
211
212 ATH_MSG_DEBUG("Alignment constants:");
213 for (int iAdof=0;iAdof<m_aNDoF;iAdof++) {
214
215 int idof = m_activeIndices[iAdof];
216 AlignPar * alignPar=(*alignParList)[idof];
217
218 double sigma = alignPar->sigma();
219 double param = -r[iAdof] * sigma;
220 double err = std::sqrt(2.*std::fabs(ainv(iAdof,iAdof))) * sigma;
221
222 ATH_MSG_DEBUG(iAdof <<" : "<< param << " +/- "<< err);
223 ATH_MSG_DEBUG("ainv("<<iAdof<<")="<<ainv(iAdof,iAdof)<<", sigma: "<<sigma);
224 ATH_MSG_DEBUG("init par: "<<alignPar->initPar());
225 alignPar->setPar(param,err);
226 ATH_MSG_DEBUG("set param to "<<param<<" for alignPar "<<alignPar);
227 ATH_MSG_DEBUG(*(*alignParList)[idof]);
228 }
229
230 if(m_logStream)
231 {
232 *m_logStream<<"ROOT inversion ok\n";
233
235
236 // norm of first derivative
237 *m_logStream<<"norm of first derivative : "<<sqrt(b.Norm2Sqr())<<"\n";
238
239 // distance to solution
240 double dist = sqrt( ( b - (a * r) ).Norm2Sqr() );
241 *m_logStream<<"distance to solution : "<<dist<<"\n";
242
243 // calculate chi2 of the alignment change
244 double chi2 = a.Similarity(r) * .5;
245 *m_logStream<<"delta(chi2) of the alignment change : "<<chi2<<" / "<<m_aNDoF<<"\n";
246
247 // time spent here
248 *m_logStream<<"time spent in solve : "<<totaltime<<" s\n";
249 }
250 }
251
252 delete [] secderiv;
253 delete [] firstderiv;
254
255 return 1;
256 }
257
258 //_______________________________________________________________________
260 {
261 ATH_MSG_INFO("solving Global using CLHEP");
262 if(m_logStream) {
263 *m_logStream<<"*************************************************************\n";
264 *m_logStream<<"************** solving using Global method ****************\n";
265 *m_logStream<<"************** using CLHEP ****************\n";
266 *m_logStream<<"*************************************************************\n";
267 }
268
269 // start measuring time
270 clock_t starttime = clock();
271
272 DataVector<AlignPar> * alignParList = m_alignModuleTool->alignParList1D();
273 //const AlignModuleList* alignModules = m_alignModuleTool->alignModules1D();
274 for (int i=0;i<(int)alignParList->size();i++)
275 ATH_MSG_DEBUG("ap["<<i<<"]="<<(*alignParList)[i]);
276
277 int nDoF = m_alignModuleTool->nAlignParameters();
278
279 // some debugging output
280 if (msgLvl(MSG::DEBUG)) {
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++)
284 //if (std::fabs((*m_bigmatrix)[i][j])>.0001)
285 msg(MSG::DEBUG)<<i<<", "<<j<<" : "<<(*m_bigmatrix)[i][j] <<endmsg;
286
287 for (int i=0;i<nDoF;i++)
288 msg(MSG::DEBUG)<<i <<" : "<<(*m_bigvector)[i]<<endmsg;
289 }
290
291 // get rescaled first and second derivatives
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++) {
295 int i = m_activeIndices[iActive];
296 (*dChi2)[iActive] = (*m_bigvector)[i];
297 for (int jActive=0;jActive<m_aNDoF;jActive++) {
298 int j = m_activeIndices[jActive];
299 (*d2Chi2)[iActive][jActive] = (*m_bigmatrix)[i][j];
300 }
301 }
302
303 ATH_MSG_DEBUG("First derivatives:" << (*dChi2));
304 ATH_MSG_DEBUG("Second derivatives:" << (*d2Chi2));
305
306 CLHEP::HepSymMatrix cov(m_aNDoF,0);
307 CLHEP::HepVector delta(m_aNDoF,0);
308 CLHEP::HepVector deltafull(m_aNDoF,0);
309
310 bool status=true;
311 int ierr(0);
312 if(!m_diagonalize) {
313 // ==========================================================
314 // Run Matrix Inversion
315 ATH_MSG_INFO("Running matrix inversion");
316 if(m_logStream)
317 *m_logStream<<"Running matrix inversion\n";
318
319 cov = *d2Chi2;
320 cov.invert(ierr);
321 if(ierr>0)
322 msg(MSG::ERROR)<<"CLHEP inversion status flag = "<<ierr<<endmsg;
323 else
324 ATH_MSG_INFO("CLHEP inversion OK");
325 if(m_logStream)
326 *m_logStream<<"CLHEP inversion status flag = "<<ierr<<"\n";
327
328 // calculate corrections
329 delta = cov * (*dChi2);
330
331 // the covariance matrix is actually defined as 2 * d2Chi2^-1
332 ATH_MSG_DEBUG("Result: "<<delta);
333 ATH_MSG_DEBUG("cov: "<<cov*2);
334
335 // -----------------------
336 // calculate also for matrix and vector multiplied by factor 0.5
337 // this should make no difference if everything is correct but
338 // it can go wrong if insensitive DoF is included
339 CLHEP::HepSymMatrix cov2 = *d2Chi2 * .5;
340 // invert the matrix
341 int ierr2 = 0;
342 cov2.invert(ierr2);
343 if(ierr2>0)
344 msg(MSG::WARNING)<<"Second CLHEP inversion status flag = "<<ierr2<<endmsg;
345
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;
350 status=false;
351 break;
352 }
353
354 if(m_logStream && (ierr2>0 || !status)) {
355 *m_logStream<<"CLHEP inversion status flag for halfed matrix = "<<ierr2<<"\n";
356 *m_logStream<<"Matrix inversion check failed\n";
357 *m_logStream<<"\n";
358 }
359 // -- end of check of matrix inversion
360 }
361 else {
362 // ==========================================================
363 // Run Diagonalization
364 ATH_MSG_INFO("Running diagonalization");
365 if(m_logStream)
366 *m_logStream<<"Running diagonalization\n";
367
368 CLHEP::HepSymMatrix D = *d2Chi2;
369 CLHEP::HepMatrix U = CLHEP::diagonalize( &D );
370
371 ATH_MSG_INFO("Diagonalization done");
372 //sold = U*sdiag*U.T.
373
374 // reorder eigenvalues ascending
375 // eigenvectors need to be reordered consistently
376 ATH_MSG_DEBUG(" Reordering eigenvalues ascending ");
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]) {
380 // swap eigenvalues
381 double ei = D[i][i];
382 D[i][i] = D[j][j];
383 D[j][j] = ei;
384 // swap eigenvectors
385 for(int k=0;k<m_aNDoF; k++) {
386 double ev = U[k][i];
387 U[k][i] = U[k][j];
388 U[k][j] = ev;
389 }
390 }
391
392 // how do I now get the eigenvalues? this cannot be the most
393 // efficient way ... CLHEP::HepSymMatrix D = d2Chi2->similarityT( U );
394 CLHEP::HepVector eigenvector(m_aNDoF);
395
396 if(m_logStream)
397 *m_logStream<<"/------ The Eigenvalue Spectrum -------\n";
398
399 ATH_MSG_DEBUG("Calculating eigenvalues");
400 for(int imode=0; imode<m_aNDoF; ++imode) {
401
402 // get the relevant eigenvector
403 for(int irow=0; irow<m_aNDoF; ++irow)
404 eigenvector[irow] = U[irow][imode];
405
406 // calculate the eigenvalue
407 //double eigenvalue = d2Chi2->similarity( eigenvector );
408 double eigenvalue = D[imode][imode];
409 ATH_MSG_DEBUG("eigenvalue "<<eigenvalue);
410
411 double evdotb = dot(*dChi2,eigenvector);
412 CLHEP::HepVector thisdelta = evdotb/eigenvalue * eigenvector;
413 deltafull += thisdelta;
414
415 if(imode<m_modcut) {
416 ATH_MSG_INFO("skipping eigenvalue "<<imode<<" : "<<eigenvalue<<" , modcut is "<<m_modcut);
417 if(m_logStream)
418 *m_logStream<<"| skipping eigenvalue "<<eigenvalue<<"\n";
419 }
420 else if( eigenvalue < m_eigenvaluethreshold ) {
421 ATH_MSG_INFO("skipping eigenvalue "<<eigenvalue<<" , cut is "<<m_eigenvaluethreshold);
422 if(m_logStream)
423 *m_logStream<<"| skipping eigenvalue "<<eigenvalue<<"\n";
424 }
425 else {
426 if(m_logStream)
427 *m_logStream<<"| "<<eigenvalue<<"\n";
428
429 delta += thisdelta;
430
431 // this is the time consuming part
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;
435 }
436 }
437
438 // the covariance matrix is actually defined as 2 * d2Chi2^-1
439
440 ATH_MSG_DEBUG("Result: "<<delta);
441 ATH_MSG_DEBUG("cov: "<<cov);
442
443 if(m_logStream)
444 *m_logStream<<"\\----- End of Eigenvalue Spectrum -----\n";
445
446 // end of diagonalization
447 // ==========================================================
448 }
449
450 // stop measuring time
451 clock_t stoptime = clock();
452 double totaltime = (stoptime-starttime)/double(CLOCKS_PER_SEC);
453 ATH_MSG_INFO("Time spent in solveCLHEP: "<<totaltime<<" s");
454
455 if(ierr==0 && status)
456 {
457 ATH_MSG_DEBUG("Alignment constants:");
458 for (int iAdof=0;iAdof<m_aNDoF;iAdof++) {
459
460 int idof = m_activeIndices[iAdof];
461 AlignPar * alignPar=(*alignParList)[idof];
462
463 double sigma = alignPar->sigma();
464 double param = -delta[iAdof] * sigma;
465 double err = std::sqrt(2.*std::fabs(cov[iAdof][iAdof])) * sigma;
466
467 ATH_MSG_DEBUG(iAdof <<" : "<< param << " +/- "<< err);
468 ATH_MSG_DEBUG("cov("<<iAdof<<")="<<cov[iAdof][iAdof]<<", sigma: "<<sigma);
469 ATH_MSG_DEBUG("init par: "<<alignPar->initPar());
470 alignPar->setPar(param,err);
471 ATH_MSG_DEBUG("set param to "<<param<<" for alignPar "<<alignPar);
472 ATH_MSG_DEBUG(*(*alignParList)[idof]);
473 }
474
475 if(m_logStream) {
477
478 // norm of first derivative
479 *m_logStream<<"norm of first derivative : "<<dChi2->norm()<<"\n";
480
481 // distance to solution
482 double dist = ( - (*d2Chi2) * deltafull + (*dChi2) ).norm();
483 *m_logStream<<"distance to solution : "<<dist<<"\n";
484
485 // calculate chi2 of the alignment change
486 double chi2 = d2Chi2->similarity(delta) * .5;
487 *m_logStream<<"delta(chi2) of the alignment change : "<<chi2<<" / "<<m_aNDoF<<"\n";
488
489 // time spent here
490 *m_logStream<<"time spent in solve : "<<totaltime<<" s\n";
491 }
492 }
493
494 delete d2Chi2;
495 delete dChi2;
496
497 return 1;
498 }
499
500 //_______________________________________________________________________
502 {
503 ATH_MSG_INFO("solving using Local method");
504 if(m_logStream) {
505 *m_logStream<<"*************************************************************\n";
506 *m_logStream<<"************** solving using Local method *****************\n";
507 *m_logStream<<"*************************************************************\n";
508 }
509
510 int totalNDoF(0);
511 double totalChi2(0.);
512
513 const AlignModuleList * alignModules = m_alignModuleTool->alignModules1D();
514
515 AlignModuleList::const_iterator imod = alignModules->begin();
516 AlignModuleList::const_iterator imod_end = alignModules->end();
517 for( ; imod!=imod_end; ++imod) {
518
519 AlignModule * module = *imod;
520
521 ATH_MSG_INFO("Solving for module: "<<module->name());
522
523 DataVector<AlignPar> * alignPars = m_alignModuleTool->getAlignPars(module);
524
525 int thisNDoF = alignPars->size();
526
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];
535 }
536 }
537
538 ATH_MSG_DEBUG("First derivatives:" << dChi2);
539 ATH_MSG_DEBUG("Second derivatives:" << d2Chi2);
540
541 if(module->nHits() < m_minNumHits || module->nTracks() < m_minNumTrks) {
542 ATH_MSG_INFO("Not enough hits in module \'"<<module->name()<<"\': "
543 <<module->nHits()<<" < "<<m_minNumHits<<" or "
544 <<module->nTracks()<<" < "<<m_minNumTrks
545 <<". Skipping...");
546
547 // print module summary even when solving is not done
548 if(m_logStream)
549 printModuleSolution(*m_logStream,module,nullptr);
550
551 continue;
552 }
553
554 ATH_MSG_DEBUG("First derivatives:" << dChi2);
555 ATH_MSG_DEBUG("Second derivatives:" << d2Chi2);
556
557
558 totalNDoF += thisNDoF;
559
560 CLHEP::HepSymMatrix cov(d2Chi2);
561
562 // invert the matrix
563 int ierr = 0;
564 cov.invert(ierr);
565 if(ierr>0)
566 ATH_MSG_WARNING("CLHEP inversion status flag = "<<ierr);
567 else
568 ATH_MSG_DEBUG("CLHEP inversion status flag = "<<ierr);
569
570 // calculate corrections
571 CLHEP::HepVector delta = cov * dChi2;
572 //ATH_MSG_DEBUG("d2Chi2: "<<d2Chi2);
573 //ATH_MSG_DEBUG("cov: "<<cov);
574 //ATH_MSG_DEBUG("d2Chi2*cov: "<<d2Chi2*cov);
575 //ATH_MSG_DEBUG("dChi2: "<<dChi2);
576 ATH_MSG_DEBUG("Result: "<<delta);
577
578 ATH_MSG_DEBUG("Alignment constants:");
579 for (int idof=0;idof<thisNDoF;++idof) {
580 AlignPar * alignPar = alignPars->at(idof);
581
582 double sigma = alignPar->sigma();
583 double param = -delta[idof] * sigma;
584 double err = std::sqrt(2.*std::fabs(cov[idof][idof])) * sigma;
585
586 ATH_MSG_DEBUG(idof <<" : "<< param << " +/- "<< err);
587 ATH_MSG_DEBUG("cov("<<idof<<")="<<cov[idof][idof]<<", sigma: "<<sigma);
588 ATH_MSG_DEBUG("init par: "<<alignPar->initPar());
589
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);
593 ATH_MSG_DEBUG(*alignPar);
594 }
595
596 if(m_logStream) {
597 printModuleSolution(*m_logStream,module,&cov);
598
599 *m_logStream<<"CLHEP inversion status flag = "<<ierr<<"\n";
600
601 // calculate chi2 of the alignment change
602 double chi2 = d2Chi2.similarity(delta) * .5;
603 totalChi2 += chi2;
604 *m_logStream<<"delta(chi2) of the alignment change : "<<chi2<<" / "<<thisNDoF<<"\n";
605 }
606 }
607
608 if(m_logStream) {
609 *m_logStream<<"--------------------------------------------------------------------------------\n";
610 *m_logStream<<"Total delta(chi2) of the alignment change from the local method : "<<totalChi2<<" / "<<totalNDoF<<"\n";
611 *m_logStream<<"\n";
612 }
613
614 return 1;
615 }
616
617 //________________________________________________________________________
619 {
620
621 if(m_readTFiles){
622 ATH_MSG_INFO("Info to obtained from from TFiles");
623 return accumulateFromTFiles();
624 }else{
625 ATH_MSG_INFO("Info to obtained from from Binary files");
626 return accumulateFromBinaries();
627 }
628 }
629
630 //________________________________________________________________________
632 {
633
634
635 DataVector<AlignPar>* alignParList = m_alignModuleTool->alignParList1D();
636 int nDoF=alignParList->size();
637
638 std::map<int,unsigned long long> modIndexMap;
639 float dummyVersion(0.);
640 double totalscale=0.;
641 for (int ivec=0;ivec<(int)m_inputVectorFiles.size();ivec++) {
642
643 ATH_MSG_DEBUG("Reading vector "<<ivec<<" from file "<<m_inputVectorFiles[ivec]);
644
645 AlVec newVector(nDoF);
646 std::map<int,unsigned long long> newModIndexMap;
647 newVector.SetPathBin(m_pathbin.value()+m_prefixName.value());
648 newVector.SetPathTxt(m_pathtxt.value()+m_prefixName.value());
649 double scale=0;
650 StatusCode sc = newVector.ReadPartial(m_inputVectorFiles[ivec],scale,newModIndexMap,dummyVersion);
651 totalscale += scale;
652 if (sc==StatusCode::FAILURE) {
653 msg(MSG::FATAL)<<"Problem reading vector from "<<m_inputVectorFiles[ivec]<<endmsg;
654 return false;
655 }
656 if (newVector.size()!=m_bigvector->size()) {
657 msg(MSG::FATAL) <<"vector wrong size! newVector size "<<newVector.size()
658 <<", bigvector size "<<m_bigvector->size()<<endmsg;
659 return false;
660 }
661
662 // check modIndexMaps to make sure they are the same
663 if (ivec==0)
664 modIndexMap = std::move(newModIndexMap);
665 else if (modIndexMap!=newModIndexMap) {
666 msg(MSG::FATAL)<<"module index maps don't agree!"<<endmsg;
667 return false;
668 }
669 if (ivec>0)
670 *m_bigvector += newVector;
671 else
672 *m_bigvector = std::move(newVector);
673 }
674
675 m_scale = totalscale;
676
677 AlSymMat * symBigMatrix=dynamic_cast<AlSymMat*>(m_bigmatrix);
678 AlSpaMat * spaBigMatrix=dynamic_cast<AlSpaMat*>(m_bigmatrix);
679
680
681 for (int imat=0;imat<(int)m_inputMatrixFiles.size();imat++) {
682 ATH_MSG_DEBUG("Reading matrix "<<imat<<" from file "<<m_inputMatrixFiles[imat]);
683
684 // create new matrix to read data from current file
685 int nDoF=modIndexMap.size();
686 bool triang;
687 StatusCode sc;
688 if (symBigMatrix) {
689 AlSymMat newMatrix(nDoF);
690 sc = newMatrix.Read(m_inputMatrixFiles[imat],nDoF,triang,dummyVersion);
691 if (sc==StatusCode::SUCCESS)
692 *symBigMatrix += newMatrix;
693 }
694 else {
695 if (!spaBigMatrix) {
696 throw std::logic_error("Unhandled matrix type");
697 }
698
699 AlSpaMat newMatrix(nDoF);
700 sc = newMatrix.Read(m_inputMatrixFiles[imat],nDoF,triang,dummyVersion);
701
702 if (sc==StatusCode::SUCCESS) {
703 if (imat>0)
704 *spaBigMatrix += newMatrix;
705 else
706 *spaBigMatrix = newMatrix;
707 }
708 }
709
710 if (sc==StatusCode::FAILURE) {
711 msg(MSG::FATAL)<<"problem reading matrix from "<<m_inputMatrixFiles[imat]<<endmsg;
712 return false;
713 }
714
715 if (!m_useSparse && triang==m_wSqMatrix) {
716 ATH_MSG_WARNING("matrix not expected format! Changing m_wSqMatrix to "<<!triang);
717 m_wSqMatrix=!triang;
718 }
719
720 }
721
722 // accumulate hitmap from hitmap files
723 if(m_readHitmaps)
724 readHitmaps();
725
726 return true;
727 }
728
729 //_______________________________________________________________________
730 void MatrixTool::storeInTFile(const TString& filename)
731 {
732 //Store reults in a single TFile....
733 //Including Matrix Vector Hitmap.. Soluton EVs etc.
734
735 ATH_MSG_DEBUG("Writing Results to a TFile");
736
737 DataVector<AlignPar> * alignParList = m_alignModuleTool->alignParList1D();
738 int nDoF = alignParList->size();
739
740 TMatrixDSparse* myTMatrix = m_bigmatrix->makeTMatrix();
741
742 ATH_MSG_DEBUG( "Created TMatrixDSparse" );
743
744
745 double *val = new double[nDoF];
746 for (int i=0;i<nDoF;i++) {
747 val[i] = (*m_bigvector)[i];
748 }
749
750 TVectorD myTVector(nDoF, val);
751 delete [] val;
752
753 ATH_MSG_DEBUG( "Created TVectorD" );
754
755
756 const AlignModuleList * moduleList = m_alignModuleTool->alignModules1D();
757 int nModules = moduleList->size();
758
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();
763 int index(0);
764 for(; imod != imod_end; ++imod) {
765 AlignModule * module = *imod;
766 hitmapA[index] = (double)module->nHits();
767 hitmapB[index] = (double)module->nTracks();
768 index++;
769 }
770
771 TVectorD hitmapHits(nModules, hitmapA);
772 TVectorD hitmapTracks(nModules, hitmapB);
773
774 delete [] hitmapA;
775 delete [] hitmapB;
776
777
778
779 TFile myFile(filename,"recreate");
780 hitmapHits.Write("Hits");
781 hitmapTracks.Write("Tracks");
782 myTMatrix->Write("Matrix");
783 myTVector.Write("Vector");
784
785 TVectorD scale(1, &m_scale) ;
786 scale.Write("Scale");
787
788
789 double *moduleInfoA = new double[nDoF];//unsigned long long
790 double *dofInfoA = new double[nDoF];//int
791
792 if (sizeof(unsigned long long) != sizeof(double))
793 ATH_MSG_ERROR("Module Identifiers will not be saved. sizeof(double)!=sizeof(ulonglong)");
794 else{
795
796 DataVector<AlignPar>* alignPars = m_alignModuleTool->alignParList1D();
797 for (int i=0;i<(int)alignPars->size();i++) {
798 //Do a direct memory copy to store unsigned long long in the momory of a double
799 double target;
800 uint64_t id = (*alignPars)[i]->alignModule()->identify().get_compact();
801 memcpy(&target, &id, sizeof(target));
802 moduleInfoA[i]=target;
803 //moduleInfoB[i]=(*alignPars)[i]->alignModule()->name();
804 uint64_t dof = (*alignPars)[i]->paramType();
805 memcpy(&target, &dof, sizeof(target));
806 dofInfoA[i]=target;
807 }
808
809 TVectorD moduleIDs(nDoF, moduleInfoA) ;
810 TVectorD moduleDoFs(nDoF,dofInfoA);
811 delete [] moduleInfoA;
812 moduleIDs.Write("ModuleID");
813 moduleDoFs.Write("dof");
814 }
815
816 myFile.Write();
817 myFile.Close();
818
819 delete myTMatrix;
820 ATH_MSG_DEBUG("Finshed writing TFILE");
821
822 }
823
824//________________________________________________________________________
826 {
827 DataVector<AlignPar>* alignParList = m_alignModuleTool->alignParList1D();
828 int nDoF=alignParList->size();
829 ATH_MSG_DEBUG("OPENING TFILES");
830
831 std::map<int,unsigned long long> modIndexMap;
832 std::map<int,unsigned long long> DoFMap;
833 double totalscale=0.;
834
835 AlSymMat * symBigMatrix=dynamic_cast<AlSymMat*>(m_bigmatrix);
836 AlSpaMat * spaBigMatrix=dynamic_cast<AlSpaMat*>(m_bigmatrix);
837 //TMatrixDSparse *accumMatrix(0);
838 AlSpaMat *accumMatrix = nullptr;
839
840 const AlignModuleList * moduleList = m_alignModuleTool->alignModules1D();
841 int nModules = moduleList->size();
842
843 TVectorD TotalHits(nModules);
844 TVectorD TotalTracks(nModules);
845
846 int numberOfReadErrors = 0;
847
848 struct rusage myusage{};
849 int itworked = getrusage(RUSAGE_SELF,&myusage);
850 if(itworked == 0)//note: rusage returns zero if it succeeds!
851 ATH_MSG_DEBUG("ItWorked");
852
853 long intialMemUse = myusage.ru_maxrss;
854
855 for (int ifile = 0; ifile < (int)m_inputTFiles.size(); ifile++) {
856 if (numberOfReadErrors > m_maxReadErrors){
857 msg(MSG::FATAL) << " number of errors when reading the TFiles already exceed " << m_maxReadErrors << endmsg;
858 return false;
859 }
860
861 ATH_MSG_DEBUG("Reading File number " << ifile << ", " << m_inputTFiles[ifile]);
862
863 itworked = getrusage(RUSAGE_SELF,&myusage);
864 if (itworked ==0){
865 ATH_MSG_DEBUG("Memory usage [MB], total " << myusage.ru_maxrss/1024 << ", increase " << (myusage.ru_maxrss-intialMemUse)/1024);
866 }
867 TFile* myFile = TFile::Open(m_inputTFiles[ifile].c_str());
868
869 if ( myFile->IsZombie() || !(myFile->IsOpen()) ) {
870 ++numberOfReadErrors;
871 ATH_MSG_ERROR( " Problem reading TFile " << m_inputTFiles[ifile] );
872 continue;
873 }
874
875 std::map<int,unsigned long long> newModIndexMap;
876
877 TVectorD* myModuleIDs;
878 myModuleIDs = (TVectorD*)myFile->Get("ModuleID");
879 if( !myModuleIDs ){
880 ++numberOfReadErrors;
881 ATH_MSG_ERROR("Modules ID not read!!!");
882 continue;
883 }
884
885 for (int i(0); i<myModuleIDs->GetNrows(); ++i){
886 //Coverting back from a double to a unvi signed long long
887 double source = (*myModuleIDs)(i);
888 uint64_t target;
889 memcpy(&target, &source, sizeof(target));
890 newModIndexMap[i]=target;
891 //std::cout << i<< " " <<target <<"\n";
892 }
893
894 delete myModuleIDs;
895
896 std::map<int,unsigned long long> newDoFMap;
897
898 TVectorD* myDoFs;
899 myDoFs = (TVectorD*)myFile->Get("dof");
900 if( !myDoFs ){
901 ++numberOfReadErrors;
902 ATH_MSG_ERROR("DoFs not read!!!");
903 continue;
904 }
905
906 for (int i(0); i<myDoFs->GetNrows(); ++i){
907 //Coverting back from a double to a unsigned long long
908 double source = (*myDoFs)(i);
909 uint64_t target;
910 memcpy(&target, &source, sizeof(target));
911 newDoFMap[i]=target;
912 }
913 delete myDoFs;
914
915
916 TVectorD* Scale;
917 Scale = (TVectorD*)myFile->Get("Scale");
918 if( !Scale ){
919 ++numberOfReadErrors;
920 ATH_MSG_ERROR("Scale not read!!!");
921 continue;
922 }
923
924 double scale=(*Scale)(0);
925 totalscale += scale;
926 delete Scale;
927
928
929 ATH_MSG_DEBUG("Reading Vector");
930 TVectorD* vector = (TVectorD*)myFile->Get("Vector");
931 if( !vector ){
932 ++numberOfReadErrors;
933 ATH_MSG_ERROR("Vector not read!!!");
934 continue;
935 }
936
937 AlVec* newVector = new AlVec(nDoF);
938 newVector->SetPathBin(m_pathbin.value()+m_prefixName.value());
939 newVector->SetPathTxt(m_pathtxt.value()+m_prefixName.value());
940
941 if (newVector->size() != m_bigvector->size() ) {
942 msg(MSG::FATAL) << "vector wrong size! newVector size " << newVector->size()
943 << ", bigvector size " << m_bigvector->size()<<endmsg;
944 delete newVector;
945 delete vector;
946 return false;
947 }
948
949 if (m_bigvector->size() != vector->GetNrows() ) {
950 msg(MSG::FATAL) << "File vector wrong size! File Vector size " << vector->GetNrows()
951 << ", bigvector size " << m_bigvector->size()<<endmsg;
952 delete newVector;
953 delete vector;
954 return false;
955 }
956
957
958 for (int i=0;i<nDoF;i++) {
959 (*newVector)[i] = (*vector)(i);
960 }
961 delete vector;
962
963 // check modIndexMaps to make sure they are the same
964 if (ifile == 0){
965 DoFMap = std::move(newDoFMap);
966 } else if (DoFMap!=newDoFMap) {
967 msg(MSG::FATAL) << "module dofs don't agree!" << endmsg;
968 return false;
969 }
970
971 if (ifile == 0){
972 modIndexMap = newModIndexMap;
973 } else if (modIndexMap!=newModIndexMap) {
974 msg(MSG::FATAL) << "module index maps don't agree!" << endmsg;
975 return false;
976 }
977
978 if (ifile>0){
979 *m_bigvector += *newVector;
980 delete newVector;
981 } else {
982 delete m_bigvector;
983 m_bigvector = newVector;
984 }
985
986
987 ATH_MSG_DEBUG("Reading matrix ");
988 TMatrixDSparse* matrix = (TMatrixDSparse*)myFile->Get("Matrix");
989
990 if( !matrix ){
991 ++numberOfReadErrors;
992 ATH_MSG_ERROR("Matrix not read!!!");
993 continue;
994 }
995
996
997 if (ifile == 0 ){
998
999 accumMatrix = new AlSpaMat(nDoF);
1000 ATH_MSG_DEBUG("Matrix size b4 "<< accumMatrix->ptrMap()->size() );
1001
1002 //This method is ok for large matrix files... really only access the non zero elements
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];
1009 if (i<j){
1010 ATH_MSG_DEBUG("i < j " );
1011 j = i;
1012 i = (myRow.GetColPtr())[jj];
1013 }
1014 (*accumMatrix)[i][j] = myElement;
1015 }
1016 }
1017 ATH_MSG_DEBUG("Matrix size AF "<< accumMatrix->ptrMap()->size() );
1018
1019 } else if ( accumMatrix) {
1020 ATH_MSG_DEBUG("Matrix size b4 "<< accumMatrix->ptrMap()->size() );
1021
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];
1028 if (i<j){
1029 ATH_MSG_DEBUG("i < j " );
1030 j = i;
1031 i = (myRow.GetColPtr())[jj];
1032 }
1033 (*accumMatrix)[i][j] += myElement;
1034 }
1035 }
1036 ATH_MSG_DEBUG("Matrix size AF "<< accumMatrix->ptrMap()->size() );
1037
1038 } else {
1039 delete matrix;
1040 ++numberOfReadErrors;
1041 ATH_MSG_ERROR("Matrix allocation error!!!");
1042 continue;
1043 }
1044
1045 delete matrix;
1046
1047 TVectorD* hits;
1048 TVectorD* tracks;
1049
1050 ATH_MSG_DEBUG("Reading hitmap ");
1051 hits = (TVectorD*)myFile->Get("Hits");
1052 if( !hits ){
1053 ++numberOfReadErrors;
1054 ATH_MSG_ERROR("Hitmap 1 not read!!!");
1055 continue;
1056 }
1057
1058 tracks = (TVectorD*)myFile->Get("Tracks");
1059 if( !tracks ){
1060 delete hits;
1061 ++numberOfReadErrors;
1062 ATH_MSG_ERROR("Hitmap 2 not read!!!");
1063 continue;
1064 }
1065
1066 if(hits->GetNrows() != TotalHits.GetNrows() ){
1067 delete hits;
1068 delete tracks;
1069 ++numberOfReadErrors;
1070 ATH_MSG_ERROR("Hitmap size incorrect!!!");
1071 continue;
1072 }
1073
1074 TotalHits += (*hits);
1075 TotalTracks += (*tracks);
1076
1077 delete hits;
1078 delete tracks;
1079
1080 myFile->Close("R");
1081 delete myFile;
1082
1083 itworked = getrusage(RUSAGE_SELF,&myusage);
1084 ATH_MSG_DEBUG("Memory usage [MB], total " << myusage.ru_maxrss/1024 << ", increase " << (myusage.ru_maxrss-intialMemUse)/1024);
1085
1086 }
1087
1088
1089
1090 // create new matrix to read data from current file
1091 if(accumMatrix){
1092 if (symBigMatrix) {
1093 AlSymMat newMatrix(nDoF);
1094 //This method is ok for small matrix files
1095 for (int i=0;i<nDoF;i++) {
1096 for (int j=0;j<=i;j++) {
1097 newMatrix[i][j] = (*accumMatrix)[i][j];
1098 }
1099 }
1100
1101 *symBigMatrix += newMatrix;
1102 delete accumMatrix;
1103 } else if (spaBigMatrix) {
1104 ATH_MSG_DEBUG( "should reassign matrix "<< spaBigMatrix->ptrMap()->size() );
1105 *spaBigMatrix += *accumMatrix;
1106 ATH_MSG_DEBUG( "?????? "<< spaBigMatrix->ptrMap()->size() );
1107 delete accumMatrix;
1108 }
1109 }
1110
1111 ATH_MSG_DEBUG( "?????? "<< m_bigmatrix->ptrMap()->size() );
1112
1113 AlignModuleList::const_iterator imod = moduleList->begin();
1114 AlignModuleList::const_iterator imod_end = moduleList->end();
1115 int index = 0;
1116 int totalhits = 0;
1117 for(; imod != imod_end; ++imod, ++index ) {
1118 AlignModule * module = *imod;
1119 module->setNHits((int)TotalHits(index));
1120 module->setNTracks((int)TotalTracks(index));
1121 totalhits += (int)TotalHits(index);
1122 }
1123
1124
1125 m_nHits = totalhits;
1126 m_nTracks = 0;
1127 m_nMeasurements = 0;
1128 m_scale = totalscale;
1129
1130 return true;
1131 }
1132
1133
1134
1135
1136 //_______________________________________________________________________
1138 {
1139 // ============
1140 // solve
1141 // ============
1142 ATH_MSG_DEBUG("in MatrixTool::solve()");
1143
1144 // set normalization scale to number of hits for now
1145 if(m_scale<0)
1146 m_scale = m_nHits;
1147
1148 //-------------------------------------------------------
1149 // write matrix and vector to file
1150 if (m_writeMat) {
1151 // version has to be 2 to for reading matrices and vectors back in to work properly
1152 double dummyVersion(2.);
1153
1154 // make map of matrix entry to module index (set by geometry manager tool)
1155 std::map<int,unsigned long long> modIndexMap;
1156 std::map<int,std::string> modNameMap;
1157 DataVector<AlignPar>* alignPars = m_alignModuleTool->alignParList1D();
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();
1161 }
1162
1163 // binary files
1164 ATH_MSG_DEBUG("writing binary files");
1165 StatusCode sc1 = m_bigmatrix->Write("matrix.bin",true,m_wSqMatrix,m_scale,dummyVersion);
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;
1169 return -1;
1170 }
1171
1172 if (m_writeMatTxt) {
1173
1174 // text files
1175 ATH_MSG_DEBUG("writing text files");
1176 sc1 = m_bigmatrix->Write("matrix.txt",false,m_wSqMatrix,m_scale,dummyVersion);
1177 sc2 = m_writeModuleNames ?
1178 m_bigvector->WritePartial("vector.txt",false,m_scale,modNameMap,dummyVersion) :
1179 m_bigvector->WritePartial("vector.txt",false,m_scale,modIndexMap,dummyVersion);
1180
1181 if (!sc1.isSuccess() || !sc2.isSuccess()) {
1182 msg(MSG::ERROR)<<"problem writing matrix or vector"<<endmsg;
1183 return -1;
1184 }
1185 }
1186
1187 ATH_MSG_DEBUG("matrix and vector written to: "<<m_pathbin.value()+m_prefixName.value()<<"matrix.bin (.txt) and "<<m_pathbin.value()+m_prefixName.value()<<"vector.bin (.txt)");
1188 }
1189
1190 //-------------------------------------------------------
1191 // write hitmap to file
1192 if (m_writeHitmap)
1193 writeHitmap();
1194
1195 if(m_writeTFile)
1196 storeInTFile(m_pathbin.value()+m_prefixName.value()+m_tfileName.value());
1197
1198
1199 if(!m_runLocal && m_solveOption==0) {
1200 ATH_MSG_DEBUG("No solving requested.");
1201 return 1;
1202 }
1203
1204 //-------------------------------------------------------
1205 // rescale the vector and the matrix according to sigmas
1206 // and apply soft mode cut
1207
1208 ATH_MSG_DEBUG("rescaling the matrix/vector and applying the soft-mode-cut");
1209
1210 DataVector<AlignPar>* alignParList = m_alignModuleTool->alignParList1D();
1211 int nDoF = alignParList->size();
1212
1213
1214 const AlSymMat * chkMatrix = dynamic_cast<const AlSymMat*>(m_bigmatrix);
1215 if(chkMatrix){
1216 // Method when using the dense matrix
1217 for (int i=0;i<nDoF;i++) {
1218 // scale the vector
1219 double sigma_i = (*alignParList)[i]->sigma();
1220 double softCut = 2 * pow( (*alignParList)[i]->softCut() , -2 );
1221 (*m_bigvector)[i] *= sigma_i;
1222
1223 for (int j=0;j<=i;j++) {
1224 // scale the matrix
1225 if ((*chkMatrix)[i][j] != 0.) {
1226 double sigma_j = (*alignParList)[j]->sigma();
1227 (*m_bigmatrix)[i][j] *= sigma_i * sigma_j;
1228 }
1229 // apply soft-mode-cut
1230 if (i==j && m_softEigenmodeCut>0.){
1231 (*m_bigmatrix)[i][j] += m_softEigenmodeCut * softCut;
1232
1233 }
1234
1235 // set first and second derivatives on AlignPar
1236 if (i==j) {
1237 (*alignParList)[i]->setFirstDeriv((*m_bigvector)[i]/sigma_i);
1238 (*alignParList)[i]->setSecndDeriv((*m_bigmatrix)[i][i]/sigma_i/sigma_i);
1239 }
1240 }
1241 }
1242 } else {
1243 // Method when using the sparse matrix
1244 for (const datamap::value_type& p : *m_bigmatrix->ptrMap()) {
1245 int i = p.first.first;
1246 int j = p.first.second;
1247
1248 // Scale matrix
1249 double sigma_i = (*alignParList)[i]->sigma();
1250 double sigma_j = (*alignParList)[j]->sigma();
1251
1252 (*m_bigmatrix)[i][j] *= sigma_i * sigma_j;
1253
1254 }
1255
1256
1257 for (int i=0;i<nDoF;i++) {
1258 // scale the vector
1259 double sigma_i = (*alignParList)[i]->sigma();
1260 (*m_bigvector)[i] *= sigma_i;
1261 if (m_softEigenmodeCut >0. ){
1262 double softCut = 2 * pow( (*alignParList)[i]->softCut() , -2 );
1263 (*m_bigmatrix)[i][i] += m_softEigenmodeCut * softCut;
1264 ATH_MSG_DEBUG( "DOF "<< i <<" Nhits "<< (*alignParList)[i]->alignModule()->nHits() << " soft-mode-cut "<< (*alignParList)[i]->softCut() <<" -> " << m_softEigenmodeCut * softCut << " sigma_i "<< sigma_i << " Matrix: " << (*m_bigmatrix)[i][i] << " Vector: " << (*m_bigvector)[i]);
1265 }
1266 (*alignParList)[i]->setFirstDeriv((*m_bigvector)[i]/sigma_i);
1267 (*alignParList)[i]->setSecndDeriv((*m_bigmatrix)[i][i]/sigma_i/sigma_i);
1268 }
1269 }
1270
1271 unsigned long long OldPixelIdentifier = 37769216; //Identifier for the Pixel Detector
1272 unsigned long long IBLIdentifier = 33574912; //Identifier for the Pixel Detector
1273
1274 unsigned long long SCT_ECA_8_Identifier = 218116096; //Identifier for the SCT ECA Last Disk
1275 std::string SCT_ECA_8_Name = "SCT/EndcapA/Disk_8";
1276
1277
1278
1279 ATH_MSG_INFO("rescaling done");
1280 ATH_MSG_INFO("Javi: Printing (*alignParList)[i]->alignModule()->identify32()");
1281
1282 // select modules with non-zero tracks
1283 for(int i=0;i<nDoF;i++)
1284 {
1285 ATH_MSG_DEBUG(i);
1286 ATH_MSG_DEBUG((*alignParList)[i]->alignModule()->identify32());
1287 ATH_MSG_DEBUG((*alignParList)[i]->alignModule());
1288 ATH_MSG_DEBUG((*alignParList)[i]->alignModule()->name());
1289 ATH_MSG_DEBUG((*alignParList)[i]->paramType());
1290
1291 //Skip solving for Pixel or IBL:
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);
1300
1302 if (SCTECA8)
1303 {ATH_MSG_INFO( "SCT ECA Last Disk DoF have been skipped in the solving because DeactivateSCT_ECA_LastDisk is set to True");
1304 continue;}
1305 if (SCTECA8_n)
1306 {ATH_MSG_INFO( "SCT ECA Last Disk DoF have been skipped in the solving because DeactivateSCT_ECA_LastDisk is set to True");
1307 continue;}
1308 }
1309
1310 if (m_AlignIBLbutNotPixel) //If m_AlignIBLbutNotPixel is set to True, Pixel will be skipped in the solving.
1311 if (oldPixel)
1312 {ATH_MSG_INFO( "Pixel DoF have been skipped in the solving because AlignIBLbutNotPixel is set to True");
1313 continue;}
1314
1315 if (m_AlignPixelbutNotIBL) //If m_AlignPixelbutNotIBL is set to True, IBL will be skipped in the solving.
1316 if (ibl)
1317 {ATH_MSG_INFO( "IBL DoF have been skipped in the solving because AlignPixelbutNotIBL is set to True");
1318 continue;}
1319
1320 //For specific DoF: (*alignParList)[i]->paramType() = 0,1,2,3,4,5,6 for Tx,Ty,Tz,Rx,Ry,Rz,Bx
1321 //Pixel Dofs:
1322 if (m_Remove_Pixel_Tx) //If m_Remove_Pixel_Tx is set to True, Pixel Tx will be skipped in the solving.
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");
1325 continue;}
1326
1327 if (m_Remove_Pixel_Ty) //If m_Remove_Pixel_Ty is set to True, Pixel Ty will be skipped in the solving.
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");
1330 continue;}
1331
1332 if (m_Remove_Pixel_Tz) //If m_Remove_Pixel_Tz is set to True, Pixel Tz will be skipped in the solving.
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");
1335 continue;}
1336
1337 if (m_Remove_Pixel_Rx) //If m_Remove_Pixel_Rx is set to True, Pixel Rx will be skipped in the solving.
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");
1340 continue;}
1341
1342 if (m_Remove_Pixel_Ry) //If m_Remove_Pixel_Ry is set to True, Pixel Ry will be skipped in the solving.
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");
1345 continue;}
1346
1347 if (m_Remove_Pixel_Rz) //If m_Remove_Pixel_Rz is set to True, Pixel Rz will be skipped in the solving.
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");
1350 continue;}
1351
1352 //IBL Dofs:
1353 if (m_Remove_IBL_Tx) //If m_Remove_IBL_Tx is set to True, IBL Tx will be skipped in the solving.
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");
1356 continue;}
1357
1358 if (m_Remove_IBL_Ty) //If m_Remove_IBL_Ty is set to True, IBL Ty will be skipped in the solving.
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");
1361 continue;}
1362
1363 if (m_Remove_IBL_Tz) //If m_Remove_IBL_Tz is set to True, IBL Tz will be skipped in the solving.
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");
1366 continue;}
1367
1368 if (m_Remove_IBL_Rx) //If m_Remove_IBL_Rx is set to True, IBL Rx will be skipped in the solving.
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");
1371 continue;}
1372
1373 if (m_Remove_IBL_Ry) //If m_Remove_IBL_Ry is set to True, IBL Ry will be skipped in the solving.
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");
1376 continue;}
1377
1378 if (m_Remove_IBL_Rz) //If m_Remove_IBL_Rz is set to True, IBL Rz will be skipped in the solving.
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");
1381 continue;}
1382
1383 if(theParameterList[i]->alignModule()->nHits() >= m_minNumHits && theParameterList[i]->alignModule()->nTracks() >= m_minNumTrks)
1384 m_activeIndices.push_back(i);
1385 }
1386 m_aNDoF = m_activeIndices.size();
1387 ATH_MSG_DEBUG("aNDoF/nDoF: "<<m_aNDoF<<"/"<<nDoF);
1388
1389 // --------------------
1390 // now do the SOLVING
1391 // --------------------
1392
1393 int info = 0;
1394
1395 // first Local solving
1396 if (m_runLocal)
1397 info = solveLocal();
1398
1399 // remove spurious modules and resize
1400 if (m_removeSpurious) {
1401
1402 ATH_MSG_INFO("Spurious removal not implemented at the moment.");
1403/* if (StatusCode::SUCCESS != spuriousRemoval()) {
1404 ATH_MSG_ERROR("Problem while trying to remove spurious. Stopping solving");
1405 return -1;
1406 }
1407
1408 // if nDoF=0, bad job...
1409 int NDoF = m_alignModuleTool->nAlignParameters();
1410 if(NDoF==0) {
1411 ATH_MSG_WARNING("Removal removed everything: NDoF=" << NDoF << " !!!");
1412 return 1;
1413 }
1414 ATH_MSG_DEBUG("NDoF: " << NDoF);
1415*/
1416 }
1417
1418 // --------------------
1419 // now Global solving
1420 switch(m_solveOption) {
1421
1422 case NONE:
1423 ATH_MSG_DEBUG("No global solving requested.");
1424 break;
1425
1426 case SOLVE_ROOT:
1427 info = solveROOT();
1428 break;
1429
1430 case SOLVE_CLHEP:
1431 info = solveCLHEP();
1432 break;
1433
1434 case SOLVE:
1435 case DIRECT_SOLVE:
1437 info = solveLapack();
1438 break;
1439
1440 case SOLVE_FAST:
1441 case DIRECT_SOLVE_FAST:
1442 info = solveSparseEigen();
1443 break;
1444
1445 default:
1446 ATH_MSG_INFO("Unknown solving option.");
1447 info = 0;
1448 break;
1449 }
1450
1451 ATH_MSG_INFO("Return value from solving: "<<info);
1452
1453 return info;
1454 }
1455
1456
1457 //_______________________________________________________________________
1461
1462 //_______________________________________________________________________
1466
1467 //________________________________________________________________________
1468 void MatrixTool::addFirstDerivatives(std::list<int,double>& )
1469 {
1470 }
1471
1472 //________________________________________________________________________
1473 void MatrixTool::addSecondDerivatives(std::list<std::pair<int,int>,double >&)
1474 {
1475 }
1476
1477 //________________________________________________________________________
1478 void MatrixTool::addFirstDerivative(int irow, double firstderiv)
1479 {
1480 (*m_bigvector)[irow] += firstderiv;
1481 }
1482
1483 //________________________________________________________________________
1484 void MatrixTool::addSecondDerivative(int irow, int icol, double secondderiv)
1485 {
1486 (*m_bigmatrix)[irow][icol] += secondderiv;
1487 }
1488
1489 //________________________________________________________________________
1490 void MatrixTool::printGlobalSolution(std::ostream & os, const CLHEP::HepSymMatrix * cov)
1491 {
1492 const AlignModuleList * alignModules = m_alignModuleTool->alignModules1D();
1493
1494 AlignModuleList::const_iterator imod = alignModules->begin();
1495 AlignModuleList::const_iterator imod_end = alignModules->end();
1496 for( ; imod!=imod_end; ++imod) {
1497 AlignModule * module = *imod;
1498
1499 DataVector<AlignPar> * alignPars = m_alignModuleTool->getAlignPars(module);
1500 int thisNDoF = alignPars->size();
1501
1502 // fill local covariance matrix
1503 CLHEP::HepSymMatrix * covsub = nullptr;
1504 if(cov && module->nHits() >= m_minNumHits && module->nTracks() >= m_minNumTrks) {
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();
1509
1510 std::vector<int>::iterator itActive = std::find(m_activeIndices.begin(),m_activeIndices.end(),ipar);
1511 if( itActive == m_activeIndices.end() )
1512 continue;
1513 int iActive = std::distance(m_activeIndices.begin(),itActive);
1514
1515 for (int j=0;j<=i;++j) {
1516 int jpar = alignPars->at(j)->index();
1517 double sigma_j = alignPars->at(j)->sigma();
1518
1519 std::vector<int>::iterator jtActive = std::find(m_activeIndices.begin(),m_activeIndices.end(),jpar);
1520 if( jtActive == m_activeIndices.end() )
1521 continue;
1522 int jActive = std::distance(m_activeIndices.begin(),jtActive);
1523
1524 (*covsub)[i][j] = (*cov)[iActive][jActive] * sigma_i * sigma_j;
1525 }
1526 }
1527 }
1528
1529 printModuleSolution(os,module,covsub);
1530
1531 delete covsub;
1532 }
1533 os << "--------------------------------------------------------------------------------" << std::endl;
1534 }
1535
1536 //________________________________________________________________________
1537 void MatrixTool::printGlobalSolution(std::ostream & os, const TMatrixDSym * cov0)
1538 {
1539 CLHEP::HepSymMatrix * cov = nullptr;
1540 if(cov0) {
1541 int nsize = cov0->GetNrows();
1542 cov = new CLHEP::HepSymMatrix(nsize,0);
1543
1544 for(int i=0; i<nsize; i++)
1545 for(int j=0; j<=i; j++)
1546 (*cov)[i][j] = (*cov0)[i][j];
1547 }
1548
1549 printGlobalSolution(os,cov);
1550
1551 delete cov;
1552 }
1553
1574 //________________________________________________________________________
1575 void MatrixTool::printModuleSolution(std::ostream & os, const AlignModule * module, const CLHEP::HepSymMatrix * cov) const
1576 {
1577 os << "--------------------------------------------------------------------------------" << std::endl;
1578 os << "Alignment parameters for module: " << module->name() << std::endl;
1579 os << "Number of tracks passing: " << module->nTracks() << std::endl;
1580 if(m_minNumHits>0 && module->nHits()<m_minNumHits) {
1581 os << "Number of hits too small: "<<module->nHits()<<" < "<<m_minNumHits<<" Skipping the module\n";
1582 return;
1583 }
1584 if(m_minNumTrks>0 && module->nTracks()<m_minNumTrks) {
1585 os << "Number of tracks too small: "<<module->nTracks()<<" < "<<m_minNumTrks<<" Skipping the module\n";
1586 return;
1587 }
1588 os << "Number of hits seen: " << module->nHits() << std::endl;
1589 os << "Number of tracks seen: " << module->nTracks() << std::endl;
1590
1591 DataVector<AlignPar> * alignPars = m_alignModuleTool->getAlignPars(module);
1592 int thisNDoF = alignPars->size();
1593
1594 if(alignPars->empty())
1595 os << "No active parameters" << std::endl;
1596 else
1597 {
1598 // output alignment parameters and errors
1599 DataVector<AlignPar>::const_iterator ipar = alignPars->begin();
1600 DataVector<AlignPar>::const_iterator ipar_end = alignPars->end();
1601 for ( ; ipar != ipar_end; ++ipar) {
1602 const AlignPar * par = *ipar;
1603 os << std::format("{:<10}{:<12.5g} +/- {:<12.5g}\n",
1604 par->dumpType(),
1605 par->par(),
1606 par->err());
1607 }
1608
1609 if(cov) {
1610 // calculate local correlation matrix
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;
1616 }
1617 }
1618 }
1619
1620 //________________________________________________________________________
1622 {
1623 return 0;
1624 }
1625
1626 //________________________________________________________________________
1628 {
1629 ATH_MSG_INFO("solving Global using Lapack");
1630 if(m_logStream) {
1631 *m_logStream<<"*************************************************************\n";
1632 *m_logStream<<"************** solving using Global method ****************\n";
1633 *m_logStream<<"************** using LAPACK ****************\n";
1634 *m_logStream<<"*************************************************************\n";
1635 }
1636
1637 // get rescaled first and second derivatives
1638 AlSymMat* aBetterMat = new AlSymMat(m_aNDoF);
1639 AlVec* aBetterVec = new AlVec(m_aNDoF);
1640 for (int iActive=0;iActive<m_aNDoF;iActive++) {
1641 int i = m_activeIndices[iActive];
1642 (*aBetterVec)[iActive] = (*m_bigvector)[i];
1643 for (int jActive=0;jActive<m_aNDoF;jActive++) {
1644 int j = m_activeIndices[jActive];
1645 (*aBetterMat)[iActive][jActive] = (*m_bigmatrix)[i][j];
1646 }
1647 }
1648
1649 // normalize bigmatrix and bigvector
1650 if(m_scaleMatrix) {
1651 if(m_scale<=0.)
1652 ATH_MSG_WARNING("Scaling requested but scale not set. Not scaling matrix and vector.");
1653 else {
1654 (*aBetterVec) *= 1./m_scale;
1655 (*aBetterMat) *= 1./m_scale;
1656 }
1657 }
1658
1659 ATH_MSG_DEBUG("Now Solving alignment using lapack diagonalization routine dspev...");
1660
1661 if (m_calDet) {
1662 const double tol = 1.e-20;
1663 // compute final determinant
1664 double determ = (*aBetterMat).determinant();
1665 ATH_MSG_INFO("Determinant: " << determ);
1666 if (fabs(determ) < tol)
1667 ATH_MSG_WARNING("Matrix is singular!");
1668 }
1669
1670 // store the original matrix for checks
1671 AlSymMat * d2Chi2 = nullptr;
1673 d2Chi2 = new AlSymMat(*aBetterMat);
1674
1675 clock_t starttime = clock();
1676
1677 // declare transition matrix + vector to store eigenvalues
1679 AlVec w(m_aNDoF); // vector to store the eigenvalues
1680 ATH_MSG_DEBUG("MatrixTool::after z/w allocation");
1681
1682 char jobz = 'V';
1683 int info = (*aBetterMat).diagonalize(jobz,w,z);
1684 ATH_MSG_DEBUG(" info: " << info);
1685 ATH_MSG_INFO("MatrixTool::after diagonalization");
1686
1687 // stop time calculation
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");
1691
1692 double time_solve = 0.;
1693 if (info==0) {
1694 starttime = clock();
1695 postSolvingLapack(aBetterVec,d2Chi2,w,z,m_aNDoF);
1696 stoptime = clock();
1697 time_solve = (stoptime-starttime)/double(CLOCKS_PER_SEC);
1698 ATH_MSG_INFO(" - time spent solving the system: "<<time_solve<<" s");
1699 if(m_logStream) {
1700 *m_logStream<<"time spent for diagonalization: "<<time_diag<<" s\n";
1701 *m_logStream<<"time spent for post-solving: "<<time_solve<<" s\n";
1702 }
1703 }
1704 else {
1705 ATH_MSG_ERROR("Problem in diagonalization. Solving skipped.");
1706 if(m_logStream)
1707 *m_logStream<<"time spent for diagonalization: "<<time_diag<<" s\n";
1708 }
1709
1710 if(m_logStream) {
1711 *m_logStream<<"total time spent in solve: "<<time_diag+time_solve<<" s\n";
1712 *m_logStream<<"\n";
1713 }
1714
1715 delete d2Chi2;
1716 delete aBetterMat;
1717 delete aBetterVec;
1718
1719 // need to do this since success return value from Lapack is 0
1720 // and from solveLapack() it is 1
1721 if (info==0)
1722 info = 1;
1723
1724 return info;
1725 }
1726
1727 //________________________________________________________________________
1729 {
1730
1731 // copied from SiGlobalChi2Algs
1732 ATH_MSG_DEBUG("in spuriousRemoval");
1733
1734 // compute determinant before resizing
1735 if (m_calDet) {
1736 const double tol = 1.e-20;
1737 double determ = m_bigmatrix->determinant();
1738 ATH_MSG_INFO("Determinant: " << determ);
1739 if (std::fabs(determ) < tol)
1740 ATH_MSG_WARNING("Matrix is singular!");
1741 }
1742
1743 // fill vector with modules that need to be removed
1744 int fillvecmods=fillVecMods();
1745 if (fillvecmods==0) {
1746
1747 //ATH_MSG_INFO(" No resize needed (NhitsCut = "
1748 // << m_hitscut << ")");
1749
1750 if (msgLvl(MSG::DEBUG)) {
1751 //m_bigmatrix->Write("bigmatrix.txt", false, m_wSqMatrix, m_scale,
1752 // MatVersion);
1753 //m_bigvector->Write("bigvector.txt", false, m_scale, m_modcodemap,
1754 // VecVersion, m_alignProcessLevel, m_fitParam);
1755 }
1756
1757 return StatusCode::SUCCESS;
1758 }
1759 else if (fillvecmods==2)
1760 return StatusCode::FAILURE;
1761
1762 /* this is a bit difficult to implement for now....
1763
1764 // remove matrix/vector elements
1765 int cont=0;
1766 ModuleIndexMap::iterator itcode;
1767 ATH_MSG_INFO("Eliminating module...");
1768
1769
1770
1771 for (std::vector<int>::const_iterator it=m_dropmods.begin();
1772 it!= m_dropmods.end(); ++it) {
1773
1774 itcode = m_modcodemap.find((*it));
1775
1776 if (itcode == m_modcodemap.end()) {
1777 ATH_MSG_WARNING("Could not find module " << *it << " in map.");
1778 return StatusCode::FAILURE;
1779 }
1780
1781 ATH_MSG_INFO(" - Removing mcode: " << (itcode->second)
1782 << " (old index: " << (*it) << " -> new index: " << (*it)-cont << ")");
1783
1784 m_bigmatrix->RemoveModule((*it)-cont);
1785 m_bigvector->RemoveModule((*it)-cont);
1786 cont++;
1787 }
1788 ATH_MSG_INFO("Modules removed from the Matrix and from the Vector Successfully!");
1789 ATH_MSG_DEBUG("(DoF: " << nDoF << ")");
1790
1791 // resizing...
1792 ATH_MSG_INFO("Resizing the bigvector in memory...");
1793 m_bigvector->reSize(nDoF-6*m_dropmods.size());
1794 ATH_MSG_INFO("Resizing the bigmatrix in memory...");
1795 m_bigmatrix->reSize(nDoF-6*m_dropmods.size());
1796
1797 ATH_MSG_INFO(m_dropmods.size() << " modules eliminated from the matrix, i.e, "
1798 << 6*m_dropmods.size() << " DoFs");
1799 ATH_MSG_INFO(nDoF/6 - m_dropmods.size() << " modules to align (" << nDoF-6*m_dropmods.size() << " DoFs)");
1800 ATH_MSG_INFO("New bigmatrix size is: " << m_bigmatrix->size());
1801 ATH_MSG_INFO("New bigvector size is: " << (*m_bigvector).size());
1802
1803 NDoF = nDoF-6*(m_dropmods.size());
1804
1805 // resize (update) nDoF variable
1806 nDoF = NDoF;
1807
1808 // Resizing vectors to store results
1809 m_alignPar->reSize(nDoF);
1810 m_alignSqErr->reSize(nDoF);
1811
1812 // Fill the mapping module map and updating m_modcodemap
1813 UpdateModMap();
1814 */
1815
1816 return StatusCode::SUCCESS;
1817 }
1818
1819 //________________________________________________________________________
1820 void MatrixTool::postSolvingLapack(AlVec * dChi2, AlSymMat * d2Chi2, AlVec &w, AlMat &z, int size)
1821 {
1822 ATH_MSG_DEBUG("in postSolvinglapack()");
1823
1824 if( z.ncol() != size) {
1825 msg(MSG::ERROR)<<"Eigenvector matrix has incorrect size : "<<z.ncol()<<" != "<<size<<endmsg;
1826 return;
1827 }
1828
1829 if( (int)m_activeIndices.size() != size) {
1830 msg(MSG::ERROR)<<"Number of active parameters is incorrect : "<<m_activeIndices.size()<<" != "<<size<<endmsg;
1831 return;
1832 }
1833
1834 // Compute bigvector in diagonal basis (Vb = Ut * bigvector)
1835 AlVec D(size);
1836 D = z*(*dChi2);
1837
1838 if (m_writeEigenMat) {
1839
1840 ATH_MSG_INFO("writing the eigenvectors in a matrix: "<< z.nrow() << "x" << z.ncol());
1841
1842 // Set Path for the z matrix (eigenvector matrix)
1843 z.SetPathBin(m_pathbin.value()+m_prefixName.value());
1844 z.SetPathTxt(m_pathtxt.value()+m_prefixName.value());
1845
1846 ATH_MSG_INFO("writing the eigenvector matrix: "<< m_scalaMatName);
1847 ATH_MSG_DEBUG("matrix will be in: "<< m_pathbin.value()+m_prefixName.value()+m_scalaMatName.value());
1848
1849 StatusCode sc = z.Write(m_scalaMatName, true); // write the eigenvector matrix
1850
1851 if (sc!=StatusCode::SUCCESS)
1852 msg(MSG::ERROR)<<"Problem writing eigenvector matrix"<<endmsg;
1853
1854 // Set Path for the w matrix (eigenvalues matrix - diagonal bigmatrix)
1855 w.SetPathBin(m_pathbin.value()+m_prefixName.value());
1856 w.SetPathTxt(m_pathtxt.value()+m_prefixName.value());
1857
1858 ATH_MSG_INFO("writing the eigenvectors in a vector: "<< w.size());
1859 ATH_MSG_INFO("writing the eigenvalues vector (diagonal bigmatrix): "<< m_scalaVecName);
1860 ATH_MSG_DEBUG("vector will be in: "<< m_pathbin.value()+m_prefixName.value()+m_scalaVecName.value());
1861
1862 sc = w.WriteEigenvalueVec(m_scalaVecName, true); // write the eigenvalues vecor
1863
1864 if (sc!=StatusCode::SUCCESS)
1865 msg(MSG::ERROR)<<"Problem writing eigenvector matrix"<<endmsg;
1866
1867 if (m_writeEigenMatTxt) {
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;
1874 }
1875
1876 }
1877
1878 // Set eigenvalue thresholds
1879 const double eigenvalue_threshold = 1e-19;
1880
1881 // weak mode removal
1882 if (m_modcut == -1) {
1883
1884 ATH_MSG_INFO(" Starting the automatic Weak Mode Removal method");
1885
1886 // create a pull vector for the alignment corrections in diagonal basis (db_pulls)
1887 //int nDoF=m_alignModuleTool->nAlignParameters();
1888 AlVec* Align_db = new AlVec(size);
1889 AlVec* Align_error_db = new AlVec(size);
1890 AlVec* AlignPull = new AlVec(size);
1891 ATH_MSG_DEBUG("AlignPull vector size is: "<< (*AlignPull).size());
1892
1893 m_modcut = 0;
1894 bool wm_stop = false;
1895
1896 // -----------------------------------------------------------------------
1897 // First pass: removing weak modes because of large pull
1898 // compute alignment pulls for corrections in diagonal basis (db)
1899 for(int i=0; i<size; i++) {
1900
1901 (*Align_db)[i] = (-D[i]/w[i]);
1902 if(m_scale<=0.)[[unlikely]]{
1903 ATH_MSG_WARNING("postSolvingLapack: Scaling requested but scale not set. Not scaling matrix and vector.");
1904 } else {
1905 (*Align_error_db)[i] = sqrt(1.0/w[i]/m_scale);
1906 }
1907
1908 if (w[i]<eigenvalue_threshold) {
1909 ATH_MSG_INFO(" + EigenMode " << i
1910 << " removed as eigenvalue lower than the threshold " << eigenvalue_threshold
1911 << ": " << w[i]);
1912 (*AlignPull)[i] = 0.0;
1913 ++m_modcut;
1914 }
1915 else
1916 (*AlignPull)[i] = (*Align_db)[i] / (*Align_error_db)[i];
1917
1918 ATH_MSG_DEBUG(i << ". AlignPar: " << (*Align_db)[i] << " +- " << (*Align_error_db)[i]
1919 << " (pull: " << (*AlignPull)[i] << ") ; w[i]: " << w[i]);
1920 }
1921 ATH_MSG_INFO(" +++ Weak Mode removal ++ stop after mode "<< m_modcut << " (First pass)");
1922 // -----------------------------------------------------------------------
1923
1924 // -----------------------------------------------------------------------
1925 // Second pass
1926 // if the error is greater than the correction -> cut this mode
1927 for(int i=m_modcut; (i<size && !wm_stop); i++) {
1928
1929 // if the error is greater than the correction -> cut this mode
1930 if (fabs((*AlignPull)[i])<m_pullcut) {
1931 ATH_MSG_INFO(" + EigenMode " << i
1932 << " removed as pull is lower than " << m_pullcut << ": "
1933 << (*AlignPull)[i]);
1934 ++m_modcut;
1935 }
1936 else
1937 wm_stop = true;
1938
1939 }
1940 ATH_MSG_INFO(" +++ Weak Mode removal ++ stop after mode "<< m_modcut << " (Second pass)");
1941 // -----------------------------------------------------------------------
1942
1943 wm_stop = false;
1944
1945 // ----------------------------------------------------------------------
1946 // Third pass
1947 // Check if the next eigenvalues is far away. If it is two orders of
1948 // magnitude bigger remove also this mode and allow the search
1949 for(int i=m_modcut; (i<size && !wm_stop); i++) {
1950
1951 // if the next eigenvalues is far away -> cut this mode
1952 if (m_eigenvalueStep*w[i]<w[i+1]) {
1953 ATH_MSG_INFO(" + EigenMode " << i
1954 << " removed as diff between eigenvalues, " << w[i] << " and " << w[i+1]
1955 << ", is greater than " << m_eigenvalueStep);
1956 ++m_modcut;
1957 }
1958 else
1959 wm_stop = true;
1960
1961 }
1962 ATH_MSG_INFO(" +++ Weak Mode removal ++ stop after mode "<< m_modcut << " (Third pass)");
1963 // -----------------------------------------------------------------------
1964
1965 wm_stop = false;
1966
1967 // -----------------------------------------------------------------------
1968 // Fourth pass
1969 // Check if the next eigenvalues is far away. If it is two orders of
1970 // magnitude bigger remove also this mode and allow the search
1971 for(int i=m_modcut; (i<size && !wm_stop); i++) {
1972
1973 // if the next eigenvalues is far away -> cut this mode
1974 if ( fabs((*Align_db)[i]) > m_Align_db_step*fabs((*Align_db)[i+1]) ) {
1975 ATH_MSG_INFO(" + EigenMode " << i
1976 << " removed as diff between corrections, " << w[i] << " and " << w[i+1]
1977 << ", is greater than "
1978 << m_Align_db_step);
1979 ++m_modcut;
1980 }
1981 else
1982 wm_stop = true;
1983
1984 }
1985 ATH_MSG_INFO(" +++ Weak Mode removal ++ stop after mode "<< m_modcut << " (Fourth pass)");
1986 // -----------------------------------------------------------------------------------------------------
1987
1988 // Free memory and clear the pointer to
1989 // prevent using invalid memory reference
1990 delete Align_db;
1991 delete Align_error_db;
1992 delete AlignPull;
1993 Align_db = nullptr;
1994 Align_error_db = nullptr;
1995 AlignPull = nullptr;
1996
1997 } // end of if(m_modcut == -1)
1998
1999 // Save some stuff to debug purposes
2000 /*
2001 if (m_storeDia) {
2002 std::string path = m_pathtxt+m_prefixName+"align_dia";
2003 std::fstream orthogon(path.c_str(), std::ios::out);
2004 orthogon.setf(std::ios::fixed);
2005 orthogon.setf(std::ios::showpoint);
2006 orthogon.precision(6);
2007
2008 orthogon << std::setw(10)
2009 << "--------------------------------------------------------------------------------"
2010 << std::endl;
2011 orthogon << std::setw(10) << " ModeCut = " << m_modcut << std::endl;
2012 orthogon << std::setw(10)
2013 << "--------------------------------------------------------------------------------"
2014 << std::endl;
2015
2016 orthogon << std::setw(10) << "mode"
2017 << std::setw(20) << "eigenmode"
2018 << std::setw(20) << "eigenmode error"
2019 << std::setw(25) << "eigenvalue"
2020 << std::endl;
2021
2022 for( int m=0; m<size; m++) {
2023
2024 // mode
2025 orthogon << std::setw(10) << m;
2026
2027 // eigenmode (db)
2028 if( w[m]>1.0e-15) orthogon << std::setw(20) << -D[m]/w[m];
2029 else orthogon << std::setw(20) << 0.0;
2030
2031 // error eigenmode (error_db)
2032 if( w[m]>1.0e-15) orthogon << std::setw(20) << sqrt(1.0/w[m]/m_scale);
2033 else orthogon << std::setw(20) << 0.0;
2034
2035 // eigenvalues
2036 orthogon << std::setw(25) << w[m] << std::endl;
2037 }
2038 orthogon.close();
2039 } // end store align_dia.txt
2040 */
2041
2042 AlVec delta(size);
2043 AlVec deltafull(size);
2044 AlVec errSq(size);
2045
2046 // full covariance matrix
2047 CLHEP::HepSymMatrix * cov = nullptr;
2049 // Warning ! The matrix can be huge!
2050 // This can lead to memory problems
2051 cov = new CLHEP::HepSymMatrix(size,0);
2052
2053 if(m_logStream)
2054 *m_logStream<<"/------ The Eigenvalue Spectrum -------\n";
2055
2056 for (int i=0;i<size;i++) {
2057 AlVec thisdelta(size);
2058 for(int j=0;j<size;j++)
2059 thisdelta[j] = z[i][j] * (-D[i]/w[i]);
2060 deltafull += thisdelta;
2061
2062 ATH_MSG_DEBUG("eigenvalue "<<w[i]);
2063 if( i<m_modcut ) {
2064 ATH_MSG_INFO("skipping eigenvalue "<<w[i]<<" , modcut is "<<m_modcut);
2065 if(m_logStream)
2066 *m_logStream<<"| skipping eigenvalue "<<w[i]<<"\n";
2067 }
2068 else if( w[i] < m_eigenvaluethreshold ) {
2069 ATH_MSG_INFO("skipping eigenvalue "<<w[i]<<" , cut is "<<m_eigenvaluethreshold);
2070 if(m_logStream)
2071 *m_logStream<<"| skipping eigenvalue "<<w[i]<<"\n";
2072 }
2073 else {
2074 if(m_logStream)
2075 *m_logStream<<"| "<<w[i]<<"\n";
2076
2077 delta += thisdelta;
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];
2083 }
2084 }
2085 }
2086 }
2087
2088 if(m_logStream)
2089 *m_logStream<<"\\----- End of Eigenvalue Spectrum -----\n";
2090
2091 ATH_MSG_DEBUG("Alignment constants:");
2092
2093 DataVector<AlignPar> * alignParList = m_alignModuleTool->alignParList1D();
2094
2095 // compute alignment corrections (translations in mm and rotations in rad) and their variances
2096 for(int i=0; i<size; i++) {
2097
2098 double param = delta[i];
2099 double err = sqrt(2.*std::fabs(errSq[i]));
2100
2101 int idof = m_activeIndices[i];
2102 AlignPar * alignPar=(*alignParList)[idof];
2103
2104 // undo the sigma scaling
2105 double sigma = alignPar->sigma();
2106
2107 param *= sigma;
2108 err *= sigma;
2109
2110 // undo normalization scaling of error
2111 if(m_scaleMatrix && m_scale>0.)
2112 err /= sqrt(m_scale);
2113
2114 ATH_MSG_DEBUG(i <<" : "<< param << " +/- "<< err);
2115 ATH_MSG_DEBUG("cov("<<i<<")="<<errSq[i]<<", sigma: "<<sigma);
2116 ATH_MSG_DEBUG("init par: "<<alignPar->initPar());
2117 alignPar->setPar(param, err);
2118 ATH_MSG_DEBUG("set param to "<<param<<" for alignPar "<<alignPar);
2119 ATH_MSG_DEBUG(*(*alignParList)[idof]);
2120 }
2121
2122 if(m_logStream) {
2124
2125 // norm of first derivative
2126 double norm1st = dChi2->norm();
2127 if(m_scaleMatrix && m_scale>0.) // undo normalization scaling
2128 norm1st *= m_scale;
2129 *m_logStream<<"norm of first derivative : "<<norm1st<<"\n";
2130
2131 if(d2Chi2) {
2132 // distance to solution
2133 double dist = ( (*d2Chi2) * deltafull + (*dChi2) ).norm();
2134 if(m_scaleMatrix && m_scale>0.) // undo normalization scaling
2135 dist *= m_scale;
2136 *m_logStream<<"distance to solution : "<<dist<<"\n";
2137
2138 // calculate chi2 of the alignment change
2139 double chi2 = delta * (*d2Chi2) * delta * .5;
2140 if(m_scaleMatrix && m_scale>0.) // undo normalization scaling
2141 chi2 *= m_scale;
2142 *m_logStream<<"delta(chi2) of the alignment change : "<<chi2<<" / "<<size<<"\n";
2143 }
2144 }
2145
2146 delete cov;
2147 }
2148
2149 //________________________________________________________________________
2151 {
2152 ATH_MSG_INFO("solving Global using SparseEigen");
2153 if(m_logStream) {
2154 *m_logStream<<"*************************************************************\n";
2155 *m_logStream<<"************** solving using Global method ****************\n";
2156 *m_logStream<<"************** using SparseEigen ****************\n";
2157 *m_logStream<<"*************************************************************\n";
2158 }
2159
2160 // start measuring time
2161 clock_t starttime = clock();
2162
2163 DataVector<AlignPar> * alignParList = m_alignModuleTool->alignParList1D();
2164
2165 AlSpaMat * ABetterMat = nullptr;
2166 bool isCopy = false;
2167 if ( dynamic_cast<AlSymMat*>(m_bigmatrix) ) {
2168 ATH_MSG_INFO("Converting Matrix Format for fast solving");
2169 ABetterMat = new AlSpaMat(*(dynamic_cast<AlSymMat*>(m_bigmatrix)));
2170 isCopy = true;
2171 }
2172 else if ( dynamic_cast<AlSpaMat*>(m_bigmatrix) ) {
2173 ATH_MSG_INFO("Matrix format native to the fast solving");
2174 ABetterMat = (dynamic_cast<AlSpaMat*>(m_bigmatrix));
2175 }
2176 else {
2177 ATH_MSG_ERROR("Cannot cast to neither AlSymMat nor AlSpaMat");
2178 return 0;
2179 }
2180
2181 ATH_MSG_DEBUG("checking active indices");
2182
2183 // use const matrix when checking for non-zero elements to avoid
2184 // filling of the whole matrix
2185 const AlSpaMat * chkMatrix = ABetterMat;
2186
2187 AlSpaMat * aBetterMat = new AlSpaMat(m_aNDoF);
2188 AlVec * aBetterVec = new AlVec(m_aNDoF);
2189
2190
2191 for (int iActive=0;iActive<m_aNDoF;iActive++) {
2192 int i = m_activeIndices[iActive];
2193 (*aBetterVec)[iActive] = (*m_bigvector)[i];
2194 for (int jActive=0;jActive<m_aNDoF;jActive++) {
2195 int j = m_activeIndices[jActive];
2196 // only fill if non-zero !!!
2197 if ( (*chkMatrix)[iActive][jActive] != 0. )
2198 (*aBetterMat)[iActive][jActive]=(*ABetterMat)[i][j];
2199 }
2200 }
2201
2202 // store original vector for cross-checks
2203 AlVec origVec(*aBetterVec);
2204
2205 ATH_MSG_DEBUG("running the solving");
2206
2207 // solve
2208 int info = (*aBetterMat).SolveWithEigen(*aBetterVec);
2209
2210 if(info == 0) {
2211 ATH_MSG_INFO("SolveWithEigen solving OK");
2212 if(m_logStream)
2213 *m_logStream<<"SolveWithEigen solving OK.\n";
2214 }
2215 else {
2216 ATH_MSG_ERROR( "SolveWithEigen error code (0 if OK) = "<<info );
2217 if(m_logStream)
2218 *m_logStream<<"SolveWithEigen error code (0 if OK) = "<<info<<"\n";
2219 }
2220
2221 if( isCopy )
2222 delete ABetterMat;
2223 ABetterMat = nullptr;
2224
2225 // stop measuring time
2226 clock_t stoptime = clock();
2227 double totaltime = (stoptime-starttime)/double(CLOCKS_PER_SEC);
2228 ATH_MSG_INFO("Time spent in SolveWithEigen: "<<totaltime<<" s");
2229
2230 ATH_MSG_DEBUG("Alignment constants:");
2231 // compute alignment corrections (translations in mm and rotations in rad)
2232 // for solveSparseEigen variances are not calculated
2233 for(int i=0; i<m_aNDoF; i++) {
2234
2235 double param = -(*aBetterVec)[i];
2236 double err = 0.;
2237
2238 int idof = m_activeIndices[i];
2239 AlignPar * alignPar=(*alignParList)[idof];
2240
2241 // undo the sigma scaling
2242 double sigma = alignPar->sigma();
2243 param *= sigma;
2244
2245 ATH_MSG_DEBUG(i <<" : "<< param << " +/- "<< err);
2246 ATH_MSG_DEBUG("sigma: "<<sigma);
2247 ATH_MSG_DEBUG("init par: "<<alignPar->initPar());
2248 alignPar->setPar(param, err);
2249 ATH_MSG_DEBUG("set param to "<<param<<" for alignPar "<<alignPar);
2250 ATH_MSG_DEBUG(*(*alignParList)[idof]);
2251 }
2252
2253 if(m_logStream) {
2254 CLHEP::HepSymMatrix * cov = nullptr;
2256
2257 // norm of first derivative
2258 *m_logStream<<"norm of first derivative : "<<origVec.norm()<<"\n";
2259
2260 // distance to solution
2261 double dist = ( (*aBetterMat) * (*aBetterVec) - origVec ).norm();
2262 *m_logStream<<"distance to solution : "<<dist<<"\n";
2263
2264 // calculate chi2 of the alignment change
2265 double chi2 = (*aBetterVec) * (*aBetterMat) * (*aBetterVec) * .5;
2266 *m_logStream<<"delta(chi2) of the alignment change : "<<chi2<<" / "<<m_aNDoF<<"\n";
2267
2268 // time spent here
2269 *m_logStream<<"time spent in solve : "<<totaltime<<" s\n";
2270 }
2271
2272 delete aBetterMat;
2273 delete aBetterVec;
2274
2275 // need to do this since success return value from Lapack is 0
2276 // and from SolveWithEigen() it is 1
2277 if (info==0)
2278 info = 1;
2279
2280 return info;
2281 }
2282
2283 //________________________________________________________________________
2285 {
2286 ATH_MSG_INFO("writing the hitmap to file");
2287
2288 const AlignModuleList * moduleList = m_alignModuleTool->alignModules1D();
2289 int nModules = moduleList->size();
2290
2291 AlMat hitmap(nModules,2);
2292 AlignModuleList::const_iterator imod = moduleList->begin();
2293 AlignModuleList::const_iterator imod_end = moduleList->end();
2294 int index(0);
2295 for(; imod != imod_end; ++imod) {
2296 AlignModule * module = *imod;
2297 hitmap[index][0] = module->nHits();
2298 hitmap[index][1] = module->nTracks();
2299 index++;
2300 }
2301
2302 // Set Path for the hitmap matrix
2303 hitmap.SetPathBin(m_pathbin.value()+m_prefixName.value());
2304 hitmap.SetPathTxt(m_pathtxt.value()+m_prefixName.value());
2305
2306 StatusCode sc = hitmap.Write("hitmap.bin",true); // write the hitmap matrix
2307
2308 if (sc!=StatusCode::SUCCESS)
2309 ATH_MSG_ERROR("Problem writing hitmap matrix");
2310
2311 if (m_writeHitmapTxt) {
2312 sc = hitmap.Write("hitmap.txt", false, 0);
2313 if (sc!=StatusCode::SUCCESS)
2314 ATH_MSG_ERROR("Problem writing hitmap matrix to text file");
2315 }
2316
2317 ATH_MSG_DEBUG("hitmap written to: "<< m_pathbin.value()+m_prefixName.value() <<"hitmap.bin (.txt)");
2318 }
2319
2320 //________________________________________________________________________
2322 {
2323 ATH_MSG_INFO("read hitmaps from files");
2324
2325 const AlignModuleList * moduleList = m_alignModuleTool->alignModules1D();
2326 int nModules = moduleList->size();
2327
2328 AlMat hitmap(nModules,2);
2329 int nFiles = (int)m_inputHitmapFiles.size();
2330 for(int imap=0;imap<nFiles; imap++) {
2331 AlMat nextmap(nModules,2);
2332
2333 ATH_MSG_INFO("Reading hitmap "<<imap<<" from file "<<m_inputHitmapFiles[imap]);
2334
2335 if(nextmap.ReadScalaPack(m_inputHitmapFiles[imap]).isFailure()) {
2336 ATH_MSG_WARNING("Problem reading hitmap from \'"<<m_inputHitmapFiles[imap]<<"\'. Skipping.");
2337 continue;
2338 }
2339
2340 if(nextmap.nrow()!=nModules || nextmap.ncol()!=2) {
2341 ATH_MSG_WARNING("Matrix in file \'"<<m_inputHitmapFiles[imap]<<"\' has wrong size ("
2342 <<nextmap.nrow()<<" x "<<nextmap.ncol()<<"), should be ("<<nModules<<" x 2). Skipping.");
2343 continue;
2344 }
2345
2346 hitmap += nextmap;
2347 }
2348
2349 AlignModuleList::const_iterator imod = moduleList->begin();
2350 AlignModuleList::const_iterator imod_end = moduleList->end();
2351 int index = 0;
2352 int totalhits = 0;
2353 for(; imod != imod_end; ++imod) {
2354 AlignModule * module = *imod;
2355 //if ((int)hitmap[index][0]!=(int)module->identify().get_identifier32().get_compact()) ATH_MSG_ERROR("bad module identifier");
2356 //module->setIdentifier((Identifier)hitmap[index][0]);
2357 module->setNHits((int)hitmap[index][0]);
2358 module->setNTracks((int)hitmap[index][1]);
2359 totalhits += (int)hitmap[index][0];
2360 index++;
2361 }
2362
2363 m_nHits = totalhits;
2364 m_nTracks = 0;
2365 m_nMeasurements = 0;
2366
2367 ATH_MSG_INFO("Hitmap accumulated from "<<nFiles<<" files with total of "<<totalhits<<" hits.");
2368 }
2369
2370} // end of namespace
2371
class TMatrixTSparse< double > TMatrixDSparse
Definition AlSpaMat.h:14
#define endmsg
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static Double_t a
static Double_t sc
size_t size() const
Number of registered mappings.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
Derived DataVector<T>.
Definition DataVector.h:795
DataModel_detail::const_iterator< DataVector > const_iterator
Standard const_iterator.
Definition DataVector.h:838
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
Definition AlMat.h:27
StatusCode ReadScalaPack(const std::string &)
Definition AlMat.cxx:372
long int nrow() const
Definition AlMat.h:157
StatusCode Write(const std::string &, bool, unsigned int precision=6)
Definition AlMat.cxx:414
void SetPathBin(const std::string &)
Definition AlMat.cxx:402
void SetPathTxt(const std::string &)
Definition AlMat.cxx:408
long int ncol() const
Definition AlMat.h:162
contains the implementation for handling sparse matrices
Definition AlSpaMat.h:27
virtual StatusCode Read(const std::string &, int &, bool &, float &) override final
Definition AlSpaMat.cxx:737
contains the base implementation for handling symmertic matrices
const datamap * ptrMap() const
contains the implementation for handling symmetric matrices in triangular representation
Definition AlSymMat.h:26
virtual StatusCode Read(const std::string &, int &, bool &, float &) override final
Definition AlSymMat.cxx:676
void SetPathBin(const std::string &)
Definition AlVec.cxx:308
double norm() const
Definition AlVec.cxx:211
StatusCode ReadPartial(const std::string &, double &, std::map< int, unsigned long long > &, float &)
Definition AlVec.cxx:464
void SetPathTxt(const std::string &)
Definition AlVec.cxx:314
int size() const
Definition AlVec.h:112
double sigma() const
returns sigma
Definition AlignPar.h:65
void setPar(double par, double err)
sets final parameter and error
Definition AlignPar.h:71
double initPar() const
returns initial parameter and error
Definition AlignPar.h:53
int nTracks() const
Definition IMatrixTool.h:88
IMatrixTool()
constructor
int nHits() const
Definition IMatrixTool.h:84
std::ostream * m_logStream
logfile output stream
Definition IMatrixTool.h:98
Gaudi::Property< std::string > m_tfileName
Definition MatrixTool.h:226
MatrixTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor.
Gaudi::Property< int > m_maxReadErrors
Definition MatrixTool.h:251
Gaudi::Property< std::string > m_prefixName
Definition MatrixTool.h:222
Gaudi::Property< bool > m_AlignIBLbutNotPixel
Definition MatrixTool.h:256
void prepareBinaryFiles(int solveOption)
reads/writes matrix entries from/to binary files as necessary
Gaudi::Property< bool > m_readHitmaps
Definition MatrixTool.h:193
Gaudi::Property< bool > m_wSqMatrix
Definition MatrixTool.h:176
Gaudi::Property< bool > m_Remove_Pixel_Ry
Definition MatrixTool.h:268
Gaudi::Property< bool > m_writeHitmap
Definition MatrixTool.h:189
Gaudi::Property< bool > m_Remove_Pixel_Rz
Definition MatrixTool.h:269
Gaudi::Property< bool > m_writeEigenMatTxt
Definition MatrixTool.h:184
Gaudi::Property< bool > m_Remove_IBL_Rx
Definition MatrixTool.h:275
double m_scale
scale for big matrix and vector normalization
Definition MatrixTool.h:204
Gaudi::Property< bool > m_runLocal
Definition MatrixTool.h:201
StatusCode spuriousRemoval()
Gaudi::Property< double > m_removeSpurious
Definition MatrixTool.h:211
Gaudi::Property< bool > m_Remove_Pixel_Tz
Definition MatrixTool.h:266
StatusCode allocateMatrix(int nDoF=0)
allocates memory for big matrix and big vector
std::vector< int > m_activeIndices
vector of indices which pass the min-hits cut
Definition MatrixTool.h:248
void addSecondDerivative(int irow, int icol, double secondderiv)
Gaudi::Property< bool > m_Remove_IBL_Rz
Definition MatrixTool.h:277
Gaudi::Property< bool > m_Remove_Pixel_Ty
Definition MatrixTool.h:265
bool accumulateFromFiles()
accumulates derivates from files.
Gaudi::Property< std::vector< std::string > > m_inputVectorFiles
Definition MatrixTool.h:237
AlVec * m_bigvector
vector to contain first derivative terms to be used for alignment
Definition MatrixTool.h:149
Gaudi::Property< bool > m_Remove_IBL_Tx
Definition MatrixTool.h:272
Gaudi::Property< int > m_minNumHits
Definition MatrixTool.h:163
static int fillVecMods()
Gaudi::Property< std::vector< std::string > > m_inputMatrixFiles
Definition MatrixTool.h:234
int m_aNDoF
number of active DoF (size of m_activeIndices)
Definition MatrixTool.h:249
Gaudi::Property< bool > m_Remove_Pixel_Tx
Definition MatrixTool.h:264
Gaudi::Property< double > m_calculateFullCovariance
Definition MatrixTool.h:215
Gaudi::Property< std::string > m_scalaVecName
Definition MatrixTool.h:231
Gaudi::Property< bool > m_Remove_IBL_Tz
Definition MatrixTool.h:274
int solve()
solves for alignment parameters
Gaudi::Property< float > m_eigenvalueStep
Definition MatrixTool.h:169
Gaudi::Property< float > m_Align_db_step
Definition MatrixTool.h:171
virtual ~MatrixTool()
Virtual destructor.
Gaudi::Property< bool > m_writeMatTxt
Definition MatrixTool.h:180
Gaudi::Property< std::vector< std::string > > m_inputHitmapFiles
Definition MatrixTool.h:241
void addSecondDerivatives(AlSymMatBase *matrix)
adds second derivatives to matrix
PublicToolHandle< IAlignModuleTool > m_alignModuleTool
Definition MatrixTool.h:142
Gaudi::Property< int > m_solveOption
Definition MatrixTool.h:160
Gaudi::Property< bool > m_writeHitmapTxt
Definition MatrixTool.h:191
bool accumulateFromTFiles()
Store Files in a tfile.
Gaudi::Property< bool > m_scaleMatrix
Definition MatrixTool.h:205
Gaudi::Property< bool > m_DeactivateSCT_ECA_LastDisk
Definition MatrixTool.h:261
Gaudi::Property< bool > m_writeMat
Definition MatrixTool.h:178
void storeInTFile(const TString &filename)
Store Files in a tfile.
void addFirstDerivatives(AlVec *vector)
adds first derivative to vector
void printModuleSolution(std::ostream &os, const AlignModule *module, const CLHEP::HepSymMatrix *cov) const
namespace { class RestoreIOSFlags { public: RestoreIOSFlags (std::ostream &os) : m_os(&os),...
Gaudi::Property< int > m_minNumTrks
Definition MatrixTool.h:165
Gaudi::Property< bool > m_diagonalize
Definition MatrixTool.h:154
Gaudi::Property< double > m_softEigenmodeCut
Definition MatrixTool.h:208
Gaudi::Property< std::vector< std::string > > m_inputTFiles
Definition MatrixTool.h:245
Gaudi::Property< bool > m_writeEigenMat
Definition MatrixTool.h:182
Gaudi::Property< int > m_modcut
Definition MatrixTool.h:161
Gaudi::Property< double > m_eigenvaluethreshold
Definition MatrixTool.h:157
Gaudi::Property< std::string > m_scalaMatName
Definition MatrixTool.h:229
Gaudi::Property< bool > m_writeTFile
Definition MatrixTool.h:196
Gaudi::Property< std::string > m_pathbin
Definition MatrixTool.h:218
Gaudi::Property< bool > m_useSparse
flag to use AlSpaMat for the big matrix (default is AlSymMat)
Definition MatrixTool.h:152
void postSolvingLapack(AlVec *dChi2, AlSymMat *d2Chi2, AlVec &w, AlMat &z, int size)
Gaudi::Property< bool > m_Remove_Pixel_Rx
Definition MatrixTool.h:267
Gaudi::Property< bool > m_calDet
Definition MatrixTool.h:174
AlSymMatBase * m_bigmatrix
matrix to contain second derivative terms to be used for alignment
Definition MatrixTool.h:146
Gaudi::Property< bool > m_AlignPixelbutNotIBL
Definition MatrixTool.h:258
@ SOLVE_FAST
Fast (Eigen method) solving after data accumulation.
Definition MatrixTool.h:61
@ SOLVE_ROOT
computation using ROOT
Definition MatrixTool.h:65
@ SOLVE
solving after data accumulation (LAPACK)
Definition MatrixTool.h:60
@ DIRECT_SOLVE_FAST
direct Fast (Eigen method) solving, already available matrix & vector
Definition MatrixTool.h:63
@ DIRECT_SOLVE
direct solving (LAPACK), already available matrix & vector
Definition MatrixTool.h:62
@ DIRECT_SOLVE_CLUSTER
computation of alignment parameters from SCALAPAK already solved matrix
Definition MatrixTool.h:64
@ NONE
not solve in any case (to be used when ipc)
Definition MatrixTool.h:59
@ SOLVE_CLHEP
computation using CLHEP
Definition MatrixTool.h:66
void addFirstDerivative(int irow, double firstderiv)
StatusCode finalize()
initialize
bool accumulateFromBinaries()
accumulates derivates from binary files
Gaudi::Property< bool > m_Remove_IBL_Ry
Definition MatrixTool.h:276
Gaudi::Property< float > m_pullcut
Definition MatrixTool.h:167
StatusCode initialize()
initialize
Gaudi::Property< bool > m_Remove_IBL_Ty
Definition MatrixTool.h:273
void printGlobalSolution(std::ostream &os, const CLHEP::HepSymMatrix *cov)
Gaudi::Property< bool > m_readTFiles
Definition MatrixTool.h:198
Gaudi::Property< std::string > m_pathtxt
Definition MatrixTool.h:220
Gaudi::Property< bool > m_writeModuleNames
Definition MatrixTool.h:186
double chi2(TH1 *h0, TH1 *h1)
void Scale(TH1 *h, double d=1)
int r
Definition globals.cxx:22
int ev
Definition globals.cxx:25
Ensure that the ATLAS eigen extensions are properly loaded.
std::vector< AlignModule * > AlignModuleList
@ z
global position (cartesian)
Definition ParamDefs.h:57
Definition dot.py:1
Definition index.py:1
#define unlikely(x)