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"
63 :Algorithm(name, pSvcLocator),
66 m_askForMatrixInversion(
true),
69 m_readDataFromDB(
false),
70 m_equationSolver(
"GMR"),
72 m_fileDir(
"/ihepbatch/besdata/public/liucx/Calib/"),
74 m_nrXtalsEnoughHits(0),
75 m_runNumberFile(
"runnumbers.dat"),
81 declareProperty(
"equationSolver", m_equationSolver);
82 declareProperty(
"dirHitsCut", m_dirHitsCut);
83 declareProperty(
"writeToFile", m_writeToFile);
84 declareProperty(
"fileExt", m_fileExt);
85 declareProperty(
"fileDir", m_fileDir);
86 declareProperty(
"readDataFromDB", m_readDataFromDB);
87 declareProperty(
"askForMatrixInversion", m_askForMatrixInversion);
88 declareProperty(
"fitPolynom", m_fitPolynom);
89 declareProperty(
"convCrit", m_convCrit);
90 declareProperty(
"runNumberFile", m_runNumberFile);
91 declareProperty(
"MsgFlag", m_MsgFlag);
93 m_calibConst =
new double[6240];
94 m_calibConstUnred =
new double[6240];
95 m_absoluteConstants =
new double[6240];
96 m_oldConstants =
new double[6240];
110 if ( 0 != m_calibConst) {
111 delete [] m_calibConst;
114 if ( 0 != m_calibConstUnred) {
115 delete [] m_calibConstUnred;
116 m_calibConstUnred = 0;
118 if ( 0 != m_absoluteConstants) {
119 delete [] m_absoluteConstants;
120 m_absoluteConstants = 0;
122 if ( 0 != m_oldConstants) {
123 delete [] m_oldConstants;
126 if ( 0 != m_myCalibData) {
127 delete m_myCalibData;
136 MsgStream log(
msgSvc(), name());
137 log << MSG::INFO <<
"in initialize()" << endreq;
141 m_calibrationSuccessful =
false;
146 if ( nt1 ) m_tuple1 = nt1;
148 m_tuple1=
ntupleSvc()->book(
"FILE302/n1",CLID_ColumnWiseTuple,
"Calib");
151 status1 = m_tuple1->addItem (
"ixtal",ixtal);
152 status1 = m_tuple1->addItem (
"gi0",gi0);
153 status1 = m_tuple1->addItem (
"calibConst",calibConst);
154 status1 = m_tuple1->addItem (
"err",err);
155 status1 = m_tuple1->addItem (
"nhitxtal",nhitxtal);
159 log << MSG::ERROR <<
"Cannot book N-tuple:" << long(m_tuple1) << endmsg;
160 return StatusCode::FAILURE;
166 scCalib = Gaudi::svcLocator() -> service(
"EmcCalibConstSvc", m_emcCalibConstSvc);
167 if( scCalib != StatusCode::SUCCESS){
168 log << MSG::ERROR <<
"can not use EmcCalibConstSvc" << endreq;
171 std::cout <<
"Test EmcCalibConstSvc DigiCalibConst(0)= "
172 << m_emcCalibConstSvc -> getDigiCalibConst(0) << std::endl;
180 return StatusCode::SUCCESS;
186 MsgStream log(
msgSvc(), name());
187 log << MSG::DEBUG <<
"in execute()" << endreq;
189 if ( m_readDataFromDB ) {
190 m_calibrationSuccessful = readInFromDB();
192 log << MSG::INFO <<
"read in accumulated matrix from DB"<<endreq;
195 m_calibrationSuccessful = readInFromFile();
197 log << MSG::INFO <<
"read in accumulated matrix from file"<<endreq;
201 if ( m_calibrationSuccessful ==
true ) {
204 if (m_askForMatrixInversion==
true) {
206 m_calibrationSuccessful =
false;
207 log << MSG::INFO <<
" Well, we have "
208 << m_nrXtalsEnoughHits <<
" crystals whith more "
209 <<
"than " << m_dirHitsCut
210 <<
" direct hits. Do you want do "
211 <<
"a matrix inversion ? [N]" << endreq;
214 m_calibrationSuccessful =
true;
218 if ( m_calibrationSuccessful ==
true ) {
221 if ( m_writeToFile ==
true) {
228 if ( m_calibrationSuccessful = m_myCalibData->
reduce() ) {
230 cout<<
"m_calibrationSuccessful="<<m_calibrationSuccessful<<endl;
233 log << MSG::INFO <<
" Reduced number of Xtals for calibration: "
237 cout<<
"m_myCalibData->nXtalsHit()="<<m_myCalibData->
nXtalsHit()
238 <<
"m_myCalibData->nXtals()="<<m_myCalibData->
nXtals()<<endl;
242 if ( m_calibrationSuccessful = solveEqua() ) {
244 for (
int i=0; i<m_myCalibData->
nXtalsHit(); i++){
246 m_calibConstUnred[m_myCalibData->
xtalInd(i)]
260 if ( m_writeToFile==
true){
269 log << MSG::WARNING <<
" Reduction of the Emc Bhabha calibration matrix FAILED !"
271 <<
" Will NOT perform Emc Bhabha calibration !"
273 return( StatusCode::FAILURE);
277 log << MSG::WARNING <<
" ERROR in reading in Emc Bhabha calibration data !"
279 <<
" Will NOT perform Emc Bhabha calibration !"
281 return( StatusCode::FAILURE);
284 return StatusCode::SUCCESS;
290 MsgStream log(
msgSvc(), name());
293 log << MSG::INFO <<
"in endRun()" << endreq;
296 return StatusCode::SUCCESS;
303 MsgStream log(
msgSvc(), name());
305 log << MSG::INFO<<
"Performs the Chi square fit of the accumulated "
311EmcBhaCalib::initCalibConst( ) {
314 MsgStream log(
msgSvc(), name());
316 for (
int i = 0; i< m_myCalibData->
nXtals(); i++ ) {
317 m_calibConst[i] = 1.;
323 <<
" No starting values for calibration constants found ! "
324 <<
"(EmcCalib.Const)"
326 <<
"Set them to 1.0 ! " << endreq;
328 log << MSG::VERBOSE <<
" Read in starting values of calibration constants !"
333 log << MSG::VERBOSE <<
" Have starting values for "
334 << nConst <<
" Xtals !" << endl
335 <<
"Set the others to 1.0 ! " << endmsg;
338 for (
int i = 0; i< nConst; i++ ) {
339 inConst >> numberXtal >> m_calibConst[numberXtal];
345 nConstEmc= m_emcCalibConstSvc -> getDigiCalibConstNo() ;
347 if ( nConstEmc!=6240) cout<<
"number of calibconst="<< nConstEmc<<endl;
353 for (
int i = 0; i< nConstEmc; i++ ) {
358 m_calibConst[i] = m_emcCalibConstSvc -> getDigiCalibConst(i);
360 m_oldConstants[i]=m_emcCalibConstSvc -> getDigiCalibConst(i);
364 m_absoluteConstants[i] =1.0;
366 m_calibConstUnred[i] =1.0;
375EmcBhaCalib::solveEqua() {
377 MsgStream log(
msgSvc(), name());
381 log << MSG::VERBOSE <<
" Solve Matrix equation with method "
384 <<
"Xtals hit: " << m_myCalibData->
nXtalsHit()
386 <<
"Nr of non Zeros: " << m_nrNonZeros << endreq;
392 double convCriterion = m_convCrit;
393 long int maxIter = 1000;
394 long int errUnit = 6;
398 long int lengthDoubleWork;
400 long int lengthIntWork;
411 if ( m_equationSolver ==
"GMR" ) {
413 cout<<m_equationSolver<<endl;
416 lengthDoubleWork = (1 + m_myCalibData->
nXtals()*(nsave+7)
419 doubleWork =
new double[lengthDoubleWork];
421 intWork =
new long int [lengthIntWork];
445 log << MSG::VERBOSE <<
" Error flag: " << errorFlag << endreq;
446 if ( errorFlag < 0 ) errorFlag = labs(errorFlag) + 2;
447 switch ( errorFlag ) {
448 case 0: log << MSG::VERBOSE <<
" all went well"
450 case 1: log << MSG::ERROR <<
" insufficient storage allocated for _doubleWork or _intWork"
452 case 2: log << MSG::ERROR <<
" method failed to reduce norm of current residual"
454 case 3: log << MSG::ERROR <<
" insufficient length for _doubleWork"
456 case 4: log << MSG::ERROR <<
" inconsistent _itol and values"
458 default: log << MSG::ERROR <<
" unknown flag" << endreq;
460 log << MSG::VERBOSE <<
" Integer workspace used = " << intWork[8] << endl
461 <<
" Double workspace used = " << intWork[9] << endreq;
467 if ( m_equationSolver ==
"PCG" ) {
469 cout<<m_equationSolver<<endl;
474 lengthDoubleWork = 5 *m_myCalibData->
nXtals() + 50000;
475 doubleWork =
new double[lengthDoubleWork];
477 intWork =
new long int [lengthIntWork];
500 switch ( errorFlag ) {
501 case 0: log << MSG::VERBOSE <<
"all went well" << endreq;
break;
502 case 1: log << MSG::ERROR <<
" insufficient storage allocated for WORK or IWORK"
504 case 2: log << MSG::ERROR <<
" method failed to to converge in maxIter steps."
506 case 3:log << MSG::ERROR <<
" Error in user input. Check input value of _nXtal,_itol."
508 case 4:log << MSG::ERROR <<
" User error tolerance set too tight. "
509 <<
"Reset to 500.0*D1MACH(3). Iteration proceeded."
511 case 5:log << MSG::ERROR <<
" Preconditioning matrix, M, is not Positive Definite. "
513 case 6: log << MSG::ERROR <<
" Matrix A is not Positive Definite."
515 default: log << MSG::ERROR <<
" unknown flag" << endreq;
517 log << MSG::VERBOSE <<
" Integer workspace used = " << intWork[9] << endl
518 <<
"Double workspace used = " << intWork[10] << endreq;
521 log << MSG::VERBOSE <<
"------ Calibration fit statistics ------- " << endl
522 <<
"maximum number of iterations =" << maxIter << endl
523 <<
" number of iterations =" << iters << endl
524 <<
"error estimate of error in final solution ="
527 if ( 0 != doubleWork)
delete [] doubleWork;
528 if ( 0 != intWork)
delete [] intWork;
530 if ( errorFlag != 0 )
return false;
538EmcBhaCalib::writeOut() {
541 std::string vectorFile = m_fileDir;
542 vectorFile += m_fileExt;
543 vectorFile +=
"allCalibVector.dat";
544 vectorOut.open(vectorFile.c_str());
547 std::string matrixFile = m_fileDir;
548 matrixFile += m_fileExt;
549 matrixFile +=
"allCalibMatrix.dat";
550 matrixOut.open(matrixFile.c_str());
552 MsgStream log(
msgSvc(), name());
554 log << MSG::VERBOSE <<
" Write out files "
559 m_myCalibData->
writeOut(matrixOut,vectorOut);
568EmcBhaCalib::writeOutConst() {
572 std::string constFile = m_fileDir;
573 constFile += m_fileExt;
574 constFile +=
"CalibConst.dat";
576 constOut.open(constFile.c_str());
578 constOut <<
"#crystalIndex relative-constant absolute-constant" << endl;
583 for (
int i=0; i < m_myCalibData->
nXtalsHit(); i++) {
585 chanIndex=m_myCalibData->
xtalInd(i);
589 if ( m_myCalibData->
xtalHitsDir(i) < m_dirHitsCut )
590 m_absoluteConstants[chanIndex] = m_oldConstants[chanIndex];
592 m_absoluteConstants[chanIndex] =
593 m_oldConstants[chanIndex] * m_calibConstUnred[chanIndex];
598 for (
int i=0; i < m_myCalibData->
nXtals(); i++) {
601 if(m_calibConstUnred[Xtal_Index]>0){
602 constOut << Xtal_Index <<
" "
603 << m_calibConstUnred[Xtal_Index] <<
" "
604 << m_oldConstants[Xtal_Index] <<
" "
605 << m_absoluteConstants[Xtal_Index]
617EmcBhaCalib::readInFromFile() {
619 MsgStream log(
msgSvc(), name());
621 log << MSG::INFO <<
" Read Bhabha calibration data from files !"
624 std::string runNumberFile = m_fileDir;
625 runNumberFile += m_fileExt;
626 runNumberFile += m_runNumberFile;
628 bool success =
false;
629 log << MSG::INFO <<
" Get file names from input file : "
633 std::string vectorFile;
634 std::string matrixFile;
636 log << MSG::INFO <<
"Runnumber non-zeros xtals"
639 ifstream datafile(runNumberFile.c_str());
643 if (datafile.good() > 0 ) {
645 while( !datafile.eof() ) {
653 if (
num.length() > 0 ) {
655 vectorFile = m_fileDir;
656 vectorFile += m_fileExt;
658 vectorFile +=
"CalibVector.dat";
660 matrixFile = m_fileDir;
661 matrixFile += m_fileExt;
663 matrixFile +=
"CalibMatrix.dat";
665 vectorIn.open(vectorFile.c_str());
666 matrixIn.open(matrixFile.c_str());
668 if ( vectorIn.good() > 0 && matrixIn.good() > 0 ) {
670 m_myCalibData->
readIn(matrixIn,vectorIn);
672 log << MSG::INFO <<
num
684 log << MSG::ERROR <<
" ERROR: Vector input file "
686 <<
" doesn't exist !" << endreq;
688 log << MSG::ERROR <<
" ERROR: Matrix input file "
690 <<
" doesn't exist !" << endreq;
698 if ( success ==
true) {
700 for (
int i=0; i < m_myCalibData->
nXtals(); i++) {
702 if ( m_myCalibData->
xtalHitsDir(i) > m_dirHitsCut )
704 m_nrXtalsEnoughHits++;
708 log << MSG::INFO<<
" Final matrix : "
709 <<
"Number of non zero elements: " << m_nrNonZeros
722EmcBhaCalib::readInFromDB() {
731EmcBhaCalib::prepareConstants() {
733 bool successfull=
false;
739 for (
int i = 0; i< m_myCalibData->
nXtalsHit(); i++ ) {
741 chanIndex=m_myCalibData->
xtalInd(i);
750 if ( m_myCalibData->
xtalHitsDir(i) < m_dirHitsCut )
751 m_absoluteConstants[chanIndex] = m_oldConstants[chanIndex];
753 m_absoluteConstants[chanIndex] =
754 m_oldConstants[chanIndex] * m_calibConstUnred[chanIndex];
758 double DigiConst[6240];
760 for(
int ind=0; ind<m_myCalibData->
nXtals(); ind++ ) {
762 DigiConst[ind]=m_absoluteConstants[ind];
785 int IxtalNumber[6240];
787 int ixtal1,ixtal2,ixtal3;
788 ixtal1=m_emcCalibConstSvc->
getIndex(1,20,26);
789 ixtal2=m_emcCalibConstSvc->
getIndex(1,23,26);
790 ixtal3=m_emcCalibConstSvc->
getIndex(1,24,26);
792 for(
int ind=0; ind<m_myCalibData->
nXtals(); ind++ ) {
802 TTree* constr=
new TTree(
"DigiCalibConst",
"DigiCalibConst");
803 constr->Branch(
"DigiCalibConst",DigiConst,
"DigiConst[6240]/D");
804 constr->Branch(
"IxtalNumber",IxtalNumber,
"IxtalNumber[6240]/I");
810 constr->SetBranchAddress(
"DigiCalibConst", aa);
811 constr->SetBranchAddress(
"IxtalNumber", Iaa);
814 TFile fconst(
"EmcCalibConst.root",
"recreate");
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