40#include "GaudiKernel/MsgStream.h"
41#include "GaudiKernel/AlgFactory.h"
42#include "GaudiKernel/ISvcLocator.h"
43#include "GaudiKernel/SmartDataPtr.h"
44#include "GaudiKernel/IDataProviderSvc.h"
45#include "GaudiKernel/PropertyMgr.h"
46#include "GaudiKernel/DataObject.h"
48#include "CLHEP/Vector/ThreeVector.h"
51using CLHEP::Hep3Vector;
54#include "GaudiKernel/MsgStream.h"
69 :Algorithm(name, pSvcLocator),
72 m_askForMatrixInversion(
true),
75 m_readDataFromDB(
false),
76 m_equationSolver(
"GMR"),
78 m_fileDir(
"/ihepbatch/besdata/public/liucx/Calib/"),
80 m_nrXtalsEnoughHits(0),
81 m_runNumberFile(
"runnumbers.dat"),
87 declareProperty(
"equationSolver", m_equationSolver);
88 declareProperty(
"dirHitsCut", m_dirHitsCut);
89 declareProperty(
"writeToFile", m_writeToFile);
90 declareProperty(
"fileExt", m_fileExt);
91 declareProperty(
"fileDir", m_fileDir);
92 declareProperty(
"readDataFromDB", m_readDataFromDB);
93 declareProperty(
"askForMatrixInversion", m_askForMatrixInversion);
94 declareProperty(
"fitPolynom", m_fitPolynom);
95 declareProperty(
"convCrit", m_convCrit);
96 declareProperty(
"runNumberFile", m_runNumberFile);
97 declareProperty(
"MsgFlag", m_MsgFlag);
99 m_calibConst =
new double[6240];
100 m_calibConstUnred =
new double[6240];
101 m_absoluteConstants =
new double[6240];
102 m_oldConstants =
new double[6240];
116 if ( 0 != m_calibConst) {
117 delete [] m_calibConst;
120 if ( 0 != m_calibConstUnred) {
121 delete [] m_calibConstUnred;
122 m_calibConstUnred = 0;
124 if ( 0 != m_absoluteConstants) {
125 delete [] m_absoluteConstants;
126 m_absoluteConstants = 0;
128 if ( 0 != m_oldConstants) {
129 delete [] m_oldConstants;
132 if ( 0 != m_myCalibData) {
133 delete m_myCalibData;
142 MsgStream log(
msgSvc(), name());
143 log << MSG::INFO <<
"in initialize()" << endreq;
147 m_calibrationSuccessful =
false;
152 if ( nt1 ) m_tuple1 = nt1;
154 m_tuple1=
ntupleSvc()->book(
"FILE302/n1",CLID_ColumnWiseTuple,
"Calib");
157 status1 = m_tuple1->addItem (
"ixtal",ixtal);
158 status1 = m_tuple1->addItem (
"gi0",gi0);
159 status1 = m_tuple1->addItem (
"calibConst",calibConst);
160 status1 = m_tuple1->addItem (
"err",err);
161 status1 = m_tuple1->addItem (
"nhitxtal",nhitxtal);
165 log << MSG::ERROR <<
"Cannot book N-tuple:" << long(m_tuple1) << endmsg;
166 return StatusCode::FAILURE;
172 scCalib = Gaudi::svcLocator() -> service(
"EmcCalibConstSvc", m_emcCalibConstSvc);
173 if( scCalib != StatusCode::SUCCESS){
174 log << MSG::ERROR <<
"can not use EmcCalibConstSvc" << endreq;
177 std::cout <<
"Test EmcCalibConstSvc DigiCalibConst(0)= "
178 << m_emcCalibConstSvc -> getDigiCalibConst(0) << std::endl;
186 return StatusCode::SUCCESS;
192 MsgStream log(
msgSvc(), name());
193 log << MSG::DEBUG <<
"in execute()" << endreq;
195 if ( m_readDataFromDB ) {
196 m_calibrationSuccessful = readInFromDB();
198 log << MSG::INFO <<
"read in accumulated matrix from DB"<<endreq;
201 m_calibrationSuccessful = readInFromFile();
203 log << MSG::INFO <<
"read in accumulated matrix from file"<<endreq;
207 if ( m_calibrationSuccessful ==
true ) {
210 if (m_askForMatrixInversion==
true) {
212 m_calibrationSuccessful =
false;
213 log << MSG::INFO <<
" Well, we have "
214 << m_nrXtalsEnoughHits <<
" crystals whith more "
215 <<
"than " << m_dirHitsCut
216 <<
" direct hits. Do you want do "
217 <<
"a matrix inversion ? [N]" << endreq;
220 m_calibrationSuccessful =
true;
224 if ( m_calibrationSuccessful ==
true ) {
227 if ( m_writeToFile ==
true) {
234 if ( m_calibrationSuccessful = m_myCalibData->
reduce() ) {
236 cout<<
"m_calibrationSuccessful="<<m_calibrationSuccessful<<endl;
239 log << MSG::INFO <<
" Reduced number of Xtals for calibration: "
243 cout<<
"m_myCalibData->nXtalsHit()="<<m_myCalibData->
nXtalsHit()
244 <<
"m_myCalibData->nXtals()="<<m_myCalibData->
nXtals()<<endl;
248 if ( m_calibrationSuccessful = solveEqua() ) {
250 for (
int i=0; i<m_myCalibData->
nXtalsHit(); i++){
252 m_calibConstUnred[m_myCalibData->
xtalInd(i)]
266 if ( m_writeToFile==
true){
275 log << MSG::WARNING <<
" Reduction of the Emc Bhabha calibration matrix FAILED !"
277 <<
" Will NOT perform Emc Bhabha calibration !"
279 return( StatusCode::FAILURE);
283 log << MSG::WARNING <<
" ERROR in reading in Emc Bhabha calibration data !"
285 <<
" Will NOT perform Emc Bhabha calibration !"
287 return( StatusCode::FAILURE);
290 return StatusCode::SUCCESS;
296 MsgStream log(
msgSvc(), name());
299 log << MSG::INFO <<
"in endRun()" << endreq;
302 return StatusCode::SUCCESS;
309 MsgStream log(
msgSvc(), name());
311 log << MSG::INFO<<
"Performs the Chi square fit of the accumulated "
317EmcBhaCalib::initCalibConst( ) {
320 MsgStream log(
msgSvc(), name());
322 for (
int i = 0; i< m_myCalibData->
nXtals(); i++ ) {
323 m_calibConst[i] = 1.;
329 <<
" No starting values for calibration constants found ! "
330 <<
"(EmcCalib.Const)"
332 <<
"Set them to 1.0 ! " << endreq;
334 log << MSG::VERBOSE <<
" Read in starting values of calibration constants !"
339 log << MSG::VERBOSE <<
" Have starting values for "
340 << nConst <<
" Xtals !" << endl
341 <<
"Set the others to 1.0 ! " << endmsg;
344 for (
int i = 0; i< nConst; i++ ) {
345 inConst >> numberXtal >> m_calibConst[numberXtal];
351 nConstEmc= m_emcCalibConstSvc -> getDigiCalibConstNo() ;
353 if ( nConstEmc!=6240) cout<<
"number of calibconst="<< nConstEmc<<endl;
359 for (
int i = 0; i< nConstEmc; i++ ) {
364 m_calibConst[i] = m_emcCalibConstSvc -> getDigiCalibConst(i);
366 m_oldConstants[i]=m_emcCalibConstSvc -> getDigiCalibConst(i);
370 m_absoluteConstants[i] =1.0;
372 m_calibConstUnred[i] =1.0;
381EmcBhaCalib::solveEqua() {
383 MsgStream log(
msgSvc(), name());
387 log << MSG::VERBOSE <<
" Solve Matrix equation with method "
390 <<
"Xtals hit: " << m_myCalibData->
nXtalsHit()
392 <<
"Nr of non Zeros: " << m_nrNonZeros << endreq;
398 double convCriterion = m_convCrit;
399 long int maxIter = 1000;
400 long int errUnit = 6;
404 long int lengthDoubleWork;
406 long int lengthIntWork;
412 long int errorFlag=9999;
417 if ( m_equationSolver ==
"GMR" ) {
419 cout<<m_equationSolver<<endl;
421 cout<<
"errorFlag="<<errorFlag<<endl;
424 lengthDoubleWork = (1 + m_myCalibData->
nXtals()*(nsave+7)
427 doubleWork =
new double[lengthDoubleWork];
429 intWork =
new long int [lengthIntWork];
452 cout<<
"errorFlag="<<errorFlag<<endl;
455 log << MSG::VERBOSE <<
" Error flag: " << errorFlag << endreq;
456 if ( errorFlag < 0 ) errorFlag = labs(errorFlag) + 2;
457 switch ( errorFlag ) {
458 case 0: log << MSG::VERBOSE <<
" all went well"
460 case 1: log << MSG::ERROR <<
" insufficient storage allocated for _doubleWork or _intWork"
462 case 2: log << MSG::ERROR <<
" method failed to reduce norm of current residual"
464 case 3: log << MSG::ERROR <<
" insufficient length for _doubleWork"
466 case 4: log << MSG::ERROR <<
" inconsistent _itol and values"
468 default: log << MSG::ERROR <<
" unknown flag" << endreq;
470 log << MSG::VERBOSE <<
" Integer workspace used = " << intWork[8] << endl
471 <<
" Double workspace used = " << intWork[9] << endreq;
477 if ( m_equationSolver ==
"PCG" ) {
479 cout<<m_equationSolver<<endl;
484 lengthDoubleWork = 5 *m_myCalibData->
nXtals() + 50000;
485 doubleWork =
new double[lengthDoubleWork];
487 intWork =
new long int [lengthIntWork];
510 switch ( errorFlag ) {
511 case 0: log << MSG::VERBOSE <<
"all went well" << endreq;
break;
512 case 1: log << MSG::ERROR <<
" insufficient storage allocated for WORK or IWORK"
514 case 2: log << MSG::ERROR <<
" method failed to to converge in maxIter steps."
516 case 3:log << MSG::ERROR <<
" Error in user input. Check input value of _nXtal,_itol."
518 case 4:log << MSG::ERROR <<
" User error tolerance set too tight. "
519 <<
"Reset to 500.0*D1MACH(3). Iteration proceeded."
521 case 5:log << MSG::ERROR <<
" Preconditioning matrix, M, is not Positive Definite. "
523 case 6: log << MSG::ERROR <<
" Matrix A is not Positive Definite."
525 default: log << MSG::ERROR <<
" unknown flag" << endreq;
527 log << MSG::VERBOSE <<
" Integer workspace used = " << intWork[9] << endl
528 <<
"Double workspace used = " << intWork[10] << endreq;
531 log << MSG::VERBOSE <<
"------ Calibration fit statistics ------- " << endl
532 <<
"maximum number of iterations =" << maxIter << endl
533 <<
" number of iterations =" << iters << endl
534 <<
"error estimate of error in final solution ="
537 if ( 0 != doubleWork)
delete [] doubleWork;
538 if ( 0 != intWork)
delete [] intWork;
540 if ( errorFlag != 0 )
return false;
548EmcBhaCalib::writeOut() {
551 std::string vectorFile = m_fileDir;
552 vectorFile += m_fileExt;
553 vectorFile +=
"allCalibVector.dat";
554 vectorOut.open(vectorFile.c_str());
557 std::string matrixFile = m_fileDir;
558 matrixFile += m_fileExt;
559 matrixFile +=
"allCalibMatrix.dat";
560 matrixOut.open(matrixFile.c_str());
562 MsgStream log(
msgSvc(), name());
564 log << MSG::VERBOSE <<
" Write out files "
569 m_myCalibData->
writeOut(matrixOut,vectorOut);
578EmcBhaCalib::writeOutConst() {
582 std::string constFile = m_fileDir;
583 constFile += m_fileExt;
584 constFile +=
"CalibConst.dat";
586 constOut.open(constFile.c_str());
588 constOut <<
"#crystalIndex relative-constant absolute-constant" << endl;
593 for (
int i=0; i < m_myCalibData->
nXtalsHit(); i++) {
595 chanIndex=m_myCalibData->
xtalInd(i);
599 if ( m_myCalibData->
xtalHitsDir(i) < m_dirHitsCut )
600 m_absoluteConstants[chanIndex] = m_oldConstants[chanIndex];
602 m_absoluteConstants[chanIndex] =
603 m_oldConstants[chanIndex] * m_calibConstUnred[chanIndex];
608 for (
int i=0; i < m_myCalibData->
nXtals(); i++) {
611 if(m_calibConstUnred[Xtal_Index]>0){
612 constOut << Xtal_Index <<
" "
613 << m_calibConstUnred[Xtal_Index] <<
" "
614 << m_oldConstants[Xtal_Index] <<
" "
615 << m_absoluteConstants[Xtal_Index]
627EmcBhaCalib::readInFromFile() {
629 MsgStream log(
msgSvc(), name());
631 log << MSG::INFO <<
" Read Bhabha calibration data from files !"
634 std::string runNumberFile = m_fileDir;
635 runNumberFile += m_fileExt;
636 runNumberFile += m_runNumberFile;
638 bool success =
false;
639 log << MSG::INFO <<
" Get file names from input file : "
643 std::string vectorFile;
644 std::string matrixFile;
646 log << MSG::INFO <<
"Runnumber non-zeros xtals"
649 ifstream datafile(runNumberFile.c_str());
653 if (datafile.good() > 0 ) {
655 while( !datafile.eof() ) {
663 if (
num.length() > 0 ) {
665 vectorFile = m_fileDir;
666 vectorFile += m_fileExt;
668 vectorFile +=
"CalibVector.dat";
670 matrixFile = m_fileDir;
671 matrixFile += m_fileExt;
673 matrixFile +=
"CalibMatrix.dat";
675 vectorIn.open(vectorFile.c_str());
676 matrixIn.open(matrixFile.c_str());
678 if ( vectorIn.good() > 0 && matrixIn.good() > 0 ) {
680 m_myCalibData->
readIn(matrixIn,vectorIn);
682 log << MSG::INFO <<
num
694 log << MSG::ERROR <<
" ERROR: Vector input file "
696 <<
" doesn't exist !" << endreq;
698 log << MSG::ERROR <<
" ERROR: Matrix input file "
700 <<
" doesn't exist !" << endreq;
708 if ( success ==
true) {
710 for (
int i=0; i < m_myCalibData->
nXtals(); i++) {
712 if ( m_myCalibData->
xtalHitsDir(i) > m_dirHitsCut )
714 m_nrXtalsEnoughHits++;
718 log << MSG::INFO<<
" Final matrix : "
719 <<
"Number of non zero elements: " << m_nrNonZeros
732EmcBhaCalib::readInFromDB() {
741EmcBhaCalib::prepareConstants() {
743 bool successfull=
false;
749 for (
int i = 0; i< m_myCalibData->
nXtalsHit(); i++ ) {
751 chanIndex=m_myCalibData->
xtalInd(i);
760 if ( m_myCalibData->
xtalHitsDir(i) < m_dirHitsCut )
761 m_absoluteConstants[chanIndex] = m_oldConstants[chanIndex];
763 m_absoluteConstants[chanIndex] =
764 m_oldConstants[chanIndex] * m_calibConstUnred[chanIndex];
768 double DigiConst[6240];
769 int IxtalNumber[6240];
771 for(
int ind=0; ind<m_myCalibData->
nXtals(); ind++ ) {
773 DigiConst[ind]=m_absoluteConstants[ind];
777 int ixtal1,ixtal2,ixtal3;
778 ixtal1=m_emcCalibConstSvc->
getIndex(1,20,26);
779 ixtal2=m_emcCalibConstSvc->
getIndex(1,23,26);
780 ixtal3=m_emcCalibConstSvc->
getIndex(1,24,26);
782 for(
int ind=0; ind<m_myCalibData->
nXtals(); ind++ ) {
792 TFile fconst(
"EmcCalibConst.root",
"recreate");
795 TTree* constr=
new TTree(
"DigiCalibConst",
"DigiCalibConst");
796 constr->Branch(
"DigiCalibConst",DigiConst,
"DigiConst[6240]/D");
797 constr->Branch(
"IxtalNumber",IxtalNumber,
"IxtalNumber[6240]/I");
828EmcBhaCalib::ntupleOut(){
831 for (
int i=0; i < m_myCalibData->
nXtalsHit(); i++) {
832 int xtalIndex=m_myCalibData->
xtalInd(i);
834 gi0 = m_oldConstants[xtalIndex];
836 if (gi0<0) cout<<
"gi0="<<gi0<<endl;
837 err = (m_calibConstUnred[xtalIndex]-gi0)/gi0;
838 calibConst=m_calibConstUnred[xtalIndex];
848EmcBhaCalib::printInfo(std::string fileName) {
851 std::string xtalHitsDirFile = m_fileDir;
852 xtalHitsDirFile += m_fileExt;
853 xtalHitsDirFile += fileName;
854 xtalHitsDirOut.open(xtalHitsDirFile.c_str());
857 for (
int i=0; i < m_myCalibData->
nXtalsHit(); i++) {
858 if ( m_myCalibData->
xtalHitsDir(i) > m_dirHitsCut )
860 int chanindex=m_myCalibData->
xtalInd(i);
861 xtalHitsDirOut<<chanindex<<endl;
864 xtalHitsDirOut.close();
869EmcBhaCalib::digiConstCor(){
877 double digiConst[6240];
879 for(
int ind=0; ind<m_myCalibData->
nXtals(); ind++ ) {
881 digiConst[ind]=m_oldConstants[ind];
888 std::string ExpEneFile;
889 ExpEneFile =
"cor.conf";
890 ExpEneIn.open(ExpEneFile.c_str());
893 double Exp_barrel[44],Exp_east[6],Exp_west[6];
895 for(
int i=0;i<56;i++) {
898 ExpEne[i]=ExpEne[i]*1.843;
899 if (i<6) Exp_east[i]=ExpEne[i];
900 if (i>=6&&i<50) Exp_barrel[i-6]=ExpEne[i];
901 if (i>=50) Exp_west[55-i]=ExpEne[i];
908 std::string EDepEneFile =
"allxtal.dat";
909 EDepEneIn.open(EDepEneFile.c_str());
911 double CorDigiConst[6240];
916 for(
int i=0;i<6240;i++) {
918 EDepEneIn>>ipart>>ithe>>iphi>>peak>>sigma;
919 int ix=m_emcCalibConstSvc->
getIndex(ipart,ithe,iphi);
921 if (ipart==0) coeff=peak/Exp_east[ithe];
922 if (ipart==1) coeff=peak/Exp_barrel[ithe];
923 if (ipart==2) coeff=peak/Exp_west[ithe];
926 CorDigiConst[ix]=coeff;
933 TTree* constr=
new TTree(
"DigiCalibConst",
"DigiCalibConst");
934 constr->Branch(
"DigiCalibConst",CorDigiConst,
"CorDigiConst[6240]/D");
938 constr->SetBranchAddress(
"DigiCalibConst", aa);
941 TFile fconst(
"EmcCalibConstCor.root",
"recreate");
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)
int & xtalHitsDir(int ind)
void printVec(int number)
EmcLSSMatrix * getMatrixM()
void writeOut(ostream &OutM, ostream &outV)
void readIn(istream &InM, istream &InV)
EmcBhaCalib(const std::string &name, ISvcLocator *pSvcLocator)
int * column(const int &rowind=0) const
double * matrix(const int &rowind=0) const
virtual int getIndex(unsigned int PartId, unsigned int ThetaIndex, unsigned int PhiIndex) const =0