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"
70 :Algorithm(name, pSvcLocator),
73 m_askForMatrixInversion(
true),
76 m_readDataFromDB(
false),
77 m_equationSolver("GMR"),
79 m_fileDir("/home/besdata/public/liucx/Calib/"),
81 m_nrXtalsEnoughHits(0),
82 m_runNumberFile("runnumbers.dat"),
88 declareProperty(
"equationSolver", m_equationSolver);
89 declareProperty(
"dirHitsCut", m_dirHitsCut);
90 declareProperty(
"writeToFile", m_writeToFile);
91 declareProperty(
"fileExt", m_fileExt);
92 declareProperty(
"fileDir", m_fileDir);
93 declareProperty(
"readDataFromDB", m_readDataFromDB);
94 declareProperty(
"askForMatrixInversion", m_askForMatrixInversion);
95 declareProperty(
"fitPolynom", m_fitPolynom);
96 declareProperty(
"convCrit", m_convCrit);
97 declareProperty(
"runNumberFile", m_runNumberFile);
98 declareProperty(
"MsgFlag", m_MsgFlag);
100 m_calibConst =
new double[6240];
101 m_calibConstUnred =
new double[6240];
102 m_absoluteConstants =
new double[6240];
103 m_oldConstants =
new double[6240];
117 if ( 0 != m_calibConst) {
118 delete [] m_calibConst;
121 if ( 0 != m_calibConstUnred) {
122 delete [] m_calibConstUnred;
123 m_calibConstUnred = 0;
125 if ( 0 != m_absoluteConstants) {
126 delete [] m_absoluteConstants;
127 m_absoluteConstants = 0;
129 if ( 0 != m_oldConstants) {
130 delete [] m_oldConstants;
133 if ( 0 != m_myCalibData) {
134 delete m_myCalibData;
143 MsgStream log(
msgSvc(), name());
144 log << MSG::INFO <<
"in initialize()" << endreq;
148 m_calibrationSuccessful =
false;
153 if ( nt1 ) m_tuple1 = nt1;
155 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" << endreq;
178 std::cout <<
"Test EmcCalibConstSvc DigiCalibConst(0)= "
179 << m_emcCalibConstSvc -> getDigiCalibConst(0) << std::endl;
191 return StatusCode::SUCCESS;
197 MsgStream log(
msgSvc(), name());
198 log << MSG::DEBUG <<
"in execute()" << endreq;
200 if ( m_readDataFromDB ) {
201 m_calibrationSuccessful = readInFromDB();
203 log << MSG::INFO <<
"read in accumulated matrix from DB"<<endreq;
206 m_calibrationSuccessful = readInFromFile();
208 log << MSG::INFO <<
"read in accumulated matrix from file"<<endreq;
212 if ( m_calibrationSuccessful ==
true ) {
215 if (m_askForMatrixInversion==
true) {
217 m_calibrationSuccessful =
false;
218 log << MSG::INFO <<
" Well, we have "
219 << m_nrXtalsEnoughHits <<
" crystals whith more "
220 <<
"than " << m_dirHitsCut
221 <<
" direct hits. Do you want do "
222 <<
"a matrix inversion ? [N]" << endreq;
225 m_calibrationSuccessful =
true;
229 if ( m_calibrationSuccessful ==
true ) {
232 if ( m_writeToFile ==
true) {
239 if ( m_calibrationSuccessful = m_myCalibData->
reduce() ) {
241 cout<<
"m_calibrationSuccessful="<<m_calibrationSuccessful<<endl;
244 log << MSG::INFO <<
" Reduced number of Xtals for calibration: "
248 cout<<
"m_myCalibData->nXtalsHit()="<<m_myCalibData->
nXtalsHit()
249 <<
"m_myCalibData->nXtals()="<<m_myCalibData->
nXtals()<<endl;
253 if ( m_calibrationSuccessful = solveEqua() ) {
255 for (
int i=0; i<m_myCalibData->
nXtalsHit(); i++){
257 m_calibConstUnred[m_myCalibData->
xtalInd(i)]
271 if ( m_writeToFile==
true){
280 log << MSG::WARNING <<
" Reduction of the Emc Bhabha calibration matrix FAILED !"
282 <<
" Will NOT perform Emc Bhabha calibration !"
284 return( StatusCode::FAILURE);
288 log << MSG::WARNING <<
" ERROR in reading in Emc Bhabha calibration data !"
290 <<
" Will NOT perform Emc Bhabha calibration !"
292 return( StatusCode::FAILURE);
295 return StatusCode::SUCCESS;
301 MsgStream log(
msgSvc(), name());
304 log << MSG::INFO <<
"in endRun()" << endreq;
307 return StatusCode::SUCCESS;
314 MsgStream log(
msgSvc(), name());
316 log << MSG::INFO<<
"Performs the Chi square fit of the accumulated "
322EmcBhaCalib::initCalibConst( ) {
325 MsgStream log(
msgSvc(), name());
327 for (
int i = 0; i< m_myCalibData->
nXtals(); i++ ) {
328 m_calibConst[i] = 1.;
334 <<
" No starting values for calibration constants found ! "
335 <<
"(EmcCalib.Const)"
337 <<
"Set them to 1.0 ! " << endreq;
339 log << MSG::VERBOSE <<
" Read in starting values of calibration constants !"
344 log << MSG::VERBOSE <<
" Have starting values for "
345 << nConst <<
" Xtals !" << endl
346 <<
"Set the others to 1.0 ! " << endmsg;
349 for (
int i = 0; i< nConst; i++ ) {
350 inConst >> numberXtal >> m_calibConst[numberXtal];
356 nConstEmc= m_emcCalibConstSvc -> getDigiCalibConstNo() ;
358 if ( nConstEmc!=6240) cout<<
"number of calibconst="<< nConstEmc<<endl;
364 for (
int i = 0; i< nConstEmc; i++ ) {
369 m_calibConst[i] = m_emcCalibConstSvc -> getDigiCalibConst(i);
371 m_oldConstants[i]=m_emcCalibConstSvc -> getDigiCalibConst(i);
375 m_absoluteConstants[i] =1.0;
377 m_calibConstUnred[i] =1.0;
386EmcBhaCalib::solveEqua() {
388 MsgStream log(
msgSvc(), name());
392 log << MSG::VERBOSE <<
" Solve Matrix equation with method "
395 <<
"Xtals hit: " << m_myCalibData->
nXtalsHit()
397 <<
"Nr of non Zeros: " << m_nrNonZeros << endreq;
403 double convCriterion = m_convCrit;
404 long int maxIter = 1000;
405 long int errUnit = 6;
409 long int lengthDoubleWork;
411 long int lengthIntWork;
417 long int errorFlag=9999;
422 if ( m_equationSolver ==
"GMR" ) {
424 cout<<m_equationSolver<<endl;
426 cout<<
"errorFlag="<<errorFlag<<endl;
429 lengthDoubleWork = (1 + m_myCalibData->
nXtals()*(nsave+7)
432 doubleWork =
new double[lengthDoubleWork];
434 intWork =
new long int [lengthIntWork];
457 cout<<
"errorFlag="<<errorFlag<<endl;
460 log << MSG::VERBOSE <<
" Error flag: " << errorFlag << endreq;
461 if ( errorFlag < 0 ) errorFlag = labs(errorFlag) + 2;
462 switch ( errorFlag ) {
463 case 0: log << MSG::VERBOSE <<
" all went well"
465 case 1: log << MSG::ERROR <<
" insufficient storage allocated for _doubleWork or _intWork"
467 case 2: log << MSG::ERROR <<
" method failed to reduce norm of current residual"
469 case 3: log << MSG::ERROR <<
" insufficient length for _doubleWork"
471 case 4: log << MSG::ERROR <<
" inconsistent _itol and values"
473 default: log << MSG::ERROR <<
" unknown flag" << endreq;
475 log << MSG::VERBOSE <<
" Integer workspace used = " << intWork[8] << endl
476 <<
" Double workspace used = " << intWork[9] << endreq;
482 if ( m_equationSolver ==
"PCG" ) {
484 cout<<m_equationSolver<<endl;
489 lengthDoubleWork = 5 *m_myCalibData->
nXtals() + 50000;
490 doubleWork =
new double[lengthDoubleWork];
492 intWork =
new long int [lengthIntWork];
515 switch ( errorFlag ) {
516 case 0: log << MSG::VERBOSE <<
"all went well" << endreq;
break;
517 case 1: log << MSG::ERROR <<
" insufficient storage allocated for WORK or IWORK"
519 case 2: log << MSG::ERROR <<
" method failed to to converge in maxIter steps."
521 case 3:log << MSG::ERROR <<
" Error in user input. Check input value of _nXtal,_itol."
523 case 4:log << MSG::ERROR <<
" User error tolerance set too tight. "
524 <<
"Reset to 500.0*D1MACH(3). Iteration proceeded."
526 case 5:log << MSG::ERROR <<
" Preconditioning matrix, M, is not Positive Definite. "
528 case 6: log << MSG::ERROR <<
" Matrix A is not Positive Definite."
530 default: log << MSG::ERROR <<
" unknown flag" << endreq;
532 log << MSG::VERBOSE <<
" Integer workspace used = " << intWork[9] << endl
533 <<
"Double workspace used = " << intWork[10] << endreq;
536 log << MSG::VERBOSE <<
"------ Calibration fit statistics ------- " << endl
537 <<
"maximum number of iterations =" << maxIter << endl
538 <<
" number of iterations =" << iters << endl
539 <<
"error estimate of error in final solution ="
542 if ( 0 != doubleWork)
delete [] doubleWork;
543 if ( 0 != intWork)
delete [] intWork;
545 if ( errorFlag != 0 )
return false;
553EmcBhaCalib::writeOut() {
556 std::string vectorFile = m_fileDir;
557 vectorFile += m_fileExt;
558 vectorFile +=
"allCalibVector.dat";
559 vectorOut.open(vectorFile.c_str());
562 std::string matrixFile = m_fileDir;
563 matrixFile += m_fileExt;
564 matrixFile +=
"allCalibMatrix.dat";
565 matrixOut.open(matrixFile.c_str());
567 MsgStream log(
msgSvc(), name());
569 log << MSG::VERBOSE <<
" Write out files "
574 m_myCalibData->
writeOut(matrixOut,vectorOut);
583EmcBhaCalib::writeOutConst() {
587 std::string constFile = m_fileDir;
588 constFile += m_fileExt;
589 constFile +=
"CalibConst.dat";
591 constOut.open(constFile.c_str());
593 constOut <<
"#crystalIndex relative-constant absolute-constant" << endl;
598 for (
int i=0; i < m_myCalibData->
nXtalsHit(); i++) {
600 chanIndex=m_myCalibData->
xtalInd(i);
604 if ( m_myCalibData->
xtalHitsDir(i) < m_dirHitsCut )
605 m_absoluteConstants[chanIndex] = m_oldConstants[chanIndex];
607 m_absoluteConstants[chanIndex] =
608 m_oldConstants[chanIndex] * m_calibConstUnred[chanIndex];
613 for (
int i=0; i < m_myCalibData->
nXtals(); i++) {
616 if(m_calibConstUnred[Xtal_Index]>0){
617 constOut << Xtal_Index <<
" "
618 << m_calibConstUnred[Xtal_Index] <<
" "
619 << m_oldConstants[Xtal_Index] <<
" "
620 << m_absoluteConstants[Xtal_Index]
632EmcBhaCalib::readInFromFile() {
634 MsgStream log(
msgSvc(), name());
636 log << MSG::INFO <<
" Read Bhabha calibration data from files !"
639 std::string runNumberFile = m_fileDir;
640 runNumberFile += m_fileExt;
641 runNumberFile += m_runNumberFile;
643 bool success =
false;
644 log << MSG::INFO <<
" Get file names from input file : "
648 std::string vectorFile;
649 std::string matrixFile;
651 log << MSG::INFO <<
"Runnumber non-zeros xtals"
654 ifstream datafile(runNumberFile.c_str());
658 if (datafile.good() > 0 ) {
660 while( !datafile.eof() ) {
668 if (
num.length() > 0 ) {
670 vectorFile = m_fileDir;
671 vectorFile += m_fileExt;
673 vectorFile +=
"CalibVector.dat";
675 matrixFile = m_fileDir;
676 matrixFile += m_fileExt;
678 matrixFile +=
"CalibMatrix.dat";
680 vectorIn.open(vectorFile.c_str());
681 matrixIn.open(matrixFile.c_str());
683 if ( vectorIn.good() > 0 && matrixIn.good() > 0 ) {
685 m_myCalibData->
readIn(matrixIn,vectorIn);
687 log << MSG::INFO <<
num
699 log << MSG::ERROR <<
" ERROR: Vector input file "
701 <<
" doesn't exist !" << endreq;
703 log << MSG::ERROR <<
" ERROR: Matrix input file "
705 <<
" doesn't exist !" << endreq;
713 if ( success ==
true) {
715 for (
int i=0; i < m_myCalibData->
nXtals(); i++) {
717 if ( m_myCalibData->
xtalHitsDir(i) > m_dirHitsCut )
719 m_nrXtalsEnoughHits++;
723 log << MSG::INFO<<
" Final matrix : "
724 <<
"Number of non zero elements: " << m_nrNonZeros
737EmcBhaCalib::readInFromDB() {
746EmcBhaCalib::prepareConstants() {
748 bool successfull=
false;
754 for (
int i = 0; i< m_myCalibData->
nXtalsHit(); i++ ) {
756 chanIndex=m_myCalibData->
xtalInd(i);
765 if ( m_myCalibData->
xtalHitsDir(i) < m_dirHitsCut )
766 m_absoluteConstants[chanIndex] = m_oldConstants[chanIndex];
768 m_absoluteConstants[chanIndex] =
769 m_oldConstants[chanIndex] * m_calibConstUnred[chanIndex];
773 double DigiConst[6240];
774 int IxtalNumber[6240];
776 for(
int ind=0; ind<m_myCalibData->
nXtals(); ind++ ) {
778 DigiConst[ind]=m_absoluteConstants[ind];
782 int ixtal1,ixtal2,ixtal3;
783 ixtal1=m_emcCalibConstSvc->
getIndex(1,20,26);
784 ixtal2=m_emcCalibConstSvc->
getIndex(1,23,26);
785 ixtal3=m_emcCalibConstSvc->
getIndex(1,24,26);
787 for(
int ind=0; ind<m_myCalibData->
nXtals(); ind++ ) {
797 TFile fconst(
"EmcCalibConst.root",
"recreate");
800 TTree* constr=
new TTree(
"DigiCalibConst",
"DigiCalibConst");
801 constr->Branch(
"DigiCalibConst",DigiConst,
"DigiConst[6240]/D");
802 constr->Branch(
"IxtalNumber",IxtalNumber,
"IxtalNumber[6240]/I");
833EmcBhaCalib::ntupleOut(){
836 for (
int i=0; i < m_myCalibData->
nXtalsHit(); i++) {
837 int xtalIndex=m_myCalibData->
xtalInd(i);
839 gi0 = m_oldConstants[xtalIndex];
841 if (gi0<0) cout<<
"gi0="<<gi0<<endl;
842 err = (m_calibConstUnred[xtalIndex]-gi0)/gi0;
843 calibConst=m_calibConstUnred[xtalIndex];
853EmcBhaCalib::printInfo(std::string fileName) {
856 std::string xtalHitsDirFile = m_fileDir;
857 xtalHitsDirFile += m_fileExt;
858 xtalHitsDirFile += fileName;
859 xtalHitsDirOut.open(xtalHitsDirFile.c_str());
862 for (
int i=0; i < m_myCalibData->
nXtalsHit(); i++) {
863 if ( m_myCalibData->
xtalHitsDir(i) > m_dirHitsCut )
865 int chanindex=m_myCalibData->
xtalInd(i);
866 xtalHitsDirOut<<chanindex<<endl;
869 xtalHitsDirOut.close();
874EmcBhaCalib::digiConstCor(){
882 double digiConst[6240];
884 for(
int ind=0; ind<m_myCalibData->
nXtals(); ind++ ) {
886 digiConst[ind]=m_oldConstants[ind];
893 std::string ExpEneFile;
894 ExpEneFile =
"cor.conf";
895 ExpEneIn.open(ExpEneFile.c_str());
898 double Exp_barrel[44],Exp_east[6],Exp_west[6];
900 for(
int i=0;i<56;i++) {
903 ExpEne[i]=ExpEne[i]*1.843;
904 if (i<6) Exp_east[i]=ExpEne[i];
905 if (i>=6&&i<50) Exp_barrel[i-6]=ExpEne[i];
906 if (i>=50) Exp_west[55-i]=ExpEne[i];
913 std::string EDepEneFile =
"allxtal.dat";
914 EDepEneIn.open(EDepEneFile.c_str());
916 double CorDigiConst[6240];
921 for(
int i=0;i<6240;i++) {
923 EDepEneIn>>ipart>>ithe>>iphi>>peak>>
sigma;
924 int ix=m_emcCalibConstSvc->
getIndex(ipart,ithe,iphi);
926 if (ipart==0) coeff=peak/Exp_east[ithe];
927 if (ipart==1) coeff=peak/Exp_barrel[ithe];
928 if (ipart==2) coeff=peak/Exp_west[ithe];
931 CorDigiConst[
ix]=coeff;
938 TTree* constr=
new TTree(
"DigiCalibConst",
"DigiCalibConst");
939 constr->Branch(
"DigiCalibConst",CorDigiConst,
"CorDigiConst[6240]/D");
943 constr->SetBranchAddress(
"DigiCalibConst", aa);
946 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)
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