// // This is the primary user interface for retrieving the bealine from // the database. Entries are for fits using tracks with SVX hits. // The best value for this run is determined by the database functionality. // // 4/2001 - creation, Ray Culbertson and Harmut Stadie // 4/2005 - added isFitted(), Bo Jayatilaka // // #include "Alignment/SvxBeam.hh" #include "VertexObjects/Beamline.hh" #include "VertexObjects/CdfBeamline.hh" #include #include #include "BaBar/Experiment.hh" #include "AbsEnv/AbsEnv.hh" #include "Edm/EventRecord.hh" #include "CLHEP/Matrix/SymMatrix.h" #include "CLHEP/Matrix/Vector.h" #include "CLHEP/Geometry/Point3D.h" #include "CLHEP/Geometry/Vector3D.h" #include "CalibDB/RunListDefs.hh" #include "Beamline/BeamlineFitter.hh" using namespace std; using namespace Beamlines; SvxBeam::SvxBeam() { // start up the database access, details determined by the // AC++ database manger _beamIom = SvxBeamPosition_mgr("SvxBeamPosition"); if( !_beamIom.isValid() ) { errlog( ELerror, "SvxBeam::SvxBeam" ) << "Error opening default database in SvxBeam" << endmsg; } // do an inital get to prime the connection if(_beamIom.get(_cont)!=Result::success) { errlog( ELerror, "SvxBeam::SvxBeam" ) << "Failure of _beamIom.get() to initialize DB contents" << endmsg; } //ErrorLog errlog; _isValid = false; _expert = false; // do not use expert interface _dbid = "none"; _reqStatus = "NONE"; _reqSource = -1; _reqHistory = -1; _reqAlgorithm = -1; _readFromFile = false; _dbFallback = true; _useTimeDep = true; } // true if the current contents are correct for this run bool SvxBeam::isValid() { return _isValid; } // check whether beamline is fitted or interpolated bool SvxBeam::isFitted() { int flag0, code1, code2; bool _isFitted = false; if (_isValid){ flag0=(_cont->begin())->Flag0(); code1 = flag0 >> 16; code2 = flag0 & 65535; if ((code1 == VXPRIM_GOOD) || (code1 == DPHI_GOOD)) _isFitted = true; else _isFitted = false; } return _isFitted; } // call must be made at begin run int SvxBeam::loadRun() { return loadRun(-1,-1);} // the following accessors will give the best beam position // available in the database // the beam position: double beamx = SvxBeam.position().x(); HepPoint3D SvxBeam::position(double z){ return getBeamline().position(z); } // the beam slope: double xslope = SvxBeam.slope.x(); Hep3Vector SvxBeam::slope(){ return getBeamline().slope(); } // the beam position as a vector HepVector SvxBeam::positionVector(double z){ return getBeamline().positionVector(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 SvxBeam::cov3(double z) { return getBeamline().cov3(z); } // the covariance matrix describing the transverse beam shape HepSymMatrix SvxBeam::cov() { return getBeamline().cov(); } // these dump the contents, good for calling at begin run // print a few-line summary void SvxBeam::printSummary(){ for(BeamConstIter it=_beamlines.begin(); it!=_beamlines.end(); it++) { const Beamline& b = *it; if(b.Channel()==1) { b.printSummary(); } else { b.printSubRun(); } } } // print everything void SvxBeam::printAll(){ for(BeamConstIter it=_beamlines.begin(); it!=_beamlines.end(); it++) { const Beamline& b = *it; if(b.Channel()==1) { b.printAll(); } else { b.printSubRun(); } } } ///////////////////////////////////////////////////////////////////////// // expert interface below here, typical user does not need these ///////////////////////////////////////////////////////////////////////// //create with specified database source, this forces re-opening of db //necessary to use these access methods // if dbid = "default" it will be taken from ofotl_prd SvxBeam::SvxBeam(string dbid) { if(dbid=="") { SvxBeam(); return; } if(dbid=="default") dbid="ofotl_prd_read"; _beamIom = SvxBeamPosition_mgr(dbid, "SvxBeamPosition"); if( !_beamIom.isValid() ) { errlog( ELerror, "SvxBeam::SvxBeam" ) << "Error opening requested database" << endmsg; } _isValid = false; _expert = true; _dbid = dbid; _reqStatus = "NONE"; _reqSource = -1; _reqHistory = -1; _reqAlgorithm = -1; _printLevel = 0; _readFromFile = false; _dbFallback = true; _useTimeDep = true; } // select "RAW" "GOOD" "TEST" or "COMPLETE" // this is the database "status" void SvxBeam::setStatus(string status) { _reqStatus = status; } // history code reflects alignments, code libraries void SvxBeam::setHistoryCode(int history){ _reqHistory = history; } // select which algorithm was used 100 = d-phi fit, 50 = vertices void SvxBeam::setAlgorithm(int algorithm){ _reqAlgorithm = algorithm; } // select data source 5 = online, 10=offline void SvxBeam::setSource(int source) { _reqSource = source; } //if set to 1, prints a summary for all entries, if set to 2 prints all void SvxBeam::printLevel(int level) { _printLevel = level; } // 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 SvxBeam::loadRun(int run, int version) { _isValid = true; _beamlines.clear(); // if using used sets then just cache current entry if(!_expert) { if(cache()!=0) { _isValid = false; return 1; } else { return 0; } } if(_readFromFile) { _isValid = false; int maxScore = 0; AbsEvent* anEvent = AbsEnv::theRunRecord( ); EventRecord::ConstIterator it(anEvent,"CdfBeamline"); for(; it.is_valid(); it++) { CdfBeamline_ch cbl(it); BeamVector bv = cbl->getBeamlines(); if(bv.size()>0 && bv[0].isSvx()) { int score = getScore(bv[0]); if(score>maxScore) { _beamlines= bv; _isValid = true; maxScore = score; } } } } // end if read from file // find requested entry in db if(!_readFromFile || (_dbFallback && (!isValid())) ) { // always need run specified if(run < 0 ) run = (AbsEnv::instance())->runNumber(); //sometimes infrastructure gives run=-1! if( run<=0 ) { errlog( ELwarning, "SvxBeam::loadRun" ) << "Found run number <=0 " << endmsg; _isValid = false; return 8; } // check that the manager is OK if( !_beamIom.isValid() ) { errlog( ELerror, "SvxBeam::loadRun" ) << "Found invalid database manager" << endmsg; _isValid = false; return 7; } // if version specified, no need to go further if(version>0) { RunListKey qkv(run,version); if(_beamIom.get(qkv, _cont)!=Result::success || _cont->size()<=0) { errlog( ELinfo, "SvxBeam::loadRun" ) << "Failure of _beamIom.get() to retrieve DB contents(line 242)" << endmsg; _isValid = false; return 1; } int cachestat = cache(); if(cachestat!=0) return cachestat; if(_printLevel==1) printSummary(); if(_printLevel==2) printAll(); // cache copies current db into Beamline vector return 0; } // some searching needed // get list of entries available for this run RunList_mgr runIom(_dbid,"RunList"); if( !runIom.isValid() ) { errlog( ELerror, "SvxBeam::loadRun" ) << "Error opening RunList database" << endmsg; _isValid = false; return 2; } RunListKey rlk("SvxBeamPosition","UNDEFINED", Run::undefined,Version::undefined, PrimType::undefined, "UNDEFINED"); rlk.setRun(run); RunList_var row; if(runIom.get(rlk,row)!=Result::success) { errlog( ELinfo, "SvxBeam::loadRun" ) << "Failure of runIom.get() to retrieve DB contents(line 272)" << endmsg; _isValid = false; return 3; } if(!row.isValid()) { errlog( ELinfo, "SvxBeam::loadRun" ) << "Found no Entries for Run "<< run << endmsg; _isValid = false; return 3; } int maxScore = 0; int bestCid = -1; // loop over entries for this run, check the contents of each for(RunList::iterator iter=row->begin(); iter!=row->end(); ++iter) { if(_beamIom.get(*iter, _cont)!=Result::success) { errlog( ELinfo, "SvxBeam::loadRun" ) << "Failure of _beamIom.get() to retrieve DB contents(line 291)" << endmsg; _isValid = false; return 4; } else if( _cont->size() <= 0 ) { errlog( ELinfo, "SvxBeam::loadRun" ) << "Received an empty container." << endmsg; continue; } // copy db in vector of Beamlines if(cache()!=0) { errlog( ELwarning, "SvxBeam::loadRun" ) << "Failure to cache DB contents" << endmsg; _isValid = false; return 4; } int score = getScore(_beamlines[0]); if(score>maxScore) { maxScore = score; bestCid = iter->id(); } } // end loop over entries if(bestCid<0) { errlog( ELwarning, "SvxBeam::loadRun" ) << "Could not find requested Beamline in DB" << endmsg; _isValid = false; return 4; } _isValid = true; // reload container with the best entry return loadCid(bestCid); } // endif not read from file return 0; } // find the relevance of a beamline to the requested beamline int SvxBeam::getScore(Beamline& b) { int ver = b.Version(); std::string stat = b.Status(); int hist = b.History(); int algo = b.Algorithm(); int srce = b.Source(); // scoring system, most important sorting is on // status, then on the history code, then on the algorithm // then version int score; if(stat == "UNDEFINED") score = (1<<24); if(stat == "TEST") score = (2<<24); if(stat == "RAW" ) score = (3<<24); if(stat == "GOOD") score = (4<<24); if(stat == "COMPLETE") score = (5<<24); score += (srce<<20) + (hist<<12) + (algo<<6) + ver; if(_reqStatus!="NONE" && stat!=_reqStatus) score=0; if(_reqHistory>=0 && hist!=_reqHistory) score=0; if(_reqAlgorithm>=0 && algo!=_reqAlgorithm) score=0; if(_reqSource>=0 && srce!=_reqSource) score=0; return score; } int SvxBeam::loadCid(int cid) { RunListKey rkb; rkb.setID(cid); if((_beamIom.get(rkb, _cont) != Result::success) || (_cont->size() == 0)) { errlog( ELerror, "SvxBeam::loadCid" ) << "Failure of _beamIom.get() to retrieve known db contents" << endmsg; _isValid = false; return 6; } int cstat = cache(); ( cstat==0 ? _isValid = true : _isValid = false); // print the current container contents if(_printLevel==1) printSummary(); if(_printLevel==2) printAll(); return ( cstat==0 || cstat==3 ? 0 : 7); } //return the whole record SvxBeamPosition SvxBeam::getRecord() { if(_cont->size()<=0) return SvxBeamPosition(); return *(_cont->begin()); } //if "best available table" was requested, see what was found string SvxBeam::getStatus() { if(!isValid()) return string("invalid table"); return _cont->key().dataStatus(); } int SvxBeam::getVersion() { if(!isValid()) return -1; return _cont->key().version(); } Beamline SvxBeam::getBeamline(int eventFlag) { Beamline x; // default is invalid with -99 flag values x.setBeamX(-99.0); x.setBeamY(-99.0); if(!_isValid) return x; int nchan = _beamlines.size(); bool phys = (AbsEnv::instance())->currentRecordType()== edm::RecordType::PhysicsEvent; bool qMC = AbsEnv::instance()->monteFlag(); // try time-dep if possible and requested if( _useTimeDep && (!qMC) && nchan>2 && ((eventFlag==-1 && phys) || eventFlag>0) ) { int event; if(eventFlag>=0) { event = eventFlag; } else { event = (AbsEnv::instance())->trigNumber(); } // the first channel is the total for the run, rest for time-dep int nbin = nchan-1; float bin = 0.5e6; // bins of 1/2 million triggers // ibin is the closest, ibin2 is next closest for extrapolation int ibin,ibin2; ibin = float(event)/bin; if(ibin<0) ibin = 0; if(ibin>nbin-1) ibin = nbin-1; if(ibin==0) { ibin2 = ibin+1; } else if(ibin==nbin-1) { ibin2 = ibin-1; } else { if(float(event)/bin - ibin <0.5) { ibin2 = ibin - 1; } else { ibin2 = ibin + 1; } } float x0,y0,xp,yp; Beamline bl; // this is the entry closest to this event Beamline bl2; // this is the 2nd entry for time-dep extrapolation for(BeamConstIter it=_beamlines.begin(); it!=_beamlines.end(); it++) { const Beamline& b = *it; if(b.Channel()==(ibin+2)) bl = b; if(b.Channel()==(ibin2+2)) bl2 = b; } if(bl.isValid() && bl2.isValid()) { float de = event - (ibin+0.5)*bin; float den = (ibin2-ibin)*bin; x0 = bl.BeamX() + de*( (bl2.BeamX() - bl.BeamX())/den ); y0 = bl.BeamY() + de*( (bl2.BeamY() - bl.BeamY())/den ); xp = bl.SlopeX() + de*( (bl2.SlopeX() - bl.SlopeX())/den ); yp = bl.SlopeY() + de*( (bl2.SlopeY() - bl.SlopeY())/den ); // set the values bl.setBeamX(x0); bl.setBeamY(y0); bl.setSlopeX(xp); bl.setSlopeY(yp); bl.setEvent(event); return bl; } //time-dep failed somehow, fall through to run-averaged } // endif timeDep // return run-averaged beamline for(BeamConstIter it=_beamlines.begin(); it!=_beamlines.end(); it++) { const Beamline& b = *it; if(b.Channel()==1) return b; } // return error values return x; } //copy db containers to vector of Beamlines int SvxBeam::cache() { _beamlines.clear(); // if using used sets, check container flags if( ( !_cont.isValid() ) || _cont.isStale() ) return 1; // check that some entries exist int nchan = _cont->size(); if(nchan<=0) return 2; Beamline x; SvxBeamPositionContainer::iterator it; for( it=_cont->begin(); it!=_cont->end(); ++it ) { SvxBeamPosition& sb = (*it); x.setBeamX(sb.BeamX()); x.setBeamY(sb.BeamY()); x.setSlopeX(sb.SlopeX()); x.setSlopeY(sb.SlopeY()); x.setWidthX(sb.WidthX()); x.setWidthY(sb.WidthY()); x.setWidthXY(sb.WidthXY()); x.setBeamZ(sb.BeamZ()); x.setWidthZ(sb.WidthZ()); x.setBeamXRate(sb.BeamXRate()); x.setBeamYRate(sb.BeamYRate()); x.setSlopeXRate(sb.SlopeXRate()); x.setSlopeYRate(sb.SlopeYRate()); x.setWidthXRate(sb.WidthXRate()); x.setWidthYRate(sb.WidthYRate()); x.setWidthXYRate(sb.WidthXYRate()); x.setBeamZRate(sb.BeamZRate()); x.setWidthZRate(sb.WidthZRate()); x.setMinimZFit(sb.MinimZFit()); x.setWidthZFit(sb.WidthZFit()); x.setBstarZFit(sb.BstarZFit()); x.setZzeroZFit(sb.ZzeroZFit()); x.setMinimZFitRate(sb.MinimZFitRate()); x.setWidthZFitRate(sb.WidthZFitRate()); x.setBstarZFitRate(sb.BstarZFitRate()); x.setZzeroZFitRate(sb.ZzeroZFitRate()); x.setEmittXFit(sb.EmittXFit()); x.setBstarXFit(sb.BstarXFit()); x.setZzeroXFit(sb.ZzeroXFit()); x.setEmittYFit(sb.EmittYFit()); x.setBstarYFit(sb.BstarYFit()); x.setZzeroYFit(sb.ZzeroYFit()); x.setEmittXRate(sb.EmittXRate()); x.setBstarXRate(sb.BstarXRate()); x.setZzeroXRate(sb.ZzeroXRate()); x.setEmittYRate(sb.EmittYRate()); x.setBstarYRate(sb.BstarYRate()); x.setZzeroYRate(sb.ZzeroYRate()); x.setFitCov00(sb.FitCov00()); x.setFitCov01(sb.FitCov01()); x.setFitCov02(sb.FitCov02()); x.setFitCov03(sb.FitCov03()); x.setFitCov11(sb.FitCov11()); x.setFitCov12(sb.FitCov12()); x.setFitCov13(sb.FitCov13()); x.setFitCov22(sb.FitCov22()); x.setFitCov23(sb.FitCov23()); x.setFitCov33(sb.FitCov33()); x.setStatistics0(sb.Statistics0()); x.setStatistics1(sb.Statistics1()); x.setFlag0(sb.Flag0()); x.setFlag1(sb.Flag1()); x.setSpare0(sb.Spare0()); x.setSpare1(sb.Spare1()); x.setSpare2(sb.Spare2()); x.setSpare3(sb.Spare3()); x.setCotOrSvx(1); x.setIsValid(true); x.setRun(_cont->key().run()); x.setEvent(-1); x.setChannel(sb.ChannelID()); x.setStatus(_cont->key().dataStatus()); x.setVersion(_cont->key().version()); _beamlines.push_back(x); } // end loop over channels // check for null entry, an empty place holder // check here since we want to still load the entry if( (*(_cont->begin())).Flag0()==0 ) return 3; return 0; } int SvxBeam::writeToOutput() { CdfBeamline* cdfBeamline = new CdfBeamline(); cdfBeamline->setBeamlines(_beamlines); char desc[100]; sprintf(desc,"SVX_%d_%s_History_%d_",getVersion(), getStatus().data(),history()); CdfBeamline_h handle(cdfBeamline); handle->set_description(std::string(desc)); AbsEvent* anEvent = AbsEnv::theRunRecord( ); anEvent->append(handle); return 0; }