00001 #include <vector>
00002 #include <string>
00003
00004 #include "DataFormats/HcalDetId/interface/HcalGenericDetId.h"
00005 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00006 #include "DataFormats/HcalDetId/interface/HcalCastorDetId.h"
00007 #include "DataFormats/HcalDetId/interface/CastorElectronicsId.h"
00008 #include "CalibFormats/CastorObjects/interface/CastorText2DetIdConverter.h"
00009
00010 #include "CondFormats/CastorObjects/interface/AllObjects.h"
00011 #include "CalibCalorimetry/CastorCalib/interface/CastorDbASCIIIO.h"
00012 #include "FWCore/Utilities/interface/Exception.h"
00013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00014
00015 namespace {
00016 class DetIdLess {
00017 public:
00018 bool operator () (DetId fFirst, DetId fSecond) const {
00019 HcalGenericDetId first (fFirst);
00020 HcalGenericDetId second (fSecond);
00021 if (first.genericSubdet () != second.genericSubdet ()) return first.genericSubdet () < second.genericSubdet ();
00022 if (first.isHcalDetId ()) {
00023 HcalDetId f1 (first);
00024 HcalDetId s1 (second);
00025 return f1.zside () != s1.zside () ? f1.zside () < s1.zside () :
00026 f1.iphi () != s1.iphi () ? f1.iphi () < s1.iphi () :
00027 f1.ietaAbs () != s1.ietaAbs () ? f1.ietaAbs () < s1.ietaAbs () :
00028 f1.depth () < s1.depth ();
00029 }
00030 else {
00031 return first.rawId() < second.rawId();
00032 }
00033 }
00034 };
00035 class CastorElectronicsIdLess {
00036 public:
00037 bool operator () (CastorElectronicsId first, CastorElectronicsId second) const {
00038 return
00039 first.readoutVMECrateId () != second.readoutVMECrateId () ? first.readoutVMECrateId () < second.readoutVMECrateId () :
00040 first.htrSlot () != second.htrSlot () ? first.htrSlot () < second.htrSlot () :
00041 first.htrTopBottom () != second.htrTopBottom () ? first.htrTopBottom () < second.htrTopBottom () :
00042 first.fiberIndex () != second.fiberIndex () ? first.fiberIndex () < second.fiberIndex () :
00043 first.fiberChanId () < second.fiberChanId ();
00044 }
00045 };
00046 }
00047
00048 std::vector <std::string> splitString (const std::string& fLine) {
00049 std::vector <std::string> result;
00050 int start = 0;
00051 bool empty = true;
00052 for (unsigned i = 0; i <= fLine.size (); i++) {
00053 if (fLine [i] == ' ' || i == fLine.size ()) {
00054 if (!empty) {
00055 std::string item (fLine, start, i-start);
00056 result.push_back (item);
00057 empty = true;
00058 }
00059 start = i+1;
00060 }
00061 else {
00062 if (empty) empty = false;
00063 }
00064 }
00065 return result;
00066 }
00067
00068 DetId getId (const std::vector <std::string> & items) {
00069 CastorText2DetIdConverter converter (items [3], items [0], items [1], items [2]);
00070 return converter.getId ();
00071 }
00072
00073 void dumpId (std::ostream& fOutput, DetId id) {
00074 CastorText2DetIdConverter converter (id);
00075 char buffer [1024];
00076 sprintf (buffer, " %15s %15s %15s %15s",
00077 converter.getField1 ().c_str (), converter.getField2 ().c_str (), converter.getField3 ().c_str (),converter.getFlavor ().c_str ());
00078 fOutput << buffer;
00079 }
00080
00081 template <class T>
00082 bool getHcalObject (std::istream& fInput, T* fObject) {
00083 if (!fObject) fObject = new T;
00084 char buffer [1024];
00085 while (fInput.getline(buffer, 1024)) {
00086 if (buffer [0] == '#') continue;
00087 std::vector <std::string> items = splitString (std::string (buffer));
00088 if (items.size()==0) continue;
00089 if (items.size () < 8) {
00090 edm::LogWarning("Format Error") << "Bad line: " << buffer << "\n line must contain 8 items: eta, phi, depth, subdet, 4x values" << std::endl;
00091 continue;
00092 }
00093 DetId id = getId (items);
00094 fObject->sort ();
00095 try {
00096 fObject->getValues (id);
00097 edm::LogWarning("Redefining Channel") << "line: " << buffer << "\n attempts to redefine data. Ignored" << std::endl;
00098 }
00099 catch (cms::Exception& e) {
00100 fObject->addValue (id,
00101 atof (items [4].c_str()), atof (items [5].c_str()),
00102 atof (items [6].c_str()), atof (items [7].c_str()));
00103 }
00104 }
00105 fObject->sort ();
00106 return true;
00107 }
00108
00109 template <class T>
00110 bool dumpHcalObject (std::ostream& fOutput, const T& fObject) {
00111 char buffer [1024];
00112 sprintf (buffer, "# %15s %15s %15s %15s %8s %8s %8s %8s %10s\n", "eta", "phi", "dep", "det", "cap0", "cap1", "cap2", "cap3", "DetId");
00113 fOutput << buffer;
00114 std::vector<DetId> channels = fObject.getAllChannels ();
00115 std::sort (channels.begin(), channels.end(), DetIdLess ());
00116 for (std::vector<DetId>::iterator channel = channels.begin ();
00117 channel != channels.end ();
00118 channel++) {
00119 const float* values = fObject.getValues (*channel)->getValues ();
00120 if (values) {
00121 dumpId (fOutput, *channel);
00122 sprintf (buffer, " %8.5f %8.5f %8.5f %8.5f %10X\n",
00123 values[0], values[1], values[2], values[3], channel->rawId ());
00124 fOutput << buffer;
00125 }
00126 }
00127 return true;
00128 }
00129
00130
00131 bool CastorDbASCIIIO::getObject (std::istream& fInput, CastorPedestals* fObject) {return getHcalObject (fInput, fObject);}
00132 bool CastorDbASCIIIO::dumpObject (std::ostream& fOutput, const CastorPedestals& fObject) {return dumpHcalObject (fOutput, fObject);}
00133 bool CastorDbASCIIIO::getObject (std::istream& fInput, CastorGains* fObject) {return getHcalObject (fInput, fObject);}
00134 bool CastorDbASCIIIO::dumpObject (std::ostream& fOutput, const CastorGains& fObject) {return dumpHcalObject (fOutput, fObject);}
00135 bool CastorDbASCIIIO::getObject (std::istream& fInput, CastorGainWidths* fObject) {return getHcalObject (fInput, fObject);}
00136 bool CastorDbASCIIIO::dumpObject (std::ostream& fOutput, const CastorGainWidths& fObject) {return dumpHcalObject (fOutput, fObject);}
00137
00138 bool CastorDbASCIIIO::getObject (std::istream& fInput, CastorPedestalWidths* fObject) {
00139 if (!fObject) fObject = new CastorPedestalWidths;
00140 char buffer [1024];
00141 while (fInput.getline(buffer, 1024)) {
00142 if (buffer [0] == '#') continue;
00143 std::vector <std::string> items = splitString (std::string (buffer));
00144 if (items.size () < 14) {
00145 edm::LogWarning("Format Error") << "Bad line: " << buffer << "\n line must contain 14 items: eta, phi, depth, subdet, 10x correlations" << std::endl;
00146 continue;
00147 }
00148 DetId id = getId (items);
00149 fObject->sort ();
00150 try {
00151 fObject->getValues (id);
00152 edm::LogWarning("Redefining Channel") << "line: " << buffer << "\n attempts to redefine data. Ignored" << std::endl;
00153 }
00154 catch (cms::Exception& e) {
00155 CastorPedestalWidth* values = fObject->setWidth (id);
00156 values->setSigma (0, 0, atof (items [4].c_str()));
00157 values->setSigma (1, 0, atof (items [5].c_str()));
00158 values->setSigma (1, 1, atof (items [6].c_str()));
00159 values->setSigma (2, 0, atof (items [7].c_str()));
00160 values->setSigma (2, 1, atof (items [8].c_str()));
00161 values->setSigma (2, 2, atof (items [9].c_str()));
00162 values->setSigma (3, 0, atof (items [10].c_str()));
00163 values->setSigma (3, 1, atof (items [11].c_str()));
00164 values->setSigma (3, 2, atof (items [12].c_str()));
00165 values->setSigma (3, 3, atof (items [13].c_str()));
00166 }
00167 }
00168 fObject->sort ();
00169 return true;
00170 }
00171
00172 bool CastorDbASCIIIO::dumpObject (std::ostream& fOutput, const CastorPedestalWidths& fObject) {
00173 char buffer [1024];
00174 sprintf (buffer, "# %15s %15s %15s %15s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %10s\n",
00175 "eta", "phi", "dep", "det",
00176 "sig_0_o", "sig_1_0", "sig_1_1", "sig_2_0", "sig_2_1", "sig_2_2", "sig_3_0", "sig_3_1", "sig_3_2", "sig_3_3",
00177 "DetId");
00178 fOutput << buffer;
00179 std::vector<DetId> channels = fObject.getAllChannels ();
00180 std::sort (channels.begin(), channels.end(), DetIdLess ());
00181 for (std::vector<DetId>::iterator channel = channels.begin ();
00182 channel != channels.end ();
00183 channel++) {
00184 const CastorPedestalWidth* item = fObject.getValues (*channel);
00185 if (item) {
00186 dumpId (fOutput, *channel);
00187 sprintf (buffer, " %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %8.5f %10X\n",
00188 item->getSigma (0,0), item->getSigma (1,0), item->getSigma (1,1), item->getSigma (2,0), item->getSigma (2,1), item->getSigma (2,2),
00189 item->getSigma (3,0), item->getSigma (3,1), item->getSigma (3,2), item->getSigma (3,3), channel->rawId ());
00190 fOutput << buffer;
00191 }
00192 }
00193 return true;
00194 }
00195
00196 bool CastorDbASCIIIO::getObject (std::istream& fInput, CastorQIEData* fObject) {
00197 char buffer [1024];
00198 while (fInput.getline(buffer, 1024)) {
00199 if (buffer [0] == '#') continue;
00200 std::vector <std::string> items = splitString (std::string (buffer));
00201 if (items.size()<1) continue;
00202 if (items [0] == "SHAPE") {
00203 if (items.size () < 33) {
00204 edm::LogWarning("Format Error") << "Bad line: " << buffer << "\n line must contain 33 items: SHAPE 32 x low QIE edges for first 32 bins" << std::endl;
00205 continue;
00206 }
00207 float lowEdges [32];
00208 int i = 32;
00209 while (--i >= 0) lowEdges [i] = atof (items [i+1].c_str ());
00210
00211 }
00212 else {
00213 if (items.size () < 36) {
00214 edm::LogWarning("Format Error") << "Bad line: " << buffer << "\n line must contain 36 items: eta, phi, depth, subdet, 4 capId x 4 Ranges x offsets, 4 capId x 4 Ranges x slopes" << std::endl;
00215 continue;
00216 }
00217 DetId id = getId (items);
00218 fObject->sort ();
00219 try {
00220 fObject->getCoder (id);
00221 edm::LogWarning("Redefining Channel") << "line: " << buffer << "\n attempts to redefine data. Ignored" << std::endl;
00222 }
00223 catch (cms::Exception& e) {
00224 CastorQIECoder coder (id.rawId ());
00225 int index = 4;
00226 for (unsigned capid = 0; capid < 4; capid++) {
00227 for (unsigned range = 0; range < 4; range++) {
00228 coder.setOffset (capid, range, atof (items [index++].c_str ()));
00229 }
00230 }
00231 for (unsigned capid = 0; capid < 4; capid++) {
00232 for (unsigned range = 0; range < 4; range++) {
00233 coder.setSlope (capid, range, atof (items [index++].c_str ()));
00234 }
00235 }
00236 fObject->addCoder (id, coder);
00237 }
00238 }
00239 }
00240 fObject->sort ();
00241 return true;
00242 }
00243
00244 bool CastorDbASCIIIO::dumpObject (std::ostream& fOutput, const CastorQIEData& fObject) {
00245 char buffer [1024];
00246 fOutput << "# QIE basic shape: SHAPE 32 x low edge values for first 32 channels" << std::endl;
00247 sprintf (buffer, "SHAPE ");
00248 fOutput << buffer;
00249 for (unsigned bin = 0; bin < 32; bin++) {
00250 sprintf (buffer, " %8.5f", fObject.getShape ().lowEdge (bin));
00251 fOutput << buffer;
00252 }
00253 fOutput << std::endl;
00254
00255 fOutput << "# QIE data" << std::endl;
00256 sprintf (buffer, "# %15s %15s %15s %15s %36s %36s %36s %36s %36s %36s %36s %36s\n",
00257 "eta", "phi", "dep", "det",
00258 "4 x offsets cap0", "4 x offsets cap1", "4 x offsets cap2", "4 x offsets cap3",
00259 "4 x slopes cap0", "4 x slopes cap1", "4 x slopes cap2", "4 x slopes cap3");
00260 fOutput << buffer;
00261 std::vector<DetId> channels = fObject.getAllChannels ();
00262 std::sort (channels.begin(), channels.end(), DetIdLess ());
00263 for (std::vector<DetId>::iterator channel = channels.begin ();
00264 channel != channels.end ();
00265 channel++) {
00266 const CastorQIECoder* coder = fObject.getCoder (*channel);
00267 dumpId (fOutput, *channel);
00268 for (unsigned capid = 0; capid < 4; capid++) {
00269 for (unsigned range = 0; range < 4; range++) {
00270 sprintf (buffer, " %8.5f", coder->offset (capid, range));
00271 fOutput << buffer;
00272 }
00273 }
00274 for (unsigned capid = 0; capid < 4; capid++) {
00275 for (unsigned range = 0; range < 4; range++) {
00276 sprintf (buffer, " %8.5f", coder->slope (capid, range));
00277 fOutput << buffer;
00278 }
00279 }
00280 fOutput << std::endl;
00281 }
00282 return true;
00283 }
00284
00285 bool CastorDbASCIIIO::getObject (std::istream& fInput, CastorCalibrationQIEData* fObject) {
00286 char buffer [1024];
00287 while (fInput.getline(buffer, 1024)) {
00288 if (buffer [0] == '#') continue;
00289 std::vector <std::string> items = splitString (std::string (buffer));
00290 if (items.size () < 36) {
00291 edm::LogWarning("Format Error") << "Bad line: " << buffer << "\n line must contain 36 items: eta, phi, depth, subdet, 32 bin values" << std::endl;
00292 continue;
00293 }
00294 DetId id = getId (items);
00295 fObject->sort ();
00296 try {
00297 fObject->getCoder (id);
00298 edm::LogWarning("Redefining Channel") << "line: " << buffer << "\n attempts to redefine data. Ignored" << std::endl;
00299 }
00300 catch (cms::Exception& e) {
00301 CastorCalibrationQIECoder coder (id.rawId ());
00302 int index = 4;
00303 float values [32];
00304 for (unsigned bin = 0; bin < 32; bin++) {
00305 values[bin] = atof (items [index++].c_str ());
00306 }
00307 coder.setMinCharges (values);
00308 fObject->addCoder (id, coder);
00309 }
00310 }
00311 fObject->sort ();
00312 return true;
00313 }
00314
00315 bool CastorDbASCIIIO::dumpObject (std::ostream& fOutput, const CastorCalibrationQIEData& fObject) {
00316 char buffer [1024];
00317 fOutput << "# QIE data in calibration mode" << std::endl;
00318 sprintf (buffer, "# %15s %15s %15s %15s %288s\n",
00319 "eta", "phi", "dep", "det", "32 x charges");
00320 fOutput << buffer;
00321 std::vector<DetId> channels = fObject.getAllChannels ();
00322 std::sort (channels.begin(), channels.end(), DetIdLess ());
00323 for (std::vector<DetId>::iterator channel = channels.begin ();
00324 channel != channels.end ();
00325 channel++) {
00326 const CastorCalibrationQIECoder* coder = fObject.getCoder (*channel);
00327 if (coder) {
00328 dumpId (fOutput, *channel);
00329 const float* lowEdge = coder->minCharges ();
00330 for (unsigned bin = 0; bin < 32; bin++) {
00331 sprintf (buffer, " %8.5f", lowEdge [bin]);
00332 fOutput << buffer;
00333 }
00334 fOutput << std::endl;
00335 }
00336 }
00337 return true;
00338 }
00339
00340 bool CastorDbASCIIIO::getObject (std::istream& fInput, CastorChannelQuality* fObject) {
00341 char buffer [1024];
00342 while (fInput.getline(buffer, 1024)) {
00343 if (buffer [0] == '#') continue;
00344 std::vector <std::string> items = splitString (std::string (buffer));
00345 if (items.size () < 5) {
00346 edm::LogWarning("Format Error") << "Bad line: " << buffer << "\n line must contain 5 items: eta, phi, depth, subdet, GOOD/BAD/HOT/DEAD" << std::endl;
00347 continue;
00348 }
00349 CastorChannelQuality::Quality value (CastorChannelQuality::UNKNOWN);
00350 for (int i = 0; i < (int) CastorChannelQuality::END; i++) {
00351 if (items [4] == std::string (CastorChannelQuality::str ((CastorChannelQuality::Quality) i))) {
00352 value = (CastorChannelQuality::Quality) i;
00353 }
00354 }
00355 fObject->setChannel (getId (items).rawId (), value);
00356 }
00357 fObject->sort ();
00358 return true;
00359 }
00360
00361 bool CastorDbASCIIIO::dumpObject (std::ostream& fOutput, const CastorChannelQuality& fObject) {
00362 char buffer [1024];
00363 sprintf (buffer, "# %15s %15s %15s %15s %8s\n",
00364 "eta", "phi", "dep", "det",
00365 "quality");
00366 fOutput << buffer;
00367 std::vector<unsigned long> channels = fObject.getAllChannels ();
00368 for (std::vector<unsigned long>::iterator channel = channels.begin ();
00369 channel != channels.end ();
00370 channel++) {
00371 DetId id ((uint32_t) *channel);
00372 dumpId (fOutput, id);
00373 sprintf (buffer, " %8s\n", CastorChannelQuality::str (fObject.quality (*channel)));
00374 }
00375 return true;
00376 }
00377
00378 bool CastorDbASCIIIO::getObject (std::istream& fInput, CastorElectronicsMap* fObject) {
00379 char buffer [1024];
00380 while (fInput.getline(buffer, 1024)) {
00381 if (buffer [0] == '#') continue;
00382 std::vector <std::string> items = splitString (std::string (buffer));
00383 if (items.size () < 12) {
00384 if (items.size()==0) continue;
00385 if (items.size()<9) {
00386 edm::LogError("MapFormat") << "CastorElectronicsMap-> line too short: " << buffer;
00387 continue;
00388 }
00389 if (items[8]=="NA" || items[8]=="NT") {
00390 while (items.size()<12) items.push_back("");
00391 } else if (items[8]=="HT") {
00392 if (items.size()==11) items.push_back("");
00393 else {
00394 edm::LogError("MapFormat") << "CastorElectronicsMap-> Bad line: " << buffer
00395 << "\n HT line must contain at least 11 items: i cr sl tb dcc spigot fiber fiberchan subdet=HT ieta iphi";
00396 continue;
00397 }
00398 } else {
00399 edm::LogError("MapFormat") << "CastorElectronicsMap-> Bad line: " << buffer
00400 << "\n line must contain 12 items: i cr sl tb dcc spigot fiber fiberchan subdet ieta iphi depth";
00401 continue;
00402 }
00403 }
00404
00405 int crate = atoi (items [1].c_str());
00406 int slot = atoi (items [2].c_str());
00407 int top = 1;
00408 if (items [3] == "b") top = 0;
00409 int dcc = atoi (items [4].c_str());
00410 int spigot = atoi (items [5].c_str());
00411 CastorElectronicsId elId;
00412 if (items[8] == "HT" || items[8] == "NT") {
00413 int slb = atoi (items [6].c_str());
00414 int slbCh = atoi (items [7].c_str());
00415 elId=CastorElectronicsId(slbCh, slb, spigot, dcc,crate,slot,top);
00416 } else {
00417 int fiber = atoi (items [6].c_str());
00418 int fiberCh = atoi (items [7].c_str());
00419
00420 elId=CastorElectronicsId(fiberCh, fiber, spigot, dcc);
00421 elId.setHTR (crate, slot, top);
00422 }
00423
00424
00425 if (items [8] == "NA") {
00426 fObject->mapEId2chId (elId, DetId (HcalDetId::Undefined));
00427 } else if (items [8] == "NT") {
00428 fObject->mapEId2tId (elId, DetId (HcalTrigTowerDetId::Undefined));
00429 } else {
00430 CastorText2DetIdConverter converter (items [8], items [9], items [10], items [11]);
00431 if (converter.isHcalCastorDetId ()) {
00432 fObject->mapEId2chId (elId, converter.getId ());
00433 }
00434 else {
00435 edm::LogWarning("Format Error") << "CastorElectronicsMap-> Unknown subdetector: "
00436 << items [8] << '/' << items [9] << '/' << items [10] << '/' << items [11] << std::endl;
00437 }
00438 }
00439 }
00440 fObject->sort ();
00441 return true;
00442 }
00443
00444 bool CastorDbASCIIIO::dumpObject (std::ostream& fOutput, const CastorElectronicsMap& fObject) {
00445 std::vector<CastorElectronicsId> eids = fObject.allElectronicsId ();
00446 char buf [1024];
00447 sprintf (buf, "#%6s %6s %6s %6s %6s %6s %6s %6s %15s %15s %15s %15s",
00448 "i", "cr", "sl", "tb", "dcc", "spigot", "fiber/slb", "fibcha/slbcha", "subdet", "ieta", "iphi", "depth");
00449 fOutput << buf << std::endl;
00450
00451 for (unsigned i = 0; i < eids.size (); i++) {
00452 CastorElectronicsId eid = eids[i];
00453 if (eid.isTriggerChainId()) {
00454 DetId trigger = fObject.lookupTrigger (eid);
00455 if (trigger.rawId ()) {
00456 CastorText2DetIdConverter converter (trigger);
00457 sprintf (buf, " %6d %6d %6d %6c %6d %6d %6d %6d %15s %15s %15s %15s",
00458 i,
00459 eid.readoutVMECrateId(), eid.htrSlot(), eid.htrTopBottom()>0?'t':'b', eid.dccid(), eid.spigot(), eid.fiberIndex(), eid.fiberChanId(),
00460 converter.getFlavor ().c_str (), converter.getField1 ().c_str (), converter.getField2 ().c_str (), converter.getField3 ().c_str ()
00461 );
00462 fOutput << buf << std::endl;
00463 }
00464 } else {
00465 DetId channel = fObject.lookup (eid);
00466 if (channel.rawId()) {
00467 CastorText2DetIdConverter converter (channel);
00468 sprintf (buf, " %6d %6d %6d %6c %6d %6d %6d %6d %15s %15s %15s %15s",
00469 i,
00470 eid.readoutVMECrateId(), eid.htrSlot(), eid.htrTopBottom()>0?'t':'b', eid.dccid(), eid.spigot(), eid.fiberIndex(), eid.fiberChanId(),
00471 converter.getFlavor ().c_str (), converter.getField1 ().c_str (), converter.getField2 ().c_str (), converter.getField3 ().c_str ()
00472 );
00473 fOutput << buf << std::endl;
00474 }
00475 }
00476 }
00477 return true;
00478 }