#include "AlignmentDB/SiAlignFrame.Defs.hh" #include "VertexObjects/Beamline.hh" #include "CalibDB/RunListKey.hh" #include #include #include "AbsEnv/AbsEnv.hh" #include "GeometryBase/CdfPhysicalVolume.hh" #include "GeometryBase/CdfDetector.hh" #include "SiliconGeometry/AbsSiDetectorNode.hh" #include "SiliconGeometry/HWSiDetectorNode.hh" #include "SiliconGeometry/SiAlignmentManager.hh" #include "CLHEP/Matrix/SymMatrix.h" #include "CLHEP/Matrix/Vector.h" #include "CLHEP/Geometry/Point3D.h" #include "CLHEP/Geometry/Vector3D.h" #include "ErrorLogger_i/gERRLOG.hh" #include "Alignment/BeamWrapper.hh" using namespace std; BeamWrapper::prodversion BeamWrapper::_currentprodVersion = V_UNINIT; int BeamWrapper::_currentRun = -999; bool BeamWrapper::_first = true; std::string BeamWrapper::_dbid("default"); struct BeamWrapper::malign BeamWrapper::_alignDB = {0,0, // runS, runE 0.,0., // Tx,Ty 0.,0., // Ax,Ay B_SVX};// beamtype //---------------------------------------------------------- // relation between svxbeam history and Alignment version // this should go into the Database !! //---------------------------------------------------------- const int BeamWrapper::_lasthistoryversion = 13; int BeamWrapper::_historyversion = 0; const std::string BeamWrapper::_defstring("default"); const std::string BeamWrapper::_defdbid("ofotl_prd_read"); const std::string BeamWrapper::_dbversion[14] = {"ofotl_prd_read 100001 1 GOOD", //history 0 "ofotl_prd_read 100001 1 GOOD", // 1 "ofotl_prd_read 100001 1 GOOD", // 2 "ofotl_prd_read 100001 1 GOOD", // 3 "ofotl_prd_read 100001 1 GOOD", // 4 "ofotl_prd_read 100001 1 GOOD", // 5 "ofotl_prd_read 100001 1 GOOD", // 6 "ofotl_prd_read 100001 1 GOOD", // 7 "ofotl_prd_read 100016 3 TEST", // 8 "ofotl_prd_read 100016 3 TEST", // 9 "ofotl_prd_read 100020 3 TEST", // 10 "ofotl_prd_read 100020 3 TEST", // 11 "ofotl_prd_read 100020 3 TEST", // 12 "ofotl_prd_read 100020 3 TEST"}; // 13 BeamWrapper::BeamWrapper(string dbid): _beamSelector ("BeamlineType" , NULL, "BEST" ), _alignPrecedence ("AlignPrecedence" , NULL, "DB" ), _customFile ("customBeamFile" , NULL, "default"), _alignFile ("alignmentFile" , NULL, "default"), _Verbose ("Verbose" , NULL, 1, -1, 5), _productionVersion ("FixtoProdVersion" , NULL, "NONE" ), _useAlign ("useAlignment" , NULL, true ), _substractoldAlign ("substractoldAlign" , NULL, true ), _noDB ("dontuseDB" , NULL, false ), _fhandle(NULL), _target(NULL) { if(_first){ _first = false; _dbid = dbid; } if(_dbid!=dbid)ERRLOG(ELerror, "BeamWrapper") << " WARNING!! " << "trying to reinit DB with different ID" << dbid << " first id: " << _dbid << " is used" << endmsg; _custBeam = CustomBeam("default"); _init = false; _validBeams = 0; _printLevel = 0; } //----------------------------------------------------------------------------- // this method is not need, if one is hapy with the defaults // if called in the beginning of a module it makes configuration very flexible // use like: ->append(_goodBeam.getTalkTo(this, &_Menu)); //----------------------------------------------------------------------------- APPMenu*BeamWrapper::getTalkTo(AppModule* theTarget, APPMenu* parent){ _target = theTarget; _Menu.initialize("BeamWrapper",theTarget, parent); _Menu.initTitle("BeamWrapper"); std::list beamTypes; beamTypes.push_back("COT"); beamTypes.push_back("SVX"); beamTypes.push_back("CUSTOM"); beamTypes.push_back("BEST"); _beamSelector.initValidList(beamTypes); std::list precedence; precedence.push_back("FILE"); precedence.push_back("DB"); precedence.push_back("FILENODBUSE"); _alignPrecedence.initValidList(precedence); std::list version; version.push_back("430"); version.push_back("452"); version.push_back("484"); version.push_back("491"); version.push_back("NONE"); _productionVersion.initValidList(version); _beamSelector.setTarget(theTarget); _alignPrecedence.setTarget(theTarget); _useAlign.setTarget(theTarget); _customFile.setTarget(theTarget); _alignFile.setTarget(theTarget); _substractoldAlign.setTarget(theTarget); _Verbose.setTarget(theTarget); _noDB.setTarget(theTarget); _productionVersion.setTarget(theTarget); _Menu.commands()->append(&_Verbose); _Menu.commands()->append(&_beamSelector); _Menu.commands()->append(&_alignPrecedence); _Menu.commands()->append(&_useAlign); _Menu.commands()->append(&_substractoldAlign); _Menu.commands()->append(&_customFile); _Menu.commands()->append(&_alignFile); _Menu.commands()->append(&_noDB); _Menu.commands()->append(&_productionVersion); return &_Menu; } void BeamWrapper::decodeBeamSelector(std::string beam){ _selectedBeam = B_BEST; if(beam=="COT") {_selectedBeam = B_COT;} else if(beam=="SVX") {_selectedBeam = B_SVX;} else if(beam=="CUSTOM"){_selectedBeam = B_CUSTOM;} else if(beam=="BEST") {_selectedBeam = B_BEST;} } void BeamWrapper::decodeAlignPrecedence(std::string align){ _precedence = O_DB; if(align=="FILE") {_precedence = O_FILE;} else if(align=="DB") {_precedence = O_DB;} else if(align=="FILENODBUSE"){_precedence = O_FILENODBUSE;} } void BeamWrapper::decodeProductionVersion(std::string version){ _prodVersion = V_NONE; if(version=="430") {_prodVersion = V_430;} else if(version=="452") {_prodVersion = V_452;} else if(version=="484") {_prodVersion = V_484;} else if(version=="491") {_prodVersion = V_491;} } //Initilization of custom beamline and Alignment files void BeamWrapper::Init(){ _init = true; _custBeam.newFile(_customFile.value()); decodeBeamSelector(_beamSelector.value()); decodeAlignPrecedence(_alignPrecedence.value()); decodeProductionVersion(_productionVersion.value()); if(_currentprodVersion == V_UNINIT)_currentprodVersion = _prodVersion; if(_currentprodVersion != _prodVersion){ ERRLOG(ELsevere, "BeamWrapper") << " WARNING!! Attempt to use mismatching ProdVersions" << "tcl's need to match!!" << endmsg; _prodVersion = _currentprodVersion; } if(_defstring!=_alignFile.value()) readAlignFile(_alignFile.value()); if(_Verbose.value()>0)std::cout << "BeamWrapper:Init Selected: " << _selectedBeam << std::endl; } //--------------------------------------------------------------- // fills constant cache (array) from specified alignment file //--------------------------------------------------------------- void BeamWrapper::readAlignFile(std::string filename){ float x,ax,y,ay; int runS, runE; beamtype whatbeam; _nalignlines = 0; _fhandle = fopen(filename.c_str(),"r"); if (_fhandle == NULL) { std::cout << std::endl << std::endl; std::cout << "BeamWrapper::readAlignFile Could not open file: " << _alignFile.value() << std::endl << std::endl; }else{ char dummy[300]; char btype; //skip 2 comment lines fgets(dummy,300,_fhandle); std::cout << dummy << std::endl; fgets(dummy,300,_fhandle); std::cout << dummy << std::endl; while (true) { int n = fscanf(_fhandle,"%d %d %f %f %f %f %c",&runS,&runE,&x,&ax,&y,&ay, &btype); switch(btype) { case 'M': whatbeam = B_CUSTOM; break; case 'S': whatbeam = B_SVX; break; case 'C': whatbeam = B_COT; break; default: whatbeam = B_SVX; } if (_nalignlines >= BEAM_MAXLINES){ std::cout << "BeamWrapper::readAlignFile tried read more than " << _nalignlines << " lines" << std::endl; break; } if (n <= 0) break; _listoalign[_nalignlines].runS = runS; _listoalign[_nalignlines].runE = runE; _listoalign[_nalignlines].Tx = x; _listoalign[_nalignlines].Ty = y; _listoalign[_nalignlines].Ax = ax; _listoalign[_nalignlines].Ay = ay; _listoalign[_nalignlines].type = whatbeam; _nalignlines++; } fclose(_fhandle); } } //--------------------------------------------------------------- // get alignment offsets for a given run (for each beamtype) //--------------------------------------------------------------- void BeamWrapper::readAlign(int run, int version){ if(run < 0) run = (AbsEnv::instance())->runNumber(); bool isvalid[4]; for(int i = 0;i<4;i++)isvalid[i] = false; for(int j = 0;j<_nalignlines;j++){ if((_listoalign[j].runS<=run)&&(_listoalign[j].runE>=run)){ beamtype whatbeam = _listoalign[j].type; _align[whatbeam].type = whatbeam; _align[whatbeam].Tx = _listoalign[j].Tx; _align[whatbeam].Ax = _listoalign[j].Ax; _align[whatbeam].Ty = _listoalign[j].Ty; _align[whatbeam].Ay = _listoalign[j].Ay; _align[whatbeam].runS = _listoalign[j].runS; _align[whatbeam].runE = _listoalign[j].runE; isvalid[whatbeam] = true; } } if(!_noDB.value()){ const SiAlignmentManager* manager = (CdfDetector::instance())->getSiDetector()->getSiAlignmentManager(); if((manager!=NULL)&&(manager->isValid())){ SiAlignmentManager::GlobalAl galign = manager->getGlobalAl(); std::cout << "BeamWrapper: actual Frame align: " << " T: " << galign.x() << " " << galign.y() << " " << " A: " << galign.xSlope() << " " << galign.ySlope() << std::endl; if((O_DB==_precedence)||((O_FILE==_precedence)&&!isvalid[B_SVX])){ std::cout << "BeamWrapper: actual Frame align used!" << std::endl; _align[B_SVX].type = B_SVX; _align[B_SVX].Tx = galign.x(); _align[B_SVX].Ax = -galign.ySlope(); _align[B_SVX].Ty = galign.y(); _align[B_SVX].Ay = galign.xSlope(); _align[B_SVX].runS = run; _align[B_SVX].runE = run; _align[B_SVX].type = B_SVX; isvalid[B_SVX] = manager->isValid(); } } } std::cout << "BeamWrapper: read alignment file" << _alignFile.value() << std::endl; std::cout << "BeamWrapper: alignment RUN " << run << std::endl; for(int i = 0;i<4;i++){ if(isvalid[i]){ std::cout << "BeamWrapper: read alignment run: " << _align[i].runS << " " << _align[i].runE << " T: " << _align[i].Tx << " " << _align[i].Ty << " A: " << _align[i].Ax << " " << _align[i].Ay << " type: " << _align[i].type << std::endl; }else{ _align[i].runS = 0; _align[i].runE = 0; _align[i].Tx = 0. ; _align[i].Ty = 0.; _align[i].Ax = 0. ; _align[i].Ay = 0.; } } } // true if the current contents are correct for this run bool BeamWrapper::isValid() { return getCurrent()->isValid(); } // the following accessors will give the best beam position // available in the database // the beam position: double beamx = BeamWrapper.position().x(); HepPoint3D BeamWrapper::position(double z0){ if(!isValid()) return HepPoint3D(-99.0,-99.0,-999.0); beamtype currentbeam = getCurrentType(); HepPoint3D current = getCurrent()->position(z0); double x = current.x(); double y = current.y(); double z = current.z(); if(_Verbose.value()>1)std::cout << "BeamWrapper: orig. BeamPos: " << x <<" "<< y <<" " << z <<" "<< std::endl; if(_useAlign.value()){ x += (_align[currentbeam].Tx + z0*_align[currentbeam].Ay); y += (_align[currentbeam].Ty - z0*_align[currentbeam].Ax); } if(_substractoldAlign.value() && B_SVX==currentbeam){ x -= (_alignDB.Tx + z0*_alignDB.Ay); y -= (_alignDB.Ty - z0*_alignDB.Ax); } if(_Verbose.value()>1)std::cout << "BeamWrapper: final BeamPos: " << x <<" "<< y <<" " << z <<" "<< std::endl; return HepPoint3D(x,y,z); } HepVector BeamWrapper::positionVector(double z0){ HepPoint3D p = position(z0); HepVector v(3); v[0] = p.x(); v[1] = p.y(); v[2] = p.z(); return v; } // the beam slope: double xslope = BeamWrapper.slope.x(); Hep3Vector BeamWrapper::slope(){ if(!isValid()) return Hep3Vector(-99.0,-99.0,-999.0); beamtype currentbeam = getCurrentType(); Hep3Vector current = getCurrent()->slope(); double x = current[0]; double y = current[1]; double z = current[2]; if(_useAlign.value()){ x += _align[currentbeam].Ay; y -= _align[currentbeam].Ax; } if(_substractoldAlign.value() && B_SVX==currentbeam){ x -= _alignDB.Ay; y += _alignDB.Ax; } return Hep3Vector(x,y,z); } // a 3x3 covariance matrix of position, element (3,3) = 35cm. // the x,y elements include intrinsic beam size and beam position // measurement errors (position and slope) HepSymMatrix BeamWrapper::cov3(double z) { return getCurrent()->cov3(z); } // these dump the contents, good for calling at begin run // print a few-line summary void BeamWrapper::printSummary(){ if(!isValid()) { std::cout << "BeamWrapper: Database handle does not contain data " << std::endl; return; } int run = (AbsEnv::instance())->runNumber(); std::cout << "BeamWrapper Postion for run " << run << " :" << std::endl; getCurrent()->printSummary(); } // print everything void BeamWrapper::printAll(){ if(!isValid()) { std::cout << "BeamWrapper: Database handle does not contain data " << std::endl; return; } int run = (AbsEnv::instance())->runNumber(); std::cout << "BeamWrapper Postion for run " << run << " :" << std::endl; getCurrent()->printAll(); } ///////////////////////////////////////////////////////////////////////// // expert interface below here, typical user does not need these ///////////////////////////////////////////////////////////////////////// // set run and version number, -1 means current run/latest version // and retrieve db record // once this interface is triggered with setDatabase, this needs to be // called explicitly at begin run (database manager no longer does it) int BeamWrapper::loadRun(int run, int version) { if(_Verbose.value()>1)printLevel(_Verbose.value()-1); if(!_init)Init(); if(AbsEnv::instance()->runNumber() != _currentRun){ _currentRun = AbsEnv::instance()->runNumber(); if(!_noDB.value()){ if(V_430==_prodVersion){ cotBeam().setHistoryCode(9); cotBeam().loadRun(); if(!cotBeam().isValid()) { cotBeam().setHistoryCode(8); } svxBeam().setHistoryCode(9); svxBeam().loadRun(); if(!svxBeam().isValid()){ svxBeam().setHistoryCode(8); } } else if(V_452==_prodVersion) { cotBeam().setHistoryCode(13); cotBeam().loadRun(); if(!cotBeam().isValid()) { cotBeam().setHistoryCode(11); cotBeam().loadRun(); } if(!cotBeam().isValid()) { cotBeam().setHistoryCode(10); } svxBeam().setHistoryCode(13); svxBeam().loadRun(); if(!svxBeam().isValid()) { svxBeam().setHistoryCode(11); svxBeam().loadRun(); } if(!svxBeam().isValid()) { svxBeam().setHistoryCode(10); } } else if(V_484==_prodVersion) { cotBeam().setHistoryCode(18); svxBeam().setHistoryCode(18); } else if(V_491==_prodVersion) { cotBeam().setHistoryCode(19); svxBeam().setHistoryCode(19); } svxBeam().loadRun(); cotBeam().loadRun(); // try to get the Alignment used to produce this Beamline updateDBAlignment(); } } readAlign(run, version); _custBeam.loadRun(); _validBeams = 0; string svxv(" "), cotv(" "), custv(" "); if( svxBeam().isValid()) { svxv = " svx ";_validBeams+=(1 << B_COT);} if( cotBeam().isValid()) { cotv = " cot ";_validBeams+=(1 << B_SVX);} if(_custBeam.isValid()) { custv = " cust";_validBeams+=(1 << B_CUSTOM);} if(_Verbose.value()>0) std::cout << "BeamWrapper: valid: " << svxv << cotv << custv << std::endl; return 0; } // all dummy methods!!! string BeamWrapper::getStatus() { if(!isValid()) return string("invalid table"); return string("undefined"); } int BeamWrapper::getCid() { if(!isValid()) return -1; return 0; } void BeamWrapper::setHistoryCode(int history){ // this is an expert interface and somewhat dangerous ... svxBeam().setHistoryCode(history); cotBeam().setHistoryCode(history); // force reload! _currentRun = -999; } int BeamWrapper::getHistoryCode(){ if(svxBeam().isValid())return _historyversion; else return 0; } int BeamWrapper::loadCid(int cid) { return 0; } //----------------------------------------------- // returns which beam is currently used //----------------------------------------------- AbsBeam* BeamWrapper::getCurrent(){ switch(_selectedBeam) { case B_COT: _currentBeam = B_COT; return &cotBeam(); case B_SVX: _currentBeam = B_SVX; return &svxBeam(); case B_CUSTOM: _currentBeam = B_CUSTOM; return &_custBeam; case B_BEST: if (_custBeam.isValid()){ _currentBeam = B_CUSTOM; return &_custBeam; }else if (svxBeam().isValid()){ _currentBeam = B_SVX; return &svxBeam(); }else if (cotBeam().isValid()){ _currentBeam = B_COT; return &cotBeam(); } default: _currentBeam = B_CUSTOM; return &_custBeam; } } //----------------------------------------------- // returns which beam is currently used //----------------------------------------------- BeamWrapper::beamtype BeamWrapper::getCurrentType(){ AbsBeam *dummy = getCurrent(); return _currentBeam; } void BeamWrapper::printLevel(int level){ _printLevel = level; _custBeam.printLevel(level); cotBeam().printLevel(level); svxBeam().printLevel(level); } //----------------------------------------------- // get Space Frame alignment constants for a given DB identifier //----------------------------------------------- bool BeamWrapper::fetchDBAlignment(std::string alignDBsource){ string dbid,status; int run, version; bool stat = false; char src[1000]; strncpy(src,alignDBsource.c_str(),1000); char* cc; cc = strtok(src," \t\n\0"); dbid = string(cc); cc = strtok(NULL," \t\n\0"); run = atoi(cc); cc = strtok(NULL," \t\n\0"); version = atoi(cc); cc = strtok(NULL," \t\n\0"); status = string(cc); SiAlignFrame_mgr frameMgr = SiAlignFrame_mgr(dbid,"SiAlignFrame"); SiAlignFrameContainer_ptr frCont; _alignDB.Tx = 0; _alignDB.Ty = 0; _alignDB.Ax = 0; _alignDB.Ay = 0; if(frameMgr.isValid()){ RunListKey qk(run, version); qk.setDataStatus(status); if(frameMgr.get(qk, frCont)==Result::success){ if( (frCont.isValid()) || !frCont.isStale()){ SiAlignFrameContainer::iterator fi = frCont->begin(); _alignDB.Tx = (*fi).Tx() ; _alignDB.Ty = (*fi).Ty() ; _alignDB.Ax = (*fi).alpha_x() ; _alignDB.Ay = (*fi).alpha_y() ; stat = true; } } } return stat; } bool BeamWrapper::updateDBAlignment(){ _alignDB.Tx = 0; _alignDB.Ty = 0; _alignDB.Ax = 0; _alignDB.Ay = 0; if( svxBeam().isValid()) { // get the history version of the svxbeam from the database record _historyversion = (svxBeam().getRecord().Flag0() & 0xFFFF); if((_historyversion>0)&&(_historyversion<=_lasthistoryversion)){ return fetchDBAlignment(_dbversion[_historyversion]); }else{ if(_historyversion>_lasthistoryversion){ // as a clutch the used Alignment global has been coded // into these fields _alignDB.Tx = svxBeam().getRecord().Spare0(); _alignDB.Ty = svxBeam().getRecord().Spare1(); _alignDB.Ax = -svxBeam().getRecord().Spare3(); _alignDB.Ay = svxBeam().getRecord().Spare2(); if(_Verbose.value()>0)std::cout << "BeamWrapper: using stored " << "Alignment: " << "TX: " << _alignDB.Tx << "TY: " << _alignDB.Ty << "AX: " << _alignDB.Ax << "AY: " << _alignDB.Ay << std::endl; return true; }else{ // the Beamline history is coupled to the Alignment version // we don't know the current version => barf! // this should be in the DB some day........... soon ERRLOG(ELsevere,"BeamWrapper: invalid svxBeam History!!!") << "Beamline Database changed, unknown history code encountered" << " update BeamWrapper " << endmsg; } } }else{ _historyversion = 0; } return false; } CotBeam & BeamWrapper::cotBeam() { static CotBeam cotBeam(_dbid); return cotBeam; } SvxBeam & BeamWrapper::svxBeam() { static SvxBeam svxBeam(_dbid); return svxBeam; } Beamline BeamWrapper::getBeamline(int eventFlag){ //this is this ugly as getBeamline is not in AbsBeam switch(getCurrentType()) { case B_COT: return cotBeam().getBeamline(eventFlag); case B_SVX: return svxBeam().getBeamline(eventFlag); case B_CUSTOM: return _custBeam.getBeamline(eventFlag); default: return _custBeam.getBeamline(eventFlag); } } int BeamWrapper::writeToOutput() { return getCurrent()->writeToOutput();} void BeamWrapper::setReadFromFile(bool x) { _custBeam.setReadFromFile(x); cotBeam().setReadFromFile(x); svxBeam().setReadFromFile(x); } void BeamWrapper::setDbFallback(bool b) { _custBeam.setDbFallback(b); cotBeam().setDbFallback(b); svxBeam().setDbFallback(b); }