40#include "GaudiKernel/DataObject.h"
41#include "GaudiKernel/IDataProviderSvc.h"
42#include "GaudiKernel/ISvcLocator.h"
43#include "GaudiKernel/MsgStream.h"
44#include "GaudiKernel/PropertyMgr.h"
45#include "GaudiKernel/SmartDataPtr.h"
47#include "CLHEP/Vector/ThreeVector.h"
50using CLHEP::Hep3Vector;
53#include "GaudiKernel/MsgStream.h"
66 : Algorithm( name, pSvcLocator )
68 , m_convCrit( 0.000001 )
69 , m_askForMatrixInversion( true )
70 , m_fitPolynom( true )
72 m_writeToFile( false )
73 , m_readDataFromDB( false )
74 , m_equationSolver(
"GMR" )
76 , m_fileDir(
"/home/besdata/public/liucx/Calib/" )
78 , m_nrXtalsEnoughHits( 0 )
79 , m_runNumberFile(
"runnumbers.dat" )
86 declareProperty(
"equationSolver", m_equationSolver );
87 declareProperty(
"dirHitsCut", m_dirHitsCut );
88 declareProperty(
"writeToFile", m_writeToFile );
89 declareProperty(
"fileExt", m_fileExt );
90 declareProperty(
"fileDir", m_fileDir );
91 declareProperty(
"readDataFromDB", m_readDataFromDB );
92 declareProperty(
"askForMatrixInversion", m_askForMatrixInversion );
93 declareProperty(
"fitPolynom", m_fitPolynom );
94 declareProperty(
"convCrit", m_convCrit );
95 declareProperty(
"runNumberFile", m_runNumberFile );
96 declareProperty(
"MsgFlag", m_MsgFlag );
98 m_calibConst =
new double[6240];
99 m_calibConstUnred =
new double[6240];
100 m_absoluteConstants =
new double[6240];
101 m_oldConstants =
new double[6240];
111 if ( 0 != m_calibConst )
113 delete[] m_calibConst;
116 if ( 0 != m_calibConstUnred )
118 delete[] m_calibConstUnred;
119 m_calibConstUnred = 0;
121 if ( 0 != m_absoluteConstants )
123 delete[] m_absoluteConstants;
124 m_absoluteConstants = 0;
126 if ( 0 != m_oldConstants )
128 delete[] m_oldConstants;
131 if ( 0 != m_myCalibData )
133 delete m_myCalibData;
141 MsgStream log(
msgSvc(), name() );
142 log << MSG::INFO <<
"in initialize()" << endmsg;
146 m_calibrationSuccessful =
false;
150 NTuplePtr nt1(
ntupleSvc(),
"FILE302/n1" );
151 if ( nt1 ) m_tuple1 = nt1;
154 m_tuple1 =
ntupleSvc()->book(
"FILE302/n1", CLID_ColumnWiseTuple,
"Calib" );
158 status1 = m_tuple1->addItem(
"ixtal", ixtal );
159 status1 = m_tuple1->addItem(
"gi0", gi0 );
160 status1 = m_tuple1->addItem(
"calibConst", calibConst );
161 status1 = m_tuple1->addItem(
"err", err );
162 status1 = m_tuple1->addItem(
"nhitxtal", nhitxtal );
166 log << MSG::ERROR <<
"Cannot book N-tuple:" << long( m_tuple1 ) << endmsg;
167 return StatusCode::FAILURE;
173 scCalib = Gaudi::svcLocator()->service(
"EmcCalibConstSvc", m_emcCalibConstSvc );
174 if ( scCalib != StatusCode::SUCCESS )
175 { log << MSG::ERROR <<
"can not use EmcCalibConstSvc" << endmsg; }
178 std::cout <<
"Test EmcCalibConstSvc DigiCalibConst(0)= "
179 << m_emcCalibConstSvc->getDigiCalibConst( 0 ) << std::endl;
189 return StatusCode::SUCCESS;
195 MsgStream log(
msgSvc(), name() );
196 log << MSG::DEBUG <<
"in execute()" << endmsg;
198 if ( m_readDataFromDB )
200 m_calibrationSuccessful = readInFromDB();
202 log << MSG::INFO <<
"read in accumulated matrix from DB" << endmsg;
206 m_calibrationSuccessful = readInFromFile();
208 log << MSG::INFO <<
"read in accumulated matrix from file" << endmsg;
211 if ( m_calibrationSuccessful ==
true )
215 if ( m_askForMatrixInversion ==
true )
218 m_calibrationSuccessful =
false;
219 log << MSG::INFO <<
" Well, we have " << m_nrXtalsEnoughHits <<
" crystals whith more "
220 <<
"than " << m_dirHitsCut <<
" direct hits. Do you want do "
221 <<
"a matrix inversion ? [N]" << endmsg;
223 m_calibrationSuccessful =
true;
226 if ( m_calibrationSuccessful ==
true )
230 if ( m_writeToFile ==
true ) { writeOut(); }
232 m_myCalibData->printVec( 2 );
235 if ( m_calibrationSuccessful = m_myCalibData->reduce() )
238 cout <<
"m_calibrationSuccessful=" << m_calibrationSuccessful << endl;
240 if ( m_myCalibData->nXtalsHit() != m_myCalibData->nXtals() )
243 <<
" Reduced number of Xtals for calibration: " << m_myCalibData->nXtalsHit()
246 cout <<
"m_myCalibData->nXtalsHit()=" << m_myCalibData->nXtalsHit()
247 <<
"m_myCalibData->nXtals()=" << m_myCalibData->nXtals() << endl;
248 m_myCalibData->printVec( 10 );
251 if ( m_calibrationSuccessful = solveEqua() )
254 for (
int i = 0; i < m_myCalibData->nXtalsHit(); i++ )
257 m_calibConstUnred[m_myCalibData->xtalInd( i )] = m_calibConst[i];
269 if ( m_writeToFile ==
true ) { writeOutConst(); }
276 log << MSG::WARNING <<
" Reduction of the Emc Bhabha calibration matrix FAILED !"
278 <<
" Will NOT perform Emc Bhabha calibration !" << endmsg;
279 return ( StatusCode::FAILURE );
285 log << MSG::WARNING <<
" ERROR in reading in Emc Bhabha calibration data !" << endl
286 <<
" Will NOT perform Emc Bhabha calibration !" << endmsg;
287 return ( StatusCode::FAILURE );
290 return StatusCode::SUCCESS;
296 MsgStream log(
msgSvc(), name() );
298 log << MSG::INFO <<
"in endRun()" << endmsg;
300 return StatusCode::SUCCESS;
305 MsgStream log(
msgSvc(), name() );
307 log << MSG::INFO <<
"Performs the Chi square fit of the accumulated " << endmsg;
311void EmcBhaCalib::initCalibConst() {
313 MsgStream log(
msgSvc(), name() );
315 for (
int i = 0; i < m_myCalibData->
nXtals(); i++ ) { m_calibConst[i] = 1.; }
317 ifstream inConst(
"EmcCalib.Const" );
320 log << MSG::VERBOSE <<
" No starting values for calibration constants found ! "
321 <<
"(EmcCalib.Const)" << endl
322 <<
"Set them to 1.0 ! " << endmsg;
326 log << MSG::VERBOSE <<
" Read in starting values of calibration constants !" << endmsg;
330 log << MSG::VERBOSE <<
" Have starting values for " << nConst <<
" Xtals !" << endl
331 <<
"Set the others to 1.0 ! " << endmsg;
334 for (
int i = 0; i < nConst; i++ ) { inConst >> numberXtal >> m_calibConst[numberXtal]; }
339 nConstEmc = m_emcCalibConstSvc->getDigiCalibConstNo();
341 if ( nConstEmc != 6240 ) cout <<
"number of calibconst=" << nConstEmc << endl;
347 for (
int i = 0; i < nConstEmc; i++ )
353 m_calibConst[i] = m_emcCalibConstSvc->getDigiCalibConst( i );
355 m_oldConstants[i] = m_emcCalibConstSvc->getDigiCalibConst( i );
359 m_absoluteConstants[i] = 1.0;
361 m_calibConstUnred[i] = 1.0;
366bool EmcBhaCalib::solveEqua() {
368 MsgStream log(
msgSvc(), name() );
372 log << MSG::VERBOSE <<
" Solve Matrix equation with method " << m_equationSolver << endl
373 <<
"Xtals hit: " << m_myCalibData->nXtalsHit() << endl
374 <<
"Nr of non Zeros: " << m_nrNonZeros << endmsg;
380 double convCriterion = m_convCrit;
381 long int maxIter = 1000;
382 long int errUnit = 6;
386 long int lengthDoubleWork;
387 double* doubleWork = 0;
388 long int lengthIntWork;
389 long int* intWork = 0;
393 double errorv = 1000;
394 long int errorFlag = 9999;
399 if ( m_equationSolver ==
"GMR" )
402 cout << m_equationSolver << endl;
404 cout <<
"errorFlag=" << errorFlag << endl;
408 ( 1 + m_myCalibData->nXtals() * ( nsave + 7 ) + nsave * ( nsave + 3 ) ) + 50000;
409 doubleWork =
new double[lengthDoubleWork];
411 intWork =
new long int[lengthIntWork];
413 dsdgmr_( &( m_myCalibData->nXtalsHit() ), m_myCalibData->getVectorR(), m_calibConst,
414 &m_nrNonZeros, m_myCalibData->getMatrixM()->row(),
415 m_myCalibData->getMatrixM()->column(), m_myCalibData->getMatrixM()->matrix(),
416 &isym, &nsave, &itol, &convCriterion, &maxIter, &iters, &errorv, &errorFlag,
417 &errUnit, doubleWork, &lengthDoubleWork, intWork, &lengthIntWork );
418 cout <<
"errorFlag=" << errorFlag << endl;
420 log << MSG::VERBOSE <<
" Error flag: " << errorFlag << endmsg;
421 if ( errorFlag < 0 ) errorFlag = labs( errorFlag ) + 2;
424 case 0: log << MSG::VERBOSE <<
" all went well" << endmsg;
break;
426 log << MSG::ERROR <<
" insufficient storage allocated for _doubleWork or _intWork"
430 log << MSG::ERROR <<
" method failed to reduce norm of current residual" << endmsg;
432 case 3: log << MSG::ERROR <<
" insufficient length for _doubleWork" << endmsg;
break;
433 case 4: log << MSG::ERROR <<
" inconsistent _itol and values" << endmsg;
break;
434 default: log << MSG::ERROR <<
" unknown flag" << endmsg;
436 log << MSG::VERBOSE <<
" Integer workspace used = " << intWork[8] << endl
437 <<
" Double workspace used = " << intWork[9] << endmsg;
443 if ( m_equationSolver ==
"PCG" )
446 cout << m_equationSolver << endl;
451 lengthDoubleWork = 5 * m_myCalibData->nXtals() + 50000;
452 doubleWork =
new double[lengthDoubleWork];
454 intWork =
new long int[lengthIntWork];
456 dsdcg_( &( m_myCalibData->nXtalsHit() ), m_myCalibData->getVectorR(), m_calibConst,
457 &m_nrNonZeros, m_myCalibData->getMatrixM()->row(),
458 m_myCalibData->getMatrixM()->column(), m_myCalibData->getMatrixM()->matrix(),
459 &isym, &itol, &convCriterion, &maxIter, &iters, &errorv, &errorFlag, &errUnit,
460 doubleWork, &lengthDoubleWork, intWork, &lengthIntWork );
464 case 0: log << MSG::VERBOSE <<
"all went well" << endmsg;
break;
466 log << MSG::ERROR <<
" insufficient storage allocated for WORK or IWORK" << endmsg;
469 log << MSG::ERROR <<
" method failed to to converge in maxIter steps." << endmsg;
472 log << MSG::ERROR <<
" Error in user input. Check input value of _nXtal,_itol."
476 log << MSG::ERROR <<
" User error tolerance set too tight. "
477 <<
"Reset to 500.0*D1MACH(3). Iteration proceeded." << endmsg;
480 log << MSG::ERROR <<
" Preconditioning matrix, M, is not Positive Definite. " << endmsg;
482 case 6: log << MSG::ERROR <<
" Matrix A is not Positive Definite." << endmsg;
break;
483 default: log << MSG::ERROR <<
" unknown flag" << endmsg;
485 log << MSG::VERBOSE <<
" Integer workspace used = " << intWork[9] << endl
486 <<
"Double workspace used = " << intWork[10] << endmsg;
489 log << MSG::VERBOSE <<
"------ Calibration fit statistics ------- " << endl
490 <<
"maximum number of iterations =" << maxIter << endl
491 <<
" number of iterations =" << iters << endl
492 <<
"error estimate of error in final solution =" << errorv << endmsg;
494 if ( 0 != doubleWork )
delete[] doubleWork;
495 if ( 0 != intWork )
delete[] intWork;
497 if ( errorFlag != 0 )
return false;
504void EmcBhaCalib::writeOut() {
507 std::string vectorFile = m_fileDir;
508 vectorFile += m_fileExt;
509 vectorFile +=
"allCalibVector.dat";
510 vectorOut.open( vectorFile.c_str() );
513 std::string matrixFile = m_fileDir;
514 matrixFile += m_fileExt;
515 matrixFile +=
"allCalibMatrix.dat";
516 matrixOut.open( matrixFile.c_str() );
518 MsgStream log(
msgSvc(), name() );
520 log << MSG::VERBOSE <<
" Write out files " << vectorFile <<
" " << matrixFile << endmsg;
522 m_myCalibData->writeOut( matrixOut, vectorOut );
529void EmcBhaCalib::writeOutConst() {
533 std::string constFile = m_fileDir;
534 constFile += m_fileExt;
535 constFile +=
"CalibConst.dat";
537 constOut.open( constFile.c_str() );
539 constOut <<
"#crystalIndex relative-constant absolute-constant" << endl;
544 for (
int i = 0; i < m_myCalibData->nXtalsHit(); i++ )
547 chanIndex = m_myCalibData->xtalInd( i );
551 if ( m_myCalibData->xtalHitsDir( i ) < m_dirHitsCut )
552 m_absoluteConstants[chanIndex] = m_oldConstants[chanIndex];
554 m_absoluteConstants[chanIndex] =
555 m_oldConstants[chanIndex] * m_calibConstUnred[chanIndex];
559 for (
int i = 0; i < m_myCalibData->nXtals(); i++ )
563 if ( m_calibConstUnred[Xtal_Index] > 0 )
565 constOut << Xtal_Index <<
" " << m_calibConstUnred[Xtal_Index] <<
" "
566 << m_oldConstants[Xtal_Index] <<
" " << m_absoluteConstants[Xtal_Index] << endl;
573bool EmcBhaCalib::readInFromFile() {
575 MsgStream log(
msgSvc(), name() );
577 log << MSG::INFO <<
" Read Bhabha calibration data from files !" << endmsg;
579 std::string runNumberFile = m_fileDir;
580 runNumberFile += m_fileExt;
581 runNumberFile += m_runNumberFile;
583 bool success =
false;
584 log << MSG::INFO <<
" Get file names from input file : " << runNumberFile << endmsg;
586 std::string vectorFile;
587 std::string matrixFile;
589 log << MSG::INFO <<
"Runnumber non-zeros xtals" << endmsg;
591 ifstream datafile( runNumberFile.c_str() );
595 if ( datafile.good() > 0 )
598 while ( !datafile.eof() )
607 if (
num.length() > 0 )
610 vectorFile = m_fileDir;
611 vectorFile += m_fileExt;
613 vectorFile +=
"CalibVector.dat";
615 matrixFile = m_fileDir;
616 matrixFile += m_fileExt;
618 matrixFile +=
"CalibMatrix.dat";
620 vectorIn.open( vectorFile.c_str() );
621 matrixIn.open( matrixFile.c_str() );
623 if ( vectorIn.good() > 0 && matrixIn.good() > 0 )
626 m_myCalibData->readIn( matrixIn, vectorIn );
628 log << MSG::INFO <<
num <<
" "
629 << m_myCalibData->getMatrixM()->num_nonZeros() <<
" "
630 << m_myCalibData->nXtalsHit() << endmsg;
637 log << MSG::ERROR <<
" ERROR: Vector input file " << vectorFile
638 <<
" doesn't exist !" << endmsg;
640 log << MSG::ERROR <<
" ERROR: Matrix input file " << matrixFile
641 <<
" doesn't exist !" << endmsg;
649 if ( success ==
true )
652 for (
int i = 0; i < m_myCalibData->nXtals(); i++ )
655 if ( m_myCalibData->xtalHitsDir( i ) > m_dirHitsCut ) { m_nrXtalsEnoughHits++; }
657 m_nrNonZeros = m_myCalibData->getMatrixM()->num_nonZeros();
658 log << MSG::INFO <<
" Final matrix : "
659 <<
"Number of non zero elements: " << m_nrNonZeros <<
" "
660 << m_myCalibData->nXtalsHit() << endmsg;
667bool EmcBhaCalib::readInFromDB() {
675bool EmcBhaCalib::prepareConstants() {
677 bool successfull =
false;
683 for (
int i = 0; i < m_myCalibData->nXtalsHit(); i++ )
686 chanIndex = m_myCalibData->xtalInd( i );
695 if ( m_myCalibData->xtalHitsDir( i ) < m_dirHitsCut )
696 m_absoluteConstants[chanIndex] = m_oldConstants[chanIndex];
698 m_absoluteConstants[chanIndex] =
699 m_oldConstants[chanIndex] * m_calibConstUnred[chanIndex];
702 double DigiConst[6240];
703 int IxtalNumber[6240];
705 for (
int ind = 0; ind < m_myCalibData->nXtals(); ind++ )
708 DigiConst[ind] = m_absoluteConstants[ind];
712 int ixtal1, ixtal2, ixtal3;
713 ixtal1 = m_emcCalibConstSvc->getIndex( 1, 20, 26 );
714 ixtal2 = m_emcCalibConstSvc->getIndex( 1, 23, 26 );
715 ixtal3 = m_emcCalibConstSvc->getIndex( 1, 24, 26 );
717 for (
int ind = 0; ind < m_myCalibData->nXtals(); ind++ )
720 IxtalNumber[ind] = -1;
728 TFile fconst(
"EmcCalibConst.root",
"recreate" );
731 TTree* constr =
new TTree(
"DigiCalibConst",
"DigiCalibConst" );
732 constr->Branch(
"DigiCalibConst", DigiConst,
"DigiConst[6240]/D" );
733 constr->Branch(
"IxtalNumber", IxtalNumber,
"IxtalNumber[6240]/I" );
762void EmcBhaCalib::ntupleOut() {
764 for (
int i = 0; i < m_myCalibData->nXtalsHit(); i++ )
766 int xtalIndex = m_myCalibData->xtalInd( i );
768 gi0 = m_oldConstants[xtalIndex];
770 if ( gi0 < 0 ) cout <<
"gi0=" << gi0 << endl;
771 err = ( m_calibConstUnred[xtalIndex] - gi0 ) / gi0;
772 calibConst = m_calibConstUnred[xtalIndex];
774 nhitxtal = m_myCalibData->xtalHitsDir( i );
779void EmcBhaCalib::printInfo( std::string fileName ) {
782 std::string xtalHitsDirFile = m_fileDir;
783 xtalHitsDirFile += m_fileExt;
784 xtalHitsDirFile += fileName;
785 xtalHitsDirOut.open( xtalHitsDirFile.c_str() );
788 for (
int i = 0; i < m_myCalibData->nXtalsHit(); i++ )
790 if ( m_myCalibData->xtalHitsDir( i ) > m_dirHitsCut )
792 int chanindex = m_myCalibData->xtalInd( i );
793 xtalHitsDirOut << chanindex << endl;
796 xtalHitsDirOut.close();
799void EmcBhaCalib::digiConstCor() {
807 double digiConst[6240];
809 for (
int ind = 0; ind < m_myCalibData->nXtals(); ind++ )
812 digiConst[ind] = m_oldConstants[ind];
819 std::string ExpEneFile;
820 ExpEneFile =
"cor.conf";
821 ExpEneIn.open( ExpEneFile.c_str() );
824 double Exp_barrel[44], Exp_east[6], Exp_west[6];
826 for (
int i = 0; i < 56; i++ )
829 ExpEneIn >> ExpEne[i];
830 ExpEne[i] = ExpEne[i] * 1.843;
831 if ( i < 6 ) Exp_east[i] = ExpEne[i];
832 if ( i >= 6 && i < 50 ) Exp_barrel[i - 6] = ExpEne[i];
833 if ( i >= 50 ) Exp_west[55 - i] = ExpEne[i];
840 std::string EDepEneFile =
"allxtal.dat";
841 EDepEneIn.open( EDepEneFile.c_str() );
843 double CorDigiConst[6240];
844 int ipart, ithe, iphi;
848 for (
int i = 0; i < 6240; i++ )
851 EDepEneIn >> ipart >> ithe >> iphi >> peak >> sigma;
852 int ix = m_emcCalibConstSvc->getIndex( ipart, ithe, iphi );
854 if ( ipart == 0 ) coeff = peak / Exp_east[ithe];
855 if ( ipart == 1 ) coeff = peak / Exp_barrel[ithe];
856 if ( ipart == 2 ) coeff = peak / Exp_west[ithe];
857 cout << coeff << endl;
859 CorDigiConst[
ix] = coeff;
865 TTree* constr =
new TTree(
"DigiCalibConst",
"DigiCalibConst" );
866 constr->Branch(
"DigiCalibConst", CorDigiConst,
"CorDigiConst[6240]/D" );
870 constr->SetBranchAddress(
"DigiCalibConst", aa );
871 constr->GetEntry( 0 );
873 TFile fconst(
"EmcCalibConstCor.root",
"recreate" );
DECLARE_COMPONENT(BesBdkRc)
EmcBhaCalib(const std::string &name, ISvcLocator *pSvcLocator)
int dsdcg_(const int *n, const double *b, double *x, const long *nelt, int *ia, int *ja, double *a, const long *isym, const long *itol, const double *tol, const long *itmax, long *iter, double *err, long *ierr, const long *iunit, double *rwork, const long *lenw, long *iwork, const long *leniw)
int dsdgmr_(const int *n, const double *b, double *x, const long *nelt, int *ia, int *ja, double *a, const long *isym, long *nsave, const long *itol, const double *tol, const long *itmax, long *iter, double *err, long *ierr, const long *iunit, double *rwork, const long *lenw, long *iwork, const long *leniw)