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
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
00073
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
00082
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
00095
00096
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& ,
00109 const RawBeamMonBlock& rbmb)
00110 {
00111 BeamMonSpill* spill = new BeamMonSpill;
00112 BeamMonSpill::StatusBits bits = spill->GetStatusBits();
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
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
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
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
00219
00220
00221
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
00231
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
00242
00243 deque<BeamMonSpill*>::iterator it1=fSpills.begin();
00244 deque<BeamMonSpill*>::iterator done = it1 + nspills;
00245 deque<BeamMonSpill*>::iterator it2 = done;
00246 --it2;
00247
00248
00249 VldTimeStamp beg = (*it1)->SpillTime();
00250 VldTimeStamp end = (*it2)->SpillTime();
00251
00252
00253 beg = VldTimeStamp(beg.GetSec());
00254
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
00279 this->DBU(all);
00280 }