// // This is the primary user interface for retrieving the bealine from // the database. Entries are for fits using cot tracks. // The best value for this run is determined by the database functionality. // // 4/2001 - creation, Ray Culbertson and Harmut Stadie // // // #include "Alignment/CotBeam.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" using namespace std; CotBeam::CotBeam() { // start up the database access, details determined by the // AC++ database manger _beamIom = CotBeamPosition_mgr("CotBeamPosition"); if( !_beamIom.isValid() ) { errlog( ELerror, "CotBeam::CotBeam" ) << "Error opening default database in CotBeam" << endmsg; } // do an inital get to prime the connection if(_beamIom.get(_cont)!=Result::success) { errlog( ELerror, "CotBeam::CotBeam" ) << "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 = false; } // true if the current contents are correct for this run bool CotBeam::isValid() { return _isValid; } // call must be made at begin run int CotBeam::loadRun() { return loadRun(-1,-1);} // the following accessors will give the best beam position // available in the database // the beam position: double beamx = CotBeam.position().x(); HepPoint3D CotBeam::position(double z){ return getBeamline().position(z); } // the beam slope: double xslope = CotBeam.slope.x(); Hep3Vector CotBeam::slope(){ return getBeamline().slope(); } // the beam position as a vector HepVector CotBeam::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 CotBeam::cov3(double z) { return getBeamline().cov3(z); } // these dump the contents, good for calling at begin run // print a few-line summary void CotBeam::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 CotBeam::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 CotBeam::CotBeam(string dbid) { if(dbid=="") { CotBeam(); return; } if(dbid=="default") dbid="ofotl_prd_read"; _beamIom = CotBeamPosition_mgr(dbid, "CotBeamPosition"); if( !_beamIom.isValid() ) { errlog( ELerror, "CotBeam::CotBeam" ) << "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 = false; } // select "RAW" "GOOD" "TEST" or "COMPLETE" // this is the database "status" void CotBeam::setStatus(string status) { _reqStatus = status; } // history code reflects alignments, code libraries void CotBeam::setHistoryCode(int history){ _reqHistory = history; } // select which algorithm was used 100 = d-phi fit, 50 = vertices void CotBeam::setAlgorithm(int algorithm){ _reqAlgorithm = algorithm; } // select data source 5 = online, 10=offline void CotBeam::setSource(int source) { _reqSource = source; } //if set to 1, prints a summary for all entries, if set to 2 prints all void CotBeam::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 CotBeam::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].isCot()) { 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, "CotBeam::loadRun" ) << "Found run number <=0 " << endmsg; _isValid = false; return 8; } // check that the manager is OK if( !_beamIom.isValid() ) { errlog( ELerror, "CotBeam::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, "CotBeam::loadRun" ) << "Failure of _beamIom.get() to retrieve DB contents(line 237)" << 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, "CotBeam::loadRun" ) << "Error opening RunList database" << endmsg; _isValid = false; return 2; } RunListKey rlk("CotBeamPosition","UNDEFINED", Run::undefined,Version::undefined, PrimType::undefined, "UNDEFINED"); rlk.setRun(run); RunList_var row; if(runIom.get(rlk,row)!=Result::success) { errlog( ELinfo, "CotBeam::loadRun" ) << "Failure of runIom.get() to retrieve DB contents(line 267)" << endmsg; _isValid = false; return 3; } if(!row.isValid()) { errlog( ELinfo, "CotBeam::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, "CotBeam::loadRun" ) << "Failure of _beamIom.get() to retrieve DB contents(line 288)" << endmsg; _isValid = false; return 4; } else if( _cont->size()<=0 ) { errlog( ELinfo, "CotBeam::loadRun" ) << "Received an empty container" << endmsg; continue; } // copy db in vector of Beamlines if(cache()!=0) { errlog( ELwarning, "CotBeam::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, "CotBeam::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 CotBeam::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 CotBeam::loadCid(int cid) { RunListKey rkb; rkb.setID(cid); if((_beamIom.get(rkb, _cont) != Result::success) || (_cont->size() == 0)) { errlog( ELerror, "CotBeam::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 CotBeamPosition CotBeam::getRecord() { if(_cont->size()<=0) return CotBeamPosition(); return *(_cont->begin()); } //if "best available table" was requested, see what was found string CotBeam::getStatus() { if(!isValid()) return string("invalid table"); return _cont->key().dataStatus(); } int CotBeam::getVersion() { if(!isValid()) return -1; return _cont->key().version(); } Beamline CotBeam::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 CotBeam::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; CotBeamPositionContainer::iterator it; for( it=_cont->begin(); it!=_cont->end(); ++it ) { CotBeamPosition& cb = (*it); x.setBeamX(cb.BeamX()); x.setBeamY(cb.BeamY()); x.setSlopeX(cb.SlopeX()); x.setSlopeY(cb.SlopeY()); x.setWidthX(cb.WidthX()); x.setWidthY(cb.WidthY()); x.setWidthXY(cb.WidthXY()); x.setBeamZ(cb.BeamZ()); x.setWidthZ(cb.WidthZ()); x.setBeamXRate(cb.BeamXRate()); x.setBeamYRate(cb.BeamYRate()); x.setSlopeXRate(cb.SlopeXRate()); x.setSlopeYRate(cb.SlopeYRate()); x.setWidthXRate(cb.WidthXRate()); x.setWidthYRate(cb.WidthYRate()); x.setWidthXYRate(cb.WidthXYRate()); x.setBeamZRate(cb.BeamZRate()); x.setWidthZRate(cb.WidthZRate()); x.setMinimZFit(cb.MinimZFit()); x.setWidthZFit(cb.WidthZFit()); x.setBstarZFit(cb.BstarZFit()); x.setZzeroZFit(cb.ZzeroZFit()); x.setMinimZFitRate(cb.MinimZFitRate()); x.setWidthZFitRate(cb.WidthZFitRate()); x.setBstarZFitRate(cb.BstarZFitRate()); x.setZzeroZFitRate(cb.ZzeroZFitRate()); x.setEmittXFit(0.0); x.setBstarXFit(0.0); x.setZzeroXFit(0.0); x.setEmittYFit(0.0); x.setBstarYFit(0.0); x.setZzeroYFit(0.0); x.setEmittXRate(0.0); x.setBstarXRate(0.0); x.setZzeroXRate(0.0); x.setEmittYRate(0.0); x.setBstarYRate(0.0); x.setZzeroYRate(0.0); x.setFitCov00(cb.FitCov00()); x.setFitCov01(cb.FitCov01()); x.setFitCov02(cb.FitCov02()); x.setFitCov03(cb.FitCov03()); x.setFitCov11(cb.FitCov11()); x.setFitCov12(cb.FitCov12()); x.setFitCov13(cb.FitCov13()); x.setFitCov22(cb.FitCov22()); x.setFitCov23(cb.FitCov23()); x.setFitCov33(cb.FitCov33()); x.setStatistics0(cb.Statistics0()); x.setStatistics1(cb.Statistics1()); x.setFlag0(cb.Flag0()); x.setFlag1(cb.Flag1()); x.setSpare0(cb.Spare0()); x.setSpare1(cb.Spare1()); x.setSpare2(cb.Spare2()); x.setSpare3(cb.Spare3()); x.setCotOrSvx(0); x.setIsValid(true); x.setRun(_cont->key().run()); x.setEvent(-1); x.setChannel(cb.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 CotBeam::writeToOutput() { CdfBeamline* cdfBeamline = new CdfBeamline(); cdfBeamline->setBeamlines(_beamlines); char desc[100]; sprintf(desc,"COT_%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; }