00001 #include <algorithm>
00002
00003 #include "BDSwicCalibrator.h"
00004 #include "BDSwicDevice.h"
00005
00006 #include <Conventions/Munits.h>
00007 #include <RawData/RawBeamMonHeaderBlock.h>
00008 #include <RawData/RawBeamMonBlock.h>
00009
00010 #include <MessageService/MsgService.h>
00011 CVSID("$Id: BDSwicCalibrator.cxx,v 1.13 2009/02/28 21:46:11 gmieg Exp $");
00012
00013
00014 static const float max_profile_pedestal_rms = 15.0;
00015
00016 BDSwicCalibrator* BDSwicCalibrator::fInstance = 0;
00017
00018 BDSwicCalibrator& BDSwicCalibrator::Get()
00019 {
00020 if (!fInstance) fInstance = new BDSwicCalibrator;
00021 return *fInstance;
00022 }
00023
00024 BDSwicCalibrator::BDSwicCalibrator()
00025 : fPeds(), fMask()
00026 {
00027 }
00028
00029 BDSwicCalibrator::~BDSwicCalibrator()
00030 {
00031 }
00032
00033 void BDSwicCalibrator::Calibrate(const RawBeamMonHeaderBlock& rbmhb,
00034 const RawBeamMonBlock& rbmb)
00035 {
00036 VldContext vc = rbmhb.GetVldContext();
00037 bool new_peds = fPeds.SetSpillTime(vc);
00038 bool new_mask = fMask.SetSpillTime(vc);
00039
00040 if (! (new_peds || new_mask)) return;
00041
00042 DevList::iterator it, done = fDevList.end();
00043 for (it=fDevList.begin(); it != done; ++it) {
00044 this->CalibrateOne(rbmhb,rbmb,**it);
00045 }
00046 }
00047
00048 void BDSwicCalibrator::CalibrateOne(const RawBeamMonHeaderBlock& ,
00049 const RawBeamMonBlock& rbmb,
00050 BDSwicDevice& sd)
00051 {
00052 if (!sd.IsValid()) {
00053 MSG("BD",Msg::kDebug)
00054 << "BDSwicCalibrator: given invalid SWIC data\n";
00055 return;
00056 }
00057
00058 string name = sd.GetData().GetName();
00059 MSG("BDU",Msg::kVerbose)
00060 << "BDSwicCalibrator: calibrating " << name << endl;
00061
00062
00063 vector<double> mean(96,0), sigma(96,0);
00064 int ok = fPeds.GetPeds(name.c_str(),mean,sigma);
00065 if (!ok) {
00066 MSG("BD",Msg::kDebug) << "BDSwicCalibrator:: no peds for: "
00067 << name << endl;
00068 }
00069
00070
00071 vector<double> mask = fMask.GetMask(name.c_str());
00072 if (!mask.size()) {
00073 MSG("BD",Msg::kWarning) << "BDSwicCalibrator:: no mask for: "
00074 << name << endl;
00075 mask = vector<double>(96,1);
00076 }
00077
00078
00079 BDSwicDevice::MonitorType monitor_type = sd.GetMonitorType();
00080 if (monitor_type == BDSwicDevice::kProfile) {
00081 for (int ind=0; ind<96; ++ind)
00082 if (sigma[ind] > max_profile_pedestal_rms) mask[ind] = 0.0;
00083 }
00084
00085 switch (monitor_type) {
00086 case BDSwicDevice::kMuon:
00087 sd.SetCapacitance(1.0e2*Munits::picofarad);
00088 break;
00089 case BDSwicDevice::kProfile:
00090 case BDSwicDevice::kHadron:
00091 case BDSwicDevice::kUnknown:
00092 default:
00093 sd.SetCapacitance(1.0e5*Munits::picofarad);
00094 break;
00095 }
00096
00097 sd.SetPeds(mean);
00098 sd.SetNoise(sigma);
00099 sd.SetMask(mask);
00100
00101
00102 BDSwicDevice::MonitorType type = sd.GetMonitorType();
00103 if (! (type == BDSwicDevice::kHadron || type == BDSwicDevice::kMuon)) return;
00104
00105
00106
00107
00108
00109
00110 string tname="", pname="";
00111 if (name == "E:HADMDS") {
00112
00113 tname = "E:HMRTD";
00114
00115 pname = "E:HMGPR";
00116 }
00117 else if (name == "E:MMA1DS") {
00118
00119 tname = "E:MM1RTD";
00120
00121 pname = "E:MM1GPR";
00122 }
00123 else if (name == "E:MMA2DS") {
00124
00125 tname = "E:MM2RTD";
00126
00127 pname = "E:MM2GPR";
00128 }
00129 else if (name == "E:MMA3DS") {
00130
00131 tname = "E:MM3RTD";
00132
00133 pname = "E:MM3GPR";
00134 }
00135 else {
00136 MSG("BD",Msg::kWarning)
00137 << "Unknown had/mu monitor: " << name
00138 << " no temp/pressure correction done\n";
00139 return;
00140 }
00141
00142 const RawBeamData* rbd_temp = rbmb[tname.c_str()];
00143 const RawBeamData* rbd_pres = rbmb[pname.c_str()];
00144
00145 if (!rbd_temp || !rbd_pres ||
00146 !rbd_temp->GetDataLength() || !rbd_pres->GetDataLength()) {
00147 MSG("BD",Msg::kWarning)
00148 << "Could not get temp/pres devices for "
00149 << name << " no temp/pressure correction done\n";
00150 return;
00151 }
00152
00153 const double temp = Munits::ToCelcius(Munits::FromFahrenheit(rbd_temp->GetData()[0]));
00154 const double pres = rbd_pres->GetData()[0];
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 const double pressure_nominal = 756;
00167 const double temperature_nominal = 20;
00168
00169 #if 0
00170 const double pressure_factor = 0.00078;
00171 const double temperature_factor = 0.00135;
00172 #else // Dharma:
00173 const double pressure_factor = 0.0013;
00174 const double temperature_factor = 0.0034;
00175 #endif
00176
00177 double tp_scale =
00178 (1.0+pressure_factor *(pres - pressure_nominal)) *
00179 (1.0+temperature_factor*(temp - temperature_nominal));
00180
00181 sd.SetGainCorrection(tp_scale);
00182
00183
00184
00185
00186 }
00187
00188 bool BDSwicCalibrator::AddDevice(BDSwicDevice& dev)
00189 {
00190
00191 if (!dev.IsValid()) {
00192 MSG("BD",Msg::kWarning)
00193 << "Not adding invalid device\n";
00194 return false;
00195 }
00196
00197 const char* device_name = dev.GetData().GetName().c_str();
00198
00199
00200 if (find(fDevList.begin(),fDevList.end(),&dev) != fDevList.end()) {
00201 return true;
00202 }
00203
00204 fPeds.AddDevice(device_name);
00205 fMask.AddDevice(device_name);
00206
00207
00208 fDevList.push_back(&dev);
00209
00210 return true;
00211 }
00212
00213 void BDSwicCalibrator::RemoveDevice(BDSwicDevice& dev)
00214 {
00215 fDevList.remove(&dev);
00216 }