Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

BMSpillFiller.cxx

Go to the documentation of this file.
00001 #include "BMSpillFiller.h"
00002 
00003 #include <BeamDataUtil/BeamMonSpill.h>
00004 #include <BeamDataUtil/BDEarliest.h>
00005 #include <BeamDataUtil/BDHornCurrent.h>
00006 #include <BeamDataUtil/BDScalar.h>
00007 #include <BeamDataUtil/BDHadMuMon.h>
00008 #include <BeamDataUtil/BDDevices.h>
00009 #include <BeamDataUtil/BDTarget.h>
00010 #include <BeamDataUtil/BDSwicPeds.h>
00011 
00012 #include <RawData/RawBeamMonBlock.h>
00013 
00014 #include <MessageService/MsgService.h>
00015 
00016 CVSID("$Id: BMSpillFiller.cxx,v 1.24 2006/05/27 07:26:38 rhatcher Exp $");
00017 
00018 #include <DatabaseInterface/DbiWriter.h>
00019 //  Instantiate associated Result Pointer class.
00020 #include <DatabaseInterface/DbiWriter.tpl>
00021 template class  DbiWriter<BeamMonSpill>;
00022 
00023 #include <string>
00024 #include <vector>
00025 using namespace std;
00026 #include <cmath>
00027 
00028 const double min_horn_current = 150;
00029 
00030 
00031 BMSpillFiller::BMSpillFiller(BDEarliest& bde,
00032                              BDScalar* bdpi[4],
00033                              BDHornCurrent& bdhc,
00034                              BDTarget& target,
00035                              BDHadMuMon* hadmu[4])
00036     : fEarliest(bde)
00037     , fHorn(bdhc)
00038     , fTarget(target)
00039     , fSpillsPerWrite(3000)
00040 {
00041     this->SetSpillsPerWrite();
00042     for (int ind=0; ind<4; ++ind) fToroids[ind] = bdpi[ind];
00043     for (int ind=0; ind<4; ++ind) fHadMu[ind]   = hadmu[ind];
00044 }
00045 
00046 BMSpillFiller::~BMSpillFiller()
00047 {
00048     this->DBU(true);
00049     while (fSpills.size()) {
00050         delete fSpills.back();
00051         fSpills.pop_back();
00052     }
00053 }
00054 
00055 void BMSpillFiller::SetSpillsPerWrite(size_t n)
00056 {
00057     fSpillsPerWrite = n;
00058 }
00059 
00060 static const RawBeamData* get_dev(const RawBeamMonBlock& rbmb,
00061                                   const char* devname)
00062 {
00063     const RawBeamData* rbd = rbmb[devname];
00064     if (!rbd) return 0;
00065     if (!rbd->GetDataLength()) return 0;
00066     return rbd;
00067 }
00068 
00069 
00070 static bool is_pm_there(const RawBeamMonBlock& rbmb, const char* dev)
00071 {
00072     // If the PM data isn't there, don't care if it's inserted or not,
00073     // it is still dead to us.
00074     const RawBeamData* pmswic = get_dev(rbmb,Form("E:M%sDS",dev));
00075     if (!pmswic) {
00076         MSG("BDD",Msg::kVerbose)
00077             << "PM" << dev << " not in data\n";
00078         return false;
00079     }
00080 
00081     // PM data is there, see if LVDT can tell us if it's inserted or
00082     // not
00083     const double lvdt_inness_cut = 6.0;
00084     const RawBeamData* lvdt = get_dev(rbmb,Form("E_M%sLV",dev));
00085     if (lvdt && lvdt->GetDataLength()) {
00086         double val = lvdt->GetData()[0];
00087         if (val < lvdt_inness_cut) return true;
00088         MSG("BDD",Msg::kVerbose)
00089             << "PM" << dev << " fails LVDT cut, val = " << val << endl;
00090         return false;
00091     }
00092     
00093 #if 0
00094     // No LVDT, (initial running had typo in dev list).  Check if the
00095     // "I:PMxxx" device is there - not given clear understanding of
00096     // what this actually is.
00097     const RawBeamData* ipm = get_dev(rbmb,Form("I:PM%s",dev));
00098     if (ipm) {
00099         MSG("BDD",Msg::kDebug)
00100             << "PM" << dev << " no I:PM" << dev << endl;
00101         return false;
00102     }
00103 #endif
00104 
00105     return true;
00106 }
00107 
00108 void BMSpillFiller::Spill(const RawBeamMonHeaderBlock& /*rbmhb*/,
00109                           const RawBeamMonBlock& rbmb)
00110 {
00111     BeamMonSpill* spill = new BeamMonSpill;
00112     BeamMonSpill::StatusBits bits = spill->GetStatusBits(); // is zeroed
00113 
00114     double dae=0, vme=0;
00115     fEarliest.GetTimestamps(dae, vme);
00116     if (dae==0 && vme==0) {
00117         MSG("BDD",Msg::kWarning)
00118             << "Both DAE and VME timestamps are zero.\n";
00119         return;
00120     }
00121 
00122 
00123     if (!vme) bits.time_source = 1;
00124     VldTimeStamp vts_dae(dae), vts_vme(vme);
00125     spill->SetTimestamps(vts_dae,vts_vme);
00126 
00127     spill->SetToroids(fToroids[0]->GetValue(),
00128                       fToroids[1]->GetValue(), 
00129                       fToroids[2]->GetValue(), 
00130                       fToroids[3]->GetValue());
00131 
00132     double horn_current = fHorn.GetValue();
00133     if (fabs(horn_current) > min_horn_current) bits.horn_on = 1;
00134     else {
00135         MSG("BDD",Msg::kDebug) << "Horn current: "
00136                               << horn_current << " not high enough\n";
00137     }
00138     spill->SetHornCurrent(horn_current);
00139 
00140     // BPMs
00141     vector<double> xp,yp,xi,yi,iave;
00142     fTarget.BpmProjection(xp,yp,xi,yi);
00143     for (size_t ind=0; ind<xi.size(); ++ind)
00144         iave.push_back(0.5*(xi[ind]+yi[ind]));
00145     spill->SetBPM(xp,yp,iave);
00146     bits.n_batches = xi.size();
00147 
00148     // profile monitors
00149     double x=0,y=0,w=0,h=0;
00150     fTarget.ProfileProjection(x,y,w,h);
00151     spill->SetProfile(x,y,w,h);
00152 
00153     // Determine which time to use to get the target position
00154     double tgttime=vme;
00155     if (tgttime==0) tgttime=dae;
00156 
00157     bool is_in = false;
00158     double location = -9999;
00159     BDTarget::BeamType beam_type = fTarget.TargetIn(is_in,location,tgttime);
00160     bits.target_in = is_in ? 1 : 0;
00161     if (is_in) {
00162         switch (beam_type) {
00163         case BDTarget::kLE: bits.beam_type = 1; break;
00164         case BDTarget::kME: bits.beam_type = 2; break;
00165         case BDTarget::kHE: bits.beam_type = 3; break;
00166         case BDTarget::kPsME: bits.beam_type = 4; break;
00167         case BDTarget::kPsHE: bits.beam_type = 5; break;
00168         case BDTarget::kUnknown: default:
00169             MSG("BDD",Msg::kDebug)
00170                 << "Unknown beam type, distance = " << location << endl;
00171             bits.beam_type = 0;
00172             break;
00173         }
00174     }
00175     else {
00176         MSG("BDD",Msg::kWarning)
00177             << "Target not in!\n";
00178     }
00179         
00180 
00181     bits.pedestal = BDSwicPeds::IsPedSpill(rbmb);
00182     if (bits.pedestal) MSG("BDD",Msg::kDebug) << "Got ped spill\n";
00183 
00184     bits.pm121_in = is_pm_there(rbmb,"121");
00185     bits.pmtgt_in = is_pm_there(rbmb,"TGT");
00186 
00187     if(!bits.pm121_in) MSG("BDD",Msg::kDebug) << "No pm121\n";
00188     if(!bits.pmtgt_in) MSG("BDD",Msg::kDebug) << "No pmtgt\n";
00189 
00190     spill->SetStatusBits(bits);
00191 
00192     spill->SetHadMuInt(fHadMu[0]->GetTotalCharge(),
00193                        fHadMu[1]->GetTotalCharge(),
00194                        fHadMu[2]->GetTotalCharge(),
00195                        fHadMu[3]->GetTotalCharge());
00196 
00197 
00198     fSpills.push_back(spill);
00199 
00200     BeamMonSpill::StatusBits sb = spill->GetStatusBits();
00201 
00202     MSG("BDD",Msg::kVerbose)
00203         << " horn_on:" << sb.horn_on
00204         << " target_in:" << sb.target_in
00205         << " beam_type:" << sb.beam_type
00206         << " pedestal:" << sb.pedestal
00207         << " pm121_in:" << sb.pm121_in
00208         << " pmtgt_in:" << sb.pmtgt_in
00209         << endl;
00210 
00211     MSG("BDD",Msg::kVerbose) << fSpills.size() << " spills\n";
00212 
00213     this->DBU();
00214 }
00215 
00216 void BMSpillFiller::DBU(bool all)
00217 {
00218     // 1. Decide if there are enough spills in a range, o.w. return
00219     // 2. Write them to DBI
00220     // 3. Remove from list
00221     // 4. Call recursively
00222 
00223     size_t nspills = fSpills.size();
00224 
00225     if (!nspills) {
00226         MSG("BDD",Msg::kDebug) << "no spills to send to DB\n";
00227         return;
00228     }
00229 
00230     // Not yet collected enough spills to even consider being full and
00231     // haven't been asked to unconditionally write everything.
00232     if (!all && nspills < fSpillsPerWrite) {
00233         MSG("BDD",Msg::kVerbose)
00234             << "dump all not requested and not enough spills ("
00235             << nspills << " < " << fSpillsPerWrite << endl;
00236         return;
00237     }
00238 
00239     if (nspills > fSpillsPerWrite) nspills = fSpillsPerWrite;
00240 
00241     // Find the spill that is just outside of one spill block length
00242     // away from the first spill.
00243     deque<BeamMonSpill*>::iterator it1=fSpills.begin();
00244     deque<BeamMonSpill*>::iterator done = it1 + nspills;
00245     deque<BeamMonSpill*>::iterator it2 = done;
00246     --it2;
00247     
00248     // Initial vld range includes a padding around the first/last spills
00249     VldTimeStamp beg = (*it1)->SpillTime();
00250     VldTimeStamp end = (*it2)->SpillTime();
00251 
00252     // truncate to integral seconds (DBI does it anyways)
00253     beg = VldTimeStamp(beg.GetSec());
00254     // add 1 second to catch last spill
00255     end = VldTimeStamp(end.GetSec()+1);
00256 
00257     VldRange range(Detector::kNear|Detector::kFar,SimFlag::kData,
00258                    beg,end,"Beam");
00259     VldTimeStamp now;
00260     DbiWriter<BeamMonSpill> writer(range,-1,0,now);
00261     
00262     size_t count = 0;
00263     for (deque<BeamMonSpill*>::iterator it=it1; it != done; ++it) {
00264         writer << **it;
00265         delete *it;
00266         ++count;
00267     }
00268 
00269     MSG("BDD",Msg::kDebug) << " wrote " << count
00270                           <<" for range: " << range << endl;
00271 
00272 
00273     ++it2;
00274     fSpills.erase(it1,it2);
00275 
00276     writer.Close();
00277 
00278     // iterate if necessary.
00279     this->DBU(all);
00280 }

Generated on Sat Nov 21 22:45:34 2009 for loon by  doxygen 1.3.9.1