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 = 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 = 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)//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 ATH_MSG_DEBUG("Memory usage [MB], total " << myusage.ru_maxrss/1024 << ", increase " << (myusage.ru_maxrss-intialMemUse)/1024);
865
866 TFile* myFile = TFile::Open(m_inputTFiles[ifile].c_str());
867
868 if ( myFile->IsZombie() || !(myFile->IsOpen()) ) {
869 ++numberOfReadErrors;
870 ATH_MSG_ERROR( " Problem reading TFile " << m_inputTFiles[ifile] );
871 continue;
872 }
873
874 std::map<int,unsigned long long> newModIndexMap;
875
876 TVectorD* myModuleIDs;
877 myModuleIDs = (TVectorD*)myFile->Get("ModuleID");
878 if( !myModuleIDs ){
879 ++numberOfReadErrors;
880 ATH_MSG_ERROR("Modules ID not read!!!");
881 continue;
882 }
883
884 for (int i(0); i<myModuleIDs->GetNrows(); ++i){
885 //Coverting back from a double to a unvi signed long long
886 double source = (*myModuleIDs)(i);
887 uint64_t target;
888 memcpy(&target, &source, sizeof(target));
889 newModIndexMap[i]=target;
890 //std::cout << i<< " " <<target <<"\n";
891 }
892
893 delete myModuleIDs;
894
895 std::map<int,unsigned long long> newDoFMap;
896
897 TVectorD* myDoFs;
898 myDoFs = (TVectorD*)myFile->Get("dof");
899 if( !myDoFs ){
900 ++numberOfReadErrors;
901 ATH_MSG_ERROR("DoFs not read!!!");
902 continue;
903 }
904
905 for (int i(0); i<myDoFs->GetNrows(); ++i){
906 //Coverting back from a double to a unsigned long long
907 double source = (*myDoFs)(i);
908 uint64_t target;
909 memcpy(&target, &source, sizeof(target));
910 newDoFMap[i]=target;
911 }
912 delete myDoFs;
913
914
915 TVectorD* Scale;
916 Scale = (TVectorD*)myFile->Get("Scale");
917 if( !Scale ){
918 ++numberOfReadErrors;
919 ATH_MSG_ERROR("Scale not read!!!");
920 continue;
921 }
922
923 double scale=(*Scale)(0);
924 totalscale += scale;
925 delete Scale;
926
927
928 ATH_MSG_DEBUG("Reading Vector");
929 TVectorD* vector = (TVectorD*)myFile->Get("Vector");
930 if( !vector ){
931 ++numberOfReadErrors;
932 ATH_MSG_ERROR("Vector not read!!!");
933 continue;
934 }
935
936 AlVec* newVector = new AlVec(nDoF);
937 newVector->SetPathBin(m_pathbin.value()+m_prefixName.value());
938 newVector->SetPathTxt(m_pathtxt.value()+m_prefixName.value());
939
940 if (newVector->size() != m_bigvector->size() ) {
941 msg(MSG::FATAL) << "vector wrong size! newVector size " << newVector->size()
942 << ", bigvector size " << m_bigvector->size()<<endmsg;
943 delete newVector;
944 delete vector;
945 return false;
946 }
947
948 if (m_bigvector->size() != vector->GetNrows() ) {
949 msg(MSG::FATAL) << "File vector wrong size! File Vector size " << vector->GetNrows()
950 << ", bigvector size " << m_bigvector->size()<<endmsg;
951 delete newVector;
952 delete vector;
953 return false;
954 }
955
956
957 for (int i=0;i<nDoF;i++) {
958 (*newVector)[i] = (*vector)(i);
959 }
960 delete vector;
961
962 // check modIndexMaps to make sure they are the same
963 if (ifile == 0){
964 DoFMap = newDoFMap;
965 } else if (DoFMap!=newDoFMap) {
966 msg(MSG::FATAL) << "module dofs don't agree!" << endmsg;
967 return false;
968 }
969
970 if (ifile == 0){
971 modIndexMap = newModIndexMap;
972 } else if (modIndexMap!=newModIndexMap) {
973 msg(MSG::FATAL) << "module index maps don't agree!" << endmsg;
974 return false;
975 }
976
977 if (ifile>0){
978 *m_bigvector += *newVector;
979 delete newVector;
980 } else {
981 delete m_bigvector;
982 m_bigvector = newVector;
983 }
984
985
986 ATH_MSG_DEBUG("Reading matrix ");
987 TMatrixDSparse* matrix = (TMatrixDSparse*)myFile->Get("Matrix");
988
989 if( !matrix ){
990 ++numberOfReadErrors;
991 ATH_MSG_ERROR("Matrix not read!!!");
992 continue;
993 }
994
995
996 if (ifile == 0 ){
997
998 accumMatrix = new AlSpaMat(nDoF);
999 ATH_MSG_DEBUG("Matrix size b4 "<< accumMatrix->ptrMap()->size() );
1000
1001 //This method is ok for large matrix files... really only access the non zero elements
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];
1008 if (i<j){
1009 ATH_MSG_DEBUG("i < j " );
1010 j = i;
1011 i = (myRow.GetColPtr())[jj];
1012 }
1013 (*accumMatrix)[i][j] = myElement;
1014 }
1015 }
1016 ATH_MSG_DEBUG("Matrix size AF "<< accumMatrix->ptrMap()->size() );
1017
1018 } else if ( accumMatrix) {
1019 ATH_MSG_DEBUG("Matrix size b4 "<< accumMatrix->ptrMap()->size() );
1020
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];
1027 if (i<j){
1028 ATH_MSG_DEBUG("i < j " );
1029 j = i;
1030 i = (myRow.GetColPtr())[jj];
1031 }
1032 (*accumMatrix)[i][j] += myElement;
1033 }
1034 }
1035 ATH_MSG_DEBUG("Matrix size AF "<< accumMatrix->ptrMap()->size() );
1036
1037 } else {
1038 delete matrix;
1039 ++numberOfReadErrors;
1040 ATH_MSG_ERROR("Matrix allocation error!!!");
1041 continue;
1042 }
1043
1044 delete matrix;
1045
1046 TVectorD* hits;
1047 TVectorD* tracks;
1048
1049 ATH_MSG_DEBUG("Reading hitmap ");
1050 hits = (TVectorD*)myFile->Get("Hits");
1051 if( !hits ){
1052 ++numberOfReadErrors;
1053 ATH_MSG_ERROR("Hitmap 1 not read!!!");
1054 continue;
1055 }
1056
1057 tracks = (TVectorD*)myFile->Get("Tracks");
1058 if( !tracks ){
1059 delete hits;
1060 ++numberOfReadErrors;
1061 ATH_MSG_ERROR("Hitmap 2 not read!!!");
1062 continue;
1063 }
1064
1065 if(hits->GetNrows() != TotalHits.GetNrows() ){
1066 delete hits;
1067 delete tracks;
1068 ++numberOfReadErrors;
1069 ATH_MSG_ERROR("Hitmap size incorrect!!!");
1070 continue;
1071 }
1072
1073 TotalHits += (*hits);
1074 TotalTracks += (*tracks);
1075
1076 delete hits;
1077 delete tracks;
1078
1079 myFile->Close("R");
1080 delete myFile;
1081
1082 itworked = getrusage(RUSAGE_SELF,&myusage);
1083 ATH_MSG_DEBUG("Memory usage [MB], total " << myusage.ru_maxrss/1024 << ", increase " << (myusage.ru_maxrss-intialMemUse)/1024);
1084
1085 }
1086
1087
1088
1089 // create new matrix to read data from current file
1090 if(accumMatrix){
1091 if (symBigMatrix) {
1092 AlSymMat newMatrix(nDoF);
1093 //This method is ok for small matrix files
1094 for (int i=0;i<nDoF;i++) {
1095 for (int j=0;j<=i;j++) {
1096 newMatrix[i][j] = (*accumMatrix)[i][j];
1097 }
1098 }
1099
1100 *symBigMatrix += newMatrix;
1101 delete accumMatrix;
1102 } else if (spaBigMatrix) {
1103 ATH_MSG_DEBUG( "should reassign matrix "<< spaBigMatrix->ptrMap()->size() );
1104 *spaBigMatrix += *accumMatrix;
1105 ATH_MSG_DEBUG( "?????? "<< spaBigMatrix->ptrMap()->size() );
1106 delete accumMatrix;
1107 }
1108 }
1109
1110 ATH_MSG_DEBUG( "?????? "<< m_bigmatrix->ptrMap()->size() );
1111
1112 AlignModuleList::const_iterator imod = moduleList->begin();
1113 AlignModuleList::const_iterator imod_end = moduleList->end();
1114 int index = 0;
1115 int totalhits = 0;
1116 for(; imod != imod_end; ++imod, ++index ) {
1117 AlignModule * module = *imod;
1118 module->setNHits((int)TotalHits(index));
1119 module->setNTracks((int)TotalTracks(index));
1120 totalhits += (int)TotalHits(index);
1121 }
1122
1123
1124 m_nHits = totalhits;
1125 m_nTracks = 0;
1126 m_nMeasurements = 0;
1127 m_scale = totalscale;
1128
1129 return true;
1130 }
1131
1132
1133
1134
1135 //_______________________________________________________________________
1137 {
1138 // ============
1139 // solve
1140 // ============
1141 ATH_MSG_DEBUG("in MatrixTool::solve()");
1142
1143 // set normalization scale to number of hits for now
1144 if(m_scale<0)
1145 m_scale = m_nHits;
1146
1147 //-------------------------------------------------------
1148 // write matrix and vector to file
1149 if (m_writeMat) {
1150 // version has to be 2 to for reading matrices and vectors back in to work properly
1151 double dummyVersion(2.);
1152
1153 // make map of matrix entry to module index (set by geometry manager tool)
1154 std::map<int,unsigned long long> modIndexMap;
1155 std::map<int,std::string> modNameMap;
1156 DataVector<AlignPar>* alignPars = m_alignModuleTool->alignParList1D();
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();
1160 }
1161
1162 // binary files
1163 ATH_MSG_DEBUG("writing binary files");
1164 StatusCode sc1 = m_bigmatrix->Write("matrix.bin",true,m_wSqMatrix,m_scale,dummyVersion);
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;
1168 return -1;
1169 }
1170
1171 if (m_writeMatTxt) {
1172
1173 // text files
1174 ATH_MSG_DEBUG("writing text files");
1175 sc1 = m_bigmatrix->Write("matrix.txt",false,m_wSqMatrix,m_scale,dummyVersion);
1176 sc2 = m_writeModuleNames ?
1177 m_bigvector->WritePartial("vector.txt",false,m_scale,modNameMap,dummyVersion) :
1178 m_bigvector->WritePartial("vector.txt",false,m_scale,modIndexMap,dummyVersion);
1179
1180 if (!sc1.isSuccess() || !sc2.isSuccess()) {
1181 msg(MSG::ERROR)<<"problem writing matrix or vector"<<endmsg;
1182 return -1;
1183 }
1184 }
1185
1186 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)");
1187 }
1188
1189 //-------------------------------------------------------
1190 // write hitmap to file
1191 if (m_writeHitmap)
1192 writeHitmap();
1193
1194 if(m_writeTFile)
1195 storeInTFile(m_pathbin.value()+m_prefixName.value()+m_tfileName.value());
1196
1197
1198 if(!m_runLocal && m_solveOption==0) {
1199 ATH_MSG_DEBUG("No solving requested.");
1200 return 1;
1201 }
1202
1203 //-------------------------------------------------------
1204 // rescale the vector and the matrix according to sigmas
1205 // and apply soft mode cut
1206
1207 ATH_MSG_DEBUG("rescaling the matrix/vector and applying the soft-mode-cut");
1208
1209 DataVector<AlignPar>* alignParList = m_alignModuleTool->alignParList1D();
1210 int nDoF = alignParList->size();
1211
1212
1213 const AlSymMat * chkMatrix = dynamic_cast<const AlSymMat*>(m_bigmatrix);
1214 if(chkMatrix){
1215 // Method when using the dense matrix
1216 for (int i=0;i<nDoF;i++) {
1217 // scale the vector
1218 double sigma_i = (*alignParList)[i]->sigma();
1219 double softCut = 2 * pow( (*alignParList)[i]->softCut() , -2 );
1220 (*m_bigvector)[i] *= sigma_i;
1221
1222 for (int j=0;j<=i;j++) {
1223 // scale the matrix
1224 if ((*chkMatrix)[i][j] != 0.) {
1225 double sigma_j = (*alignParList)[j]->sigma();
1226 (*m_bigmatrix)[i][j] *= sigma_i * sigma_j;
1227 }
1228 // apply soft-mode-cut
1229 if (i==j && m_softEigenmodeCut>0.){
1230 (*m_bigmatrix)[i][j] += m_softEigenmodeCut * softCut;
1231
1232 }
1233
1234 // set first and second derivatives on AlignPar
1235 if (i==j) {
1236 (*alignParList)[i]->setFirstDeriv((*m_bigvector)[i]/sigma_i);
1237 (*alignParList)[i]->setSecndDeriv((*m_bigmatrix)[i][i]/sigma_i/sigma_i);
1238 }
1239 }
1240 }
1241 } else {
1242 // Method when using the sparse matrix
1243 for (const datamap::value_type& p : *m_bigmatrix->ptrMap()) {
1244 int i = p.first.first;
1245 int j = p.first.second;
1246
1247 // Scale matrix
1248 double sigma_i = (*alignParList)[i]->sigma();
1249 double sigma_j = (*alignParList)[j]->sigma();
1250
1251 (*m_bigmatrix)[i][j] *= sigma_i * sigma_j;
1252
1253 }
1254
1255
1256 for (int i=0;i<nDoF;i++) {
1257 // scale the vector
1258 double sigma_i = (*alignParList)[i]->sigma();
1259 (*m_bigvector)[i] *= sigma_i;
1260 if (m_softEigenmodeCut >0. ){
1261 double softCut = 2 * pow( (*alignParList)[i]->softCut() , -2 );
1262 (*m_bigmatrix)[i][i] += m_softEigenmodeCut * softCut;
1263 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]);
1264 }
1265 (*alignParList)[i]->setFirstDeriv((*m_bigvector)[i]/sigma_i);
1266 (*alignParList)[i]->setSecndDeriv((*m_bigmatrix)[i][i]/sigma_i/sigma_i);
1267 }
1268 }
1269
1270 unsigned long long OldPixelIdentifier = 37769216; //Identifier for the Pixel Detector
1271 unsigned long long IBLIdentifier = 33574912; //Identifier for the Pixel Detector
1272
1273 unsigned long long SCT_ECA_8_Identifier = 218116096; //Identifier for the SCT ECA Last Disk
1274 std::string SCT_ECA_8_Name = "SCT/EndcapA/Disk_8";
1275
1276
1277
1278 ATH_MSG_INFO("rescaling done");
1279 ATH_MSG_INFO("Javi: Printing (*alignParList)[i]->alignModule()->identify32()");
1280
1281 // select modules with non-zero tracks
1282 for(int i=0;i<nDoF;i++)
1283 {
1284 ATH_MSG_DEBUG(i);
1285 ATH_MSG_DEBUG((*alignParList)[i]->alignModule()->identify32());
1286 ATH_MSG_DEBUG((*alignParList)[i]->alignModule());
1287 ATH_MSG_DEBUG((*alignParList)[i]->alignModule()->name());
1288 ATH_MSG_DEBUG((*alignParList)[i]->paramType());
1289
1290 //Skip solving for Pixel or IBL:
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);
1299
1301 if (SCTECA8)
1302 {ATH_MSG_INFO( "SCT ECA Last Disk DoF have been skipped in the solving because DeactivateSCT_ECA_LastDisk is set to True");
1303 continue;}
1304 if (SCTECA8_n)
1305 {ATH_MSG_INFO( "SCT ECA Last Disk DoF have been skipped in the solving because DeactivateSCT_ECA_LastDisk is set to True");
1306 continue;}
1307 }
1308
1309 if (m_AlignIBLbutNotPixel) //If m_AlignIBLbutNotPixel is set to True, Pixel will be skipped in the solving.
1310 if (oldPixel)
1311 {ATH_MSG_INFO( "Pixel DoF have been skipped in the solving because AlignIBLbutNotPixel is set to True");
1312 continue;}
1313
1314 if (m_AlignPixelbutNotIBL) //If m_AlignPixelbutNotIBL is set to True, IBL will be skipped in the solving.
1315 if (ibl)
1316 {ATH_MSG_INFO( "IBL DoF have been skipped in the solving because AlignPixelbutNotIBL is set to True");
1317 continue;}
1318
1319 //For specific DoF: (*alignParList)[i]->paramType() = 0,1,2,3,4,5,6 for Tx,Ty,Tz,Rx,Ry,Rz,Bx
1320 //Pixel Dofs:
1321 if (m_Remove_Pixel_Tx) //If m_Remove_Pixel_Tx is set to True, Pixel Tx will be skipped in the solving.
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");
1324 continue;}
1325
1326 if (m_Remove_Pixel_Ty) //If m_Remove_Pixel_Ty is set to True, Pixel Ty will be skipped in the solving.
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");
1329 continue;}
1330
1331 if (m_Remove_Pixel_Tz) //If m_Remove_Pixel_Tz is set to True, Pixel Tz will be skipped in the solving.
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");
1334 continue;}
1335
1336 if (m_Remove_Pixel_Rx) //If m_Remove_Pixel_Rx is set to True, Pixel Rx will be skipped in the solving.
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");
1339 continue;}
1340
1341 if (m_Remove_Pixel_Ry) //If m_Remove_Pixel_Ry is set to True, Pixel Ry will be skipped in the solving.
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");
1344 continue;}
1345
1346 if (m_Remove_Pixel_Rz) //If m_Remove_Pixel_Rz is set to True, Pixel Rz will be skipped in the solving.
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");
1349 continue;}
1350
1351 //IBL Dofs:
1352 if (m_Remove_IBL_Tx) //If m_Remove_IBL_Tx is set to True, IBL Tx will be skipped in the solving.
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");
1355 continue;}
1356
1357 if (m_Remove_IBL_Ty) //If m_Remove_IBL_Ty is set to True, IBL Ty will be skipped in the solving.
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");
1360 continue;}
1361
1362 if (m_Remove_IBL_Tz) //If m_Remove_IBL_Tz is set to True, IBL Tz will be skipped in the solving.
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");
1365 continue;}
1366
1367 if (m_Remove_IBL_Rx) //If m_Remove_IBL_Rx is set to True, IBL Rx will be skipped in the solving.
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");
1370 continue;}
1371
1372 if (m_Remove_IBL_Ry) //If m_Remove_IBL_Ry is set to True, IBL Ry will be skipped in the solving.
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");
1375 continue;}
1376
1377 if (m_Remove_IBL_Rz) //If m_Remove_IBL_Rz is set to True, IBL Rz will be skipped in the solving.
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");
1380 continue;}
1381
1382 if(theParameterList[i]->alignModule()->nHits() >= m_minNumHits && theParameterList[i]->alignModule()->nTracks() >= m_minNumTrks)
1383 m_activeIndices.push_back(i);
1384 }
1385 m_aNDoF = m_activeIndices.size();
1386 ATH_MSG_DEBUG("aNDoF/nDoF: "<<m_aNDoF<<"/"<<nDoF);
1387
1388 // --------------------
1389 // now do the SOLVING
1390 // --------------------
1391
1392 int info = 0;
1393
1394 // first Local solving
1395 if (m_runLocal)
1396 info = solveLocal();
1397
1398 // remove spurious modules and resize
1399 if (m_removeSpurious) {
1400
1401 ATH_MSG_INFO("Spurious removal not implemented at the moment.");
1402/* if (StatusCode::SUCCESS != spuriousRemoval()) {
1403 ATH_MSG_ERROR("Problem while trying to remove spurious. Stopping solving");
1404 return -1;
1405 }
1406
1407 // if nDoF=0, bad job...
1408 int NDoF = m_alignModuleTool->nAlignParameters();
1409 if(NDoF==0) {
1410 ATH_MSG_WARNING("Removal removed everything: NDoF=" << NDoF << " !!!");
1411 return 1;
1412 }
1413 ATH_MSG_DEBUG("NDoF: " << NDoF);
1414*/
1415 }
1416
1417 // --------------------
1418 // now Global solving
1419 switch(m_solveOption) {
1420
1421 case NONE:
1422 ATH_MSG_DEBUG("No global solving requested.");
1423 break;
1424
1425 case SOLVE_ROOT:
1426 info = solveROOT();
1427 break;
1428
1429 case SOLVE_CLHEP:
1430 info = solveCLHEP();
1431 break;
1432
1433 case SOLVE:
1434 case DIRECT_SOLVE:
1436 info = solveLapack();
1437 break;
1438
1439 case SOLVE_FAST:
1440 case DIRECT_SOLVE_FAST:
1441 info = solveSparseEigen();
1442 break;
1443
1444 default:
1445 ATH_MSG_INFO("Unknown solving option.");
1446 info = 0;
1447 break;
1448 }
1449
1450 ATH_MSG_INFO("Return value from solving: "<<info);
1451
1452 return info;
1453 }
1454
1455
1456 //_______________________________________________________________________
1460
1461 //_______________________________________________________________________
1465
1466 //________________________________________________________________________
1467 void MatrixTool::addFirstDerivatives(std::list<int,double>& )
1468 {
1469 }
1470
1471 //________________________________________________________________________
1472 void MatrixTool::addSecondDerivatives(std::list<std::pair<int,int>,double >&)
1473 {
1474 }
1475
1476 //________________________________________________________________________
1477 void MatrixTool::addFirstDerivative(int irow, double firstderiv)
1478 {
1479 (*m_bigvector)[irow] += firstderiv;
1480 }
1481
1482 //________________________________________________________________________
1483 void MatrixTool::addSecondDerivative(int irow, int icol, double secondderiv)
1484 {
1485 (*m_bigmatrix)[irow][icol] += secondderiv;
1486 }
1487
1488 //________________________________________________________________________
1489 void MatrixTool::printGlobalSolution(std::ostream & os, const CLHEP::HepSymMatrix * cov)
1490 {
1491 const AlignModuleList * alignModules = m_alignModuleTool->alignModules1D();
1492
1493 AlignModuleList::const_iterator imod = alignModules->begin();
1494 AlignModuleList::const_iterator imod_end = alignModules->end();
1495 for( ; imod!=imod_end; ++imod) {
1496 AlignModule * module = *imod;
1497
1498 DataVector<AlignPar> * alignPars = m_alignModuleTool->getAlignPars(module);
1499 int thisNDoF = alignPars->size();
1500
1501 // fill local covariance matrix
1502 CLHEP::HepSymMatrix * covsub = nullptr;
1503 if(cov && module->nHits() >= m_minNumHits && module->nTracks() >= m_minNumTrks) {
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();
1508
1509 std::vector<int>::iterator itActive = std::find(m_activeIndices.begin(),m_activeIndices.end(),ipar);
1510 if( itActive == m_activeIndices.end() )
1511 continue;
1512 int iActive = std::distance(m_activeIndices.begin(),itActive);
1513
1514 for (int j=0;j<=i;++j) {
1515 int jpar = alignPars->at(j)->index();
1516 double sigma_j = alignPars->at(j)->sigma();
1517
1518 std::vector<int>::iterator jtActive = std::find(m_activeIndices.begin(),m_activeIndices.end(),jpar);
1519 if( jtActive == m_activeIndices.end() )
1520 continue;
1521 int jActive = std::distance(m_activeIndices.begin(),jtActive);
1522
1523 (*covsub)[i][j] = (*cov)[iActive][jActive] * sigma_i * sigma_j;
1524 }
1525 }
1526 }
1527
1528 printModuleSolution(os,module,covsub);
1529
1530 delete covsub;
1531 }
1532 os << "--------------------------------------------------------------------------------" << std::endl;
1533 }
1534
1535 //________________________________________________________________________
1536 void MatrixTool::printGlobalSolution(std::ostream & os, const TMatrixDSym * cov0)
1537 {
1538 CLHEP::HepSymMatrix * cov = nullptr;
1539 if(cov0) {
1540 int nsize = cov0->GetNrows();
1541 cov = new CLHEP::HepSymMatrix(nsize,0);
1542
1543 for(int i=0; i<nsize; i++)
1544 for(int j=0; j<=i; j++)
1545 (*cov)[i][j] = (*cov0)[i][j];
1546 }
1547
1548 printGlobalSolution(os,cov);
1549
1550 delete cov;
1551 }
1552
1573 //________________________________________________________________________
1574 void MatrixTool::printModuleSolution(std::ostream & os, const AlignModule * module, const CLHEP::HepSymMatrix * cov) const
1575 {
1576 os << "--------------------------------------------------------------------------------" << std::endl;
1577 os << "Alignment parameters for module: " << module->name() << std::endl;
1578 os << "Number of tracks passing: " << module->nTracks() << std::endl;
1579 if(m_minNumHits>0 && module->nHits()<m_minNumHits) {
1580 os << "Number of hits too small: "<<module->nHits()<<" < "<<m_minNumHits<<" Skipping the module\n";
1581 return;
1582 }
1583 if(m_minNumTrks>0 && module->nTracks()<m_minNumTrks) {
1584 os << "Number of tracks too small: "<<module->nTracks()<<" < "<<m_minNumTrks<<" Skipping the module\n";
1585 return;
1586 }
1587 os << "Number of hits seen: " << module->nHits() << std::endl;
1588 os << "Number of tracks seen: " << module->nTracks() << std::endl;
1589
1590 DataVector<AlignPar> * alignPars = m_alignModuleTool->getAlignPars(module);
1591 int thisNDoF = alignPars->size();
1592
1593 if(alignPars->empty())
1594 os << "No active parameters" << std::endl;
1595 else
1596 {
1597 // output alignment parameters and errors
1598 DataVector<AlignPar>::const_iterator ipar = alignPars->begin();
1599 DataVector<AlignPar>::const_iterator ipar_end = alignPars->end();
1600 for ( ; ipar != ipar_end; ++ipar) {
1601 const AlignPar * par = *ipar;
1602 os << std::format("{:<10}{:<12.5g} +/- {:<12.5g}\n",
1603 par->dumpType(),
1604 par->par(),
1605 par->err());
1606 }
1607
1608 if(cov) {
1609 // calculate local correlation matrix
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;
1615 }
1616 }
1617 }
1618
1619 //________________________________________________________________________
1621 {
1622 return 0;
1623 }
1624
1625 //________________________________________________________________________
1627 {
1628 ATH_MSG_INFO("solving Global using Lapack");
1629 if(m_logStream) {
1630 *m_logStream<<"*************************************************************\n";
1631 *m_logStream<<"************** solving using Global method ****************\n";
1632 *m_logStream<<"************** using LAPACK ****************\n";
1633 *m_logStream<<"*************************************************************\n";
1634 }
1635
1636 // get rescaled first and second derivatives
1637 AlSymMat* aBetterMat = new AlSymMat(m_aNDoF);
1638 AlVec* aBetterVec = new AlVec(m_aNDoF);
1639 for (int iActive=0;iActive<m_aNDoF;iActive++) {
1640 int i = m_activeIndices[iActive];
1641 (*aBetterVec)[iActive] = (*m_bigvector)[i];
1642 for (int jActive=0;jActive<m_aNDoF;jActive++) {
1643 int j = m_activeIndices[jActive];
1644 (*aBetterMat)[iActive][jActive] = (*m_bigmatrix)[i][j];
1645 }
1646 }
1647
1648 // normalize bigmatrix and bigvector
1649 if(m_scaleMatrix) {
1650 if(m_scale<=0.)
1651 ATH_MSG_WARNING("Scaling requested but scale not set. Not scaling matrix and vector.");
1652 else {
1653 (*aBetterVec) *= 1./m_scale;
1654 (*aBetterMat) *= 1./m_scale;
1655 }
1656 }
1657
1658 ATH_MSG_DEBUG("Now Solving alignment using lapack diagonalization routine dspev...");
1659
1660 if (m_calDet) {
1661 const double tol = 1.e-20;
1662 // compute final determinant
1663 double determ = (*aBetterMat).determinant();
1664 ATH_MSG_INFO("Determinant: " << determ);
1665 if (fabs(determ) < tol)
1666 ATH_MSG_WARNING("Matrix is singular!");
1667 }
1668
1669 // store the original matrix for checks
1670 AlSymMat * d2Chi2 = nullptr;
1672 d2Chi2 = new AlSymMat(*aBetterMat);
1673
1674 clock_t starttime = clock();
1675
1676 // declare transition matrix + vector to store eigenvalues
1678 AlVec w(m_aNDoF); // vector to store the eigenvalues
1679 ATH_MSG_DEBUG("MatrixTool::after z/w allocation");
1680
1681 char jobz = 'V';
1682 int info = (*aBetterMat).diagonalize(jobz,w,z);
1683 ATH_MSG_DEBUG(" info: " << info);
1684 ATH_MSG_INFO("MatrixTool::after diagonalization");
1685
1686 // stop time calculation
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");
1690
1691 double time_solve = 0.;
1692 if (info==0) {
1693 starttime = clock();
1694 postSolvingLapack(aBetterVec,d2Chi2,w,z,m_aNDoF);
1695 stoptime = clock();
1696 time_solve = (stoptime-starttime)/double(CLOCKS_PER_SEC);
1697 ATH_MSG_INFO(" - time spent solving the system: "<<time_solve<<" s");
1698 if(m_logStream) {
1699 *m_logStream<<"time spent for diagonalization: "<<time_diag<<" s\n";
1700 *m_logStream<<"time spent for post-solving: "<<time_solve<<" s\n";
1701 }
1702 }
1703 else {
1704 ATH_MSG_ERROR("Problem in diagonalization. Solving skipped.");
1705 if(m_logStream)
1706 *m_logStream<<"time spent for diagonalization: "<<time_diag<<" s\n";
1707 }
1708
1709 if(m_logStream) {
1710 *m_logStream<<"total time spent in solve: "<<time_diag+time_solve<<" s\n";
1711 *m_logStream<<"\n";
1712 }
1713
1714 delete d2Chi2;
1715 delete aBetterMat;
1716 delete aBetterVec;
1717
1718 // need to do this since success return value from Lapack is 0
1719 // and from solveLapack() it is 1
1720 if (info==0)
1721 info = 1;
1722
1723 return info;
1724 }
1725
1726 //________________________________________________________________________
1728 {
1729
1730 // copied from SiGlobalChi2Algs
1731 ATH_MSG_DEBUG("in spuriousRemoval");
1732
1733 // compute determinant before resizing
1734 if (m_calDet) {
1735 const double tol = 1.e-20;
1736 double determ = m_bigmatrix->determinant();
1737 ATH_MSG_INFO("Determinant: " << determ);
1738 if (std::fabs(determ) < tol)
1739 ATH_MSG_WARNING("Matrix is singular!");
1740 }
1741
1742 // fill vector with modules that need to be removed
1743 int fillvecmods=fillVecMods();
1744 if (fillvecmods==0) {
1745
1746 //ATH_MSG_INFO(" No resize needed (NhitsCut = "
1747 // << m_hitscut << ")");
1748
1749 if (msgLvl(MSG::DEBUG)) {
1750 //m_bigmatrix->Write("bigmatrix.txt", false, m_wSqMatrix, m_scale,
1751 // MatVersion);
1752 //m_bigvector->Write("bigvector.txt", false, m_scale, m_modcodemap,
1753 // VecVersion, m_alignProcessLevel, m_fitParam);
1754 }
1755
1756 return StatusCode::SUCCESS;
1757 }
1758 else if (fillvecmods==2)
1759 return StatusCode::FAILURE;
1760
1761 /* this is a bit difficult to implement for now....
1762
1763 // remove matrix/vector elements
1764 int cont=0;
1765 ModuleIndexMap::iterator itcode;
1766 ATH_MSG_INFO("Eliminating module...");
1767
1768
1769
1770 for (std::vector<int>::const_iterator it=m_dropmods.begin();
1771 it!= m_dropmods.end(); ++it) {
1772
1773 itcode = m_modcodemap.find((*it));
1774
1775 if (itcode == m_modcodemap.end()) {
1776 ATH_MSG_WARNING("Could not find module " << *it << " in map.");
1777 return StatusCode::FAILURE;
1778 }
1779
1780 ATH_MSG_INFO(" - Removing mcode: " << (itcode->second)
1781 << " (old index: " << (*it) << " -> new index: " << (*it)-cont << ")");
1782
1783 m_bigmatrix->RemoveModule((*it)-cont);
1784 m_bigvector->RemoveModule((*it)-cont);
1785 cont++;
1786 }
1787 ATH_MSG_INFO("Modules removed from the Matrix and from the Vector Successfully!");
1788 ATH_MSG_DEBUG("(DoF: " << nDoF << ")");
1789
1790 // resizing...
1791 ATH_MSG_INFO("Resizing the bigvector in memory...");
1792 m_bigvector->reSize(nDoF-6*m_dropmods.size());
1793 ATH_MSG_INFO("Resizing the bigmatrix in memory...");
1794 m_bigmatrix->reSize(nDoF-6*m_dropmods.size());
1795
1796 ATH_MSG_INFO(m_dropmods.size() << " modules eliminated from the matrix, i.e, "
1797 << 6*m_dropmods.size() << " DoFs");
1798 ATH_MSG_INFO(nDoF/6 - m_dropmods.size() << " modules to align (" << nDoF-6*m_dropmods.size() << " DoFs)");
1799 ATH_MSG_INFO("New bigmatrix size is: " << m_bigmatrix->size());
1800 ATH_MSG_INFO("New bigvector size is: " << (*m_bigvector).size());
1801
1802 NDoF = nDoF-6*(m_dropmods.size());
1803
1804 // resize (update) nDoF variable
1805 nDoF = NDoF;
1806
1807 // Resizing vectors to store results
1808 m_alignPar->reSize(nDoF);
1809 m_alignSqErr->reSize(nDoF);
1810
1811 // Fill the mapping module map and updating m_modcodemap
1812 UpdateModMap();
1813 */
1814
1815 return StatusCode::SUCCESS;
1816 }
1817
1818 //________________________________________________________________________
1819 void MatrixTool::postSolvingLapack(AlVec * dChi2, AlSymMat * d2Chi2, AlVec &w, AlMat &z, int size)
1820 {
1821 ATH_MSG_DEBUG("in postSolvinglapack()");
1822
1823 if( z.ncol() != size) {
1824 msg(MSG::ERROR)<<"Eigenvector matrix has incorrect size : "<<z.ncol()<<" != "<<size<<endmsg;
1825 return;
1826 }
1827
1828 if( (int)m_activeIndices.size() != size) {
1829 msg(MSG::ERROR)<<"Number of active parameters is incorrect : "<<m_activeIndices.size()<<" != "<<size<<endmsg;
1830 return;
1831 }
1832
1833 // Compute bigvector in diagonal basis (Vb = Ut * bigvector)
1834 AlVec D(size);
1835 D = z*(*dChi2);
1836
1837 if (m_writeEigenMat) {
1838
1839 ATH_MSG_INFO("writing the eigenvectors in a matrix: "<< z.nrow() << "x" << z.ncol());
1840
1841 // Set Path for the z matrix (eigenvector matrix)
1842 z.SetPathBin(m_pathbin.value()+m_prefixName.value());
1843 z.SetPathTxt(m_pathtxt.value()+m_prefixName.value());
1844
1845 ATH_MSG_INFO("writing the eigenvector matrix: "<< m_scalaMatName);
1846 ATH_MSG_DEBUG("matrix will be in: "<< m_pathbin.value()+m_prefixName.value()+m_scalaMatName.value());
1847
1848 StatusCode sc = z.Write(m_scalaMatName, true); // write the eigenvector matrix
1849
1850 if (sc!=StatusCode::SUCCESS)
1851 msg(MSG::ERROR)<<"Problem writing eigenvector matrix"<<endmsg;
1852
1853 // Set Path for the w matrix (eigenvalues matrix - diagonal bigmatrix)
1854 w.SetPathBin(m_pathbin.value()+m_prefixName.value());
1855 w.SetPathTxt(m_pathtxt.value()+m_prefixName.value());
1856
1857 ATH_MSG_INFO("writing the eigenvectors in a vector: "<< w.size());
1858 ATH_MSG_INFO("writing the eigenvalues vector (diagonal bigmatrix): "<< m_scalaVecName);
1859 ATH_MSG_DEBUG("vector will be in: "<< m_pathbin.value()+m_prefixName.value()+m_scalaVecName.value());
1860
1861 sc = w.WriteEigenvalueVec(m_scalaVecName, true); // write the eigenvalues vecor
1862
1863 if (sc!=StatusCode::SUCCESS)
1864 msg(MSG::ERROR)<<"Problem writing eigenvector matrix"<<endmsg;
1865
1866 if (m_writeEigenMatTxt) {
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;
1873 }
1874
1875 }
1876
1877 // Set eigenvalue thresholds
1878 const double eigenvalue_threshold = 1e-19;
1879
1880 // weak mode removal
1881 if (m_modcut == -1) {
1882
1883 ATH_MSG_INFO(" Starting the automatic Weak Mode Removal method");
1884
1885 // create a pull vector for the alignment corrections in diagonal basis (db_pulls)
1886 //int nDoF=m_alignModuleTool->nAlignParameters();
1887 AlVec* Align_db = new AlVec(size);
1888 AlVec* Align_error_db = new AlVec(size);
1889 AlVec* AlignPull = new AlVec(size);
1890 ATH_MSG_DEBUG("AlignPull vector size is: "<< (*AlignPull).size());
1891
1892 m_modcut = 0;
1893 bool wm_stop = false;
1894
1895 // -----------------------------------------------------------------------
1896 // First pass: removing weak modes because of large pull
1897 // compute alignment pulls for corrections in diagonal basis (db)
1898 for(int i=0; i<size; i++) {
1899
1900 (*Align_db)[i] = (-D[i]/w[i]);
1901 if(m_scale<=0.)[[unlikely]]{
1902 ATH_MSG_WARNING("postSolvingLapack: Scaling requested but scale not set. Not scaling matrix and vector.");
1903 } else {
1904 (*Align_error_db)[i] = sqrt(1.0/w[i]/m_scale);
1905 }
1906
1907 if (w[i]<eigenvalue_threshold) {
1908 ATH_MSG_INFO(" + EigenMode " << i
1909 << " removed as eigenvalue lower than the threshold " << eigenvalue_threshold
1910 << ": " << w[i]);
1911 (*AlignPull)[i] = 0.0;
1912 ++m_modcut;
1913 }
1914 else
1915 (*AlignPull)[i] = (*Align_db)[i] / (*Align_error_db)[i];
1916
1917 ATH_MSG_DEBUG(i << ". AlignPar: " << (*Align_db)[i] << " +- " << (*Align_error_db)[i]
1918 << " (pull: " << (*AlignPull)[i] << ") ; w[i]: " << w[i]);
1919 }
1920 ATH_MSG_INFO(" +++ Weak Mode removal ++ stop after mode "<< m_modcut << " (First pass)");
1921 // -----------------------------------------------------------------------
1922
1923 // -----------------------------------------------------------------------
1924 // Second pass
1925 // if the error is greater than the correction -> cut this mode
1926 for(int i=m_modcut; (i<size && !wm_stop); i++) {
1927
1928 // if the error is greater than the correction -> cut this mode
1929 if (fabs((*AlignPull)[i])<m_pullcut) {
1930 ATH_MSG_INFO(" + EigenMode " << i
1931 << " removed as pull is lower than " << m_pullcut << ": "
1932 << (*AlignPull)[i]);
1933 ++m_modcut;
1934 }
1935 else
1936 wm_stop = true;
1937
1938 }
1939 ATH_MSG_INFO(" +++ Weak Mode removal ++ stop after mode "<< m_modcut << " (Second pass)");
1940 // -----------------------------------------------------------------------
1941
1942 wm_stop = false;
1943
1944 // ----------------------------------------------------------------------
1945 // Third pass
1946 // Check if the next eigenvalues is far away. If it is two orders of
1947 // magnitude bigger remove also this mode and allow the search
1948 for(int i=m_modcut; (i<size && !wm_stop); i++) {
1949
1950 // if the next eigenvalues is far away -> cut this mode
1951 if (m_eigenvalueStep*w[i]<w[i+1]) {
1952 ATH_MSG_INFO(" + EigenMode " << i
1953 << " removed as diff between eigenvalues, " << w[i] << " and " << w[i+1]
1954 << ", is greater than " << m_eigenvalueStep);
1955 ++m_modcut;
1956 }
1957 else
1958 wm_stop = true;
1959
1960 }
1961 ATH_MSG_INFO(" +++ Weak Mode removal ++ stop after mode "<< m_modcut << " (Third pass)");
1962 // -----------------------------------------------------------------------
1963
1964 wm_stop = false;
1965
1966 // -----------------------------------------------------------------------
1967 // Fourth pass
1968 // Check if the next eigenvalues is far away. If it is two orders of
1969 // magnitude bigger remove also this mode and allow the search
1970 for(int i=m_modcut; (i<size && !wm_stop); i++) {
1971
1972 // if the next eigenvalues is far away -> cut this mode
1973 if ( fabs((*Align_db)[i]) > m_Align_db_step*fabs((*Align_db)[i+1]) ) {
1974 ATH_MSG_INFO(" + EigenMode " << i
1975 << " removed as diff between corrections, " << w[i] << " and " << w[i+1]
1976 << ", is greater than "
1977 << m_Align_db_step);
1978 ++m_modcut;
1979 }
1980 else
1981 wm_stop = true;
1982
1983 }
1984 ATH_MSG_INFO(" +++ Weak Mode removal ++ stop after mode "<< m_modcut << " (Fourth pass)");
1985 // -----------------------------------------------------------------------------------------------------
1986
1987 // Free memory and clear the pointer to
1988 // prevent using invalid memory reference
1989 delete Align_db;
1990 delete Align_error_db;
1991 delete AlignPull;
1992 Align_db = nullptr;
1993 Align_error_db = nullptr;
1994 AlignPull = nullptr;
1995
1996 } // end of if(m_modcut == -1)
1997
1998 // Save some stuff to debug purposes
1999 /*
2000 if (m_storeDia) {
2001 std::string path = m_pathtxt+m_prefixName+"align_dia";
2002 std::fstream orthogon(path.c_str(), std::ios::out);
2003 orthogon.setf(std::ios::fixed);
2004 orthogon.setf(std::ios::showpoint);
2005 orthogon.precision(6);
2006
2007 orthogon << std::setw(10)
2008 << "--------------------------------------------------------------------------------"
2009 << std::endl;
2010 orthogon << std::setw(10) << " ModeCut = " << m_modcut << std::endl;
2011 orthogon << std::setw(10)
2012 << "--------------------------------------------------------------------------------"
2013 << std::endl;
2014
2015 orthogon << std::setw(10) << "mode"
2016 << std::setw(20) << "eigenmode"
2017 << std::setw(20) << "eigenmode error"
2018 << std::setw(25) << "eigenvalue"
2019 << std::endl;
2020
2021 for( int m=0; m<size; m++) {
2022
2023 // mode
2024 orthogon << std::setw(10) << m;
2025
2026 // eigenmode (db)
2027 if( w[m]>1.0e-15) orthogon << std::setw(20) << -D[m]/w[m];
2028 else orthogon << std::setw(20) << 0.0;
2029
2030 // error eigenmode (error_db)
2031 if( w[m]>1.0e-15) orthogon << std::setw(20) << sqrt(1.0/w[m]/m_scale);
2032 else orthogon << std::setw(20) << 0.0;
2033
2034 // eigenvalues
2035 orthogon << std::setw(25) << w[m] << std::endl;
2036 }
2037 orthogon.close();
2038 } // end store align_dia.txt
2039 */
2040
2041 AlVec delta(size);
2042 AlVec deltafull(size);
2043 AlVec errSq(size);
2044
2045 // full covariance matrix
2046 CLHEP::HepSymMatrix * cov = nullptr;
2048 // Warning ! The matrix can be huge!
2049 // This can lead to memory problems
2050 cov = new CLHEP::HepSymMatrix(size,0);
2051
2052 if(m_logStream)
2053 *m_logStream<<"/------ The Eigenvalue Spectrum -------\n";
2054
2055 for (int i=0;i<size;i++) {
2056 AlVec thisdelta(size);
2057 for(int j=0;j<size;j++)
2058 thisdelta[j] = z[i][j] * (-D[i]/w[i]);
2059 deltafull += thisdelta;
2060
2061 ATH_MSG_DEBUG("eigenvalue "<<w[i]);
2062 if( i<m_modcut ) {
2063 ATH_MSG_INFO("skipping eigenvalue "<<w[i]<<" , modcut is "<<m_modcut);
2064 if(m_logStream)
2065 *m_logStream<<"| skipping eigenvalue "<<w[i]<<"\n";
2066 }
2067 else if( w[i] < m_eigenvaluethreshold ) {
2068 ATH_MSG_INFO("skipping eigenvalue "<<w[i]<<" , cut is "<<m_eigenvaluethreshold);
2069 if(m_logStream)
2070 *m_logStream<<"| skipping eigenvalue "<<w[i]<<"\n";
2071 }
2072 else {
2073 if(m_logStream)
2074 *m_logStream<<"| "<<w[i]<<"\n";
2075
2076 delta += thisdelta;
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];
2082 }
2083 }
2084 }
2085 }
2086
2087 if(m_logStream)
2088 *m_logStream<<"\\----- End of Eigenvalue Spectrum -----\n";
2089
2090 ATH_MSG_DEBUG("Alignment constants:");
2091
2092 DataVector<AlignPar> * alignParList = m_alignModuleTool->alignParList1D();
2093
2094 // compute alignment corrections (translations in mm and rotations in rad) and their variances
2095 for(int i=0; i<size; i++) {
2096
2097 double param = delta[i];
2098 double err = sqrt(2.*std::fabs(errSq[i]));
2099
2100 int idof = m_activeIndices[i];
2101 AlignPar * alignPar=(*alignParList)[idof];
2102
2103 // undo the sigma scaling
2104 double sigma = alignPar->sigma();
2105
2106 param *= sigma;
2107 err *= sigma;
2108
2109 // undo normalization scaling of error
2110 if(m_scaleMatrix && m_scale>0.)
2111 err /= sqrt(m_scale);
2112
2113 ATH_MSG_DEBUG(i <<" : "<< param << " +/- "<< err);
2114 ATH_MSG_DEBUG("cov("<<i<<")="<<errSq[i]<<", sigma: "<<sigma);
2115 ATH_MSG_DEBUG("init par: "<<alignPar->initPar());
2116 alignPar->setPar(param, err);
2117 ATH_MSG_DEBUG("set param to "<<param<<" for alignPar "<<alignPar);
2118 ATH_MSG_DEBUG(*(*alignParList)[idof]);
2119 }
2120
2121 if(m_logStream) {
2123
2124 // norm of first derivative
2125 double norm1st = dChi2->norm();
2126 if(m_scaleMatrix && m_scale>0.) // undo normalization scaling
2127 norm1st *= m_scale;
2128 *m_logStream<<"norm of first derivative : "<<norm1st<<"\n";
2129
2130 if(d2Chi2) {
2131 // distance to solution
2132 double dist = ( (*d2Chi2) * deltafull + (*dChi2) ).norm();
2133 if(m_scaleMatrix && m_scale>0.) // undo normalization scaling
2134 dist *= m_scale;
2135 *m_logStream<<"distance to solution : "<<dist<<"\n";
2136
2137 // calculate chi2 of the alignment change
2138 double chi2 = delta * (*d2Chi2) * delta * .5;
2139 if(m_scaleMatrix && m_scale>0.) // undo normalization scaling
2140 chi2 *= m_scale;
2141 *m_logStream<<"delta(chi2) of the alignment change : "<<chi2<<" / "<<size<<"\n";
2142 }
2143 }
2144
2145 delete cov;
2146 }
2147
2148 //________________________________________________________________________
2150 {
2151 ATH_MSG_INFO("solving Global using SparseEigen");
2152 if(m_logStream) {
2153 *m_logStream<<"*************************************************************\n";
2154 *m_logStream<<"************** solving using Global method ****************\n";
2155 *m_logStream<<"************** using SparseEigen ****************\n";
2156 *m_logStream<<"*************************************************************\n";
2157 }
2158
2159 // start measuring time
2160 clock_t starttime = clock();
2161
2162 DataVector<AlignPar> * alignParList = m_alignModuleTool->alignParList1D();
2163
2164 AlSpaMat * ABetterMat = nullptr;
2165 bool isCopy = false;
2166 if ( dynamic_cast<AlSymMat*>(m_bigmatrix) ) {
2167 ATH_MSG_INFO("Converting Matrix Format for fast solving");
2168 ABetterMat = new AlSpaMat(*(dynamic_cast<AlSymMat*>(m_bigmatrix)));
2169 isCopy = true;
2170 }
2171 else if ( dynamic_cast<AlSpaMat*>(m_bigmatrix) ) {
2172 ATH_MSG_INFO("Matrix format native to the fast solving");
2173 ABetterMat = (dynamic_cast<AlSpaMat*>(m_bigmatrix));
2174 }
2175 else {
2176 ATH_MSG_ERROR("Cannot cast to neither AlSymMat nor AlSpaMat");
2177 return 0;
2178 }
2179
2180 ATH_MSG_DEBUG("checking active indices");
2181
2182 // use const matrix when checking for non-zero elements to avoid
2183 // filling of the whole matrix
2184 const AlSpaMat * chkMatrix = ABetterMat;
2185
2186 AlSpaMat * aBetterMat = new AlSpaMat(m_aNDoF);
2187 AlVec * aBetterVec = new AlVec(m_aNDoF);
2188
2189
2190 for (int iActive=0;iActive<m_aNDoF;iActive++) {
2191 int i = m_activeIndices[iActive];
2192 (*aBetterVec)[iActive] = (*m_bigvector)[i];
2193 for (int jActive=0;jActive<m_aNDoF;jActive++) {
2194 int j = m_activeIndices[jActive];
2195 // only fill if non-zero !!!
2196 if ( (*chkMatrix)[iActive][jActive] != 0. )
2197 (*aBetterMat)[iActive][jActive]=(*ABetterMat)[i][j];
2198 }
2199 }
2200
2201 // store original vector for cross-checks
2202 AlVec origVec(*aBetterVec);
2203
2204 ATH_MSG_DEBUG("running the solving");
2205
2206 // solve
2207 int info = (*aBetterMat).SolveWithEigen(*aBetterVec);
2208
2209 if(info == 0) {
2210 ATH_MSG_INFO("SolveWithEigen solving OK");
2211 if(m_logStream)
2212 *m_logStream<<"SolveWithEigen solving OK.\n";
2213 }
2214 else {
2215 ATH_MSG_ERROR( "SolveWithEigen error code (0 if OK) = "<<info );
2216 if(m_logStream)
2217 *m_logStream<<"SolveWithEigen error code (0 if OK) = "<<info<<"\n";
2218 }
2219
2220 if( isCopy )
2221 delete ABetterMat;
2222 ABetterMat = nullptr;
2223
2224 // stop measuring time
2225 clock_t stoptime = clock();
2226 double totaltime = (stoptime-starttime)/double(CLOCKS_PER_SEC);
2227 ATH_MSG_INFO("Time spent in SolveWithEigen: "<<totaltime<<" s");
2228
2229 ATH_MSG_DEBUG("Alignment constants:");
2230 // compute alignment corrections (translations in mm and rotations in rad)
2231 // for solveSparseEigen variances are not calculated
2232 for(int i=0; i<m_aNDoF; i++) {
2233
2234 double param = -(*aBetterVec)[i];
2235 double err = 0.;
2236
2237 int idof = m_activeIndices[i];
2238 AlignPar * alignPar=(*alignParList)[idof];
2239
2240 // undo the sigma scaling
2241 double sigma = alignPar->sigma();
2242 param *= sigma;
2243
2244 ATH_MSG_DEBUG(i <<" : "<< param << " +/- "<< err);
2245 ATH_MSG_DEBUG("sigma: "<<sigma);
2246 ATH_MSG_DEBUG("init par: "<<alignPar->initPar());
2247 alignPar->setPar(param, err);
2248 ATH_MSG_DEBUG("set param to "<<param<<" for alignPar "<<alignPar);
2249 ATH_MSG_DEBUG(*(*alignParList)[idof]);
2250 }
2251
2252 if(m_logStream) {
2253 CLHEP::HepSymMatrix * cov = nullptr;
2255
2256 // norm of first derivative
2257 *m_logStream<<"norm of first derivative : "<<origVec.norm()<<"\n";
2258
2259 // distance to solution
2260 double dist = ( (*aBetterMat) * (*aBetterVec) - origVec ).norm();
2261 *m_logStream<<"distance to solution : "<<dist<<"\n";
2262
2263 // calculate chi2 of the alignment change
2264 double chi2 = (*aBetterVec) * (*aBetterMat) * (*aBetterVec) * .5;
2265 *m_logStream<<"delta(chi2) of the alignment change : "<<chi2<<" / "<<m_aNDoF<<"\n";
2266
2267 // time spent here
2268 *m_logStream<<"time spent in solve : "<<totaltime<<" s\n";
2269 }
2270
2271 delete aBetterMat;
2272 delete aBetterVec;
2273
2274 // need to do this since success return value from Lapack is 0
2275 // and from SolveWithEigen() it is 1
2276 if (info==0)
2277 info = 1;
2278
2279 return info;
2280 }
2281
2282 //________________________________________________________________________
2284 {
2285 ATH_MSG_INFO("writing the hitmap to file");
2286
2287 const AlignModuleList * moduleList = m_alignModuleTool->alignModules1D();
2288 int nModules = moduleList->size();
2289
2290 AlMat hitmap(nModules,2);
2291 AlignModuleList::const_iterator imod = moduleList->begin();
2292 AlignModuleList::const_iterator imod_end = moduleList->end();
2293 int index(0);
2294 for(; imod != imod_end; ++imod) {
2295 AlignModule * module = *imod;
2296 hitmap[index][0] = module->nHits();
2297 hitmap[index][1] = module->nTracks();
2298 index++;
2299 }
2300
2301 // Set Path for the hitmap matrix
2302 hitmap.SetPathBin(m_pathbin.value()+m_prefixName.value());
2303 hitmap.SetPathTxt(m_pathtxt.value()+m_prefixName.value());
2304
2305 StatusCode sc = hitmap.Write("hitmap.bin",true); // write the hitmap matrix
2306
2307 if (sc!=StatusCode::SUCCESS)
2308 ATH_MSG_ERROR("Problem writing hitmap matrix");
2309
2310 if (m_writeHitmapTxt) {
2311 sc = hitmap.Write("hitmap.txt", false, 0);
2312 if (sc!=StatusCode::SUCCESS)
2313 ATH_MSG_ERROR("Problem writing hitmap matrix to text file");
2314 }
2315
2316 ATH_MSG_DEBUG("hitmap written to: "<< m_pathbin.value()+m_prefixName.value() <<"hitmap.bin (.txt)");
2317 }
2318
2319 //________________________________________________________________________
2321 {
2322 ATH_MSG_INFO("read hitmaps from files");
2323
2324 const AlignModuleList * moduleList = m_alignModuleTool->alignModules1D();
2325 int nModules = moduleList->size();
2326
2327 AlMat hitmap(nModules,2);
2328 int nFiles = (int)m_inputHitmapFiles.size();
2329 for(int imap=0;imap<nFiles; imap++) {
2330 AlMat nextmap(nModules,2);
2331
2332 ATH_MSG_INFO("Reading hitmap "<<imap<<" from file "<<m_inputHitmapFiles[imap]);
2333
2334 if(nextmap.ReadScalaPack(m_inputHitmapFiles[imap]).isFailure()) {
2335 ATH_MSG_WARNING("Problem reading hitmap from \'"<<m_inputHitmapFiles[imap]<<"\'. Skipping.");
2336 continue;
2337 }
2338
2339 if(nextmap.nrow()!=nModules || nextmap.ncol()!=2) {
2340 ATH_MSG_WARNING("Matrix in file \'"<<m_inputHitmapFiles[imap]<<"\' has wrong size ("
2341 <<nextmap.nrow()<<" x "<<nextmap.ncol()<<"), should be ("<<nModules<<" x 2). Skipping.");
2342 continue;
2343 }
2344
2345 hitmap += nextmap;
2346 }
2347
2348 AlignModuleList::const_iterator imod = moduleList->begin();
2349 AlignModuleList::const_iterator imod_end = moduleList->end();
2350 int index = 0;
2351 int totalhits = 0;
2352 for(; imod != imod_end; ++imod) {
2353 AlignModule * module = *imod;
2354 //if ((int)hitmap[index][0]!=(int)module->identify().get_identifier32().get_compact()) ATH_MSG_ERROR("bad module identifier");
2355 //module->setIdentifier((Identifier)hitmap[index][0]);
2356 module->setNHits((int)hitmap[index][0]);
2357 module->setNTracks((int)hitmap[index][1]);
2358 totalhits += (int)hitmap[index][0];
2359 index++;
2360 }
2361
2362 m_nHits = totalhits;
2363 m_nTracks = 0;
2364 m_nMeasurements = 0;
2365
2366 ATH_MSG_INFO("Hitmap accumulated from "<<nFiles<<" files with total of "<<totalhits<<" hits.");
2367 }
2368
2369} // end of namespace
2370
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:734
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:310
double norm() const
Definition AlVec.cxx:213
StatusCode ReadPartial(const std::string &, double &, std::map< int, unsigned long long > &, float &)
Definition AlVec.cxx:491
void SetPathTxt(const std::string &)
Definition AlVec.cxx:316
int size() const
Definition AlVec.h:109
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)