00001
00009 #include "DataFormats/Streamer/interface/StreamedProducts.h"
00010 #include "EventFilter/StorageManager/interface/InitMsgCollection.h"
00011 #include "FWCore/Framework/interface/EventSelector.h"
00012 #include "FWCore/Utilities/interface/DebugMacros.h"
00013 #include "FWCore/Utilities/interface/Exception.h"
00014 #include "IOPool/Streamer/interface/DumpTools.h"
00015 #include "IOPool/Streamer/interface/OtherMessage.h"
00016 #include "IOPool/Streamer/interface/StreamerInputSource.h"
00017 #include "IOPool/Streamer/interface/Utilities.h"
00018
00019 #include "boost/algorithm/string/trim.hpp"
00020 #include <iostream>
00021
00022 using namespace stor;
00023 using namespace edm;
00024
00028 InitMsgCollection::InitMsgCollection()
00029 {
00030 FDEBUG(5) << "Executing constructor for InitMsgCollection" << std::endl;
00031 initMsgList_.clear();
00032 outModNameTable_.clear();
00033
00034 serializedFullSet_.reset(new InitMsgBuffer(2 * sizeof(Header)));
00035 OtherMessageBuilder fullSetMsg(&(*serializedFullSet_)[0], Header::INIT_SET);
00036 }
00037
00041 InitMsgCollection::~InitMsgCollection()
00042 {
00043 FDEBUG(5) << "Executing destructor for InitMsgCollection" << std::endl;
00044 }
00045
00046 #if 0
00047
00048
00049
00050
00051
00052
00053
00054 bool testAndAddIfUnique(InitMsgView const& initMsgView);
00055 InitMsgSharedPtr getElementForSelection(Strings const& triggerSelection);
00056
00075 bool InitMsgCollection::testAndAddIfUnique(InitMsgView const& initMsgView)
00076 {
00077 boost::mutex::scoped_lock sl(listLock_);
00078
00079
00080 bool addToList = true;
00081
00082
00083 std::string inputOMLabel = initMsgView.outputModuleLabel();
00084 Strings inputTriggerList;
00085 initMsgView.hltTriggerNames(inputTriggerList);
00086 if (inputTriggerList.size() == 0) {
00087 addToList = false;
00088 throw cms::Exception("InitMsgCollection", "testAndAddIfUnique:")
00089 << "The full trigger list specified for the \"" << inputOMLabel
00090 << "\" output module is empty!" << std::endl;
00091 }
00092
00093
00094
00095 Strings inputSelectionList;
00096 initMsgView.hltTriggerSelections(inputSelectionList);
00097 if (! EventSelector::selectionIsValid(inputSelectionList,
00098 inputTriggerList)) {
00099 addToList = false;
00100 throw cms::Exception("InitMsgCollection", "testAndAddIfUnique:")
00101 << "The trigger selection specified for the \"" << inputOMLabel
00102 << "\" output module is not valid for the full trigger list!"
00103 << std::endl;
00104 }
00105
00106
00107 if (initMsgList_.size() == 0) {
00108 this->add(initMsgView);
00109 }
00110
00111
00112 else {
00113
00114
00115 std::vector<InitMsgSharedPtr>::const_iterator msgIter;
00116 for (msgIter = initMsgList_.begin(); msgIter != initMsgList_.end(); msgIter++) {
00117 InitMsgSharedPtr serializedProds = *msgIter;
00118 InitMsgView existingInitMsg(&(*serializedProds)[0]);
00119 std::string existingOMLabel = existingInitMsg.outputModuleLabel();
00120
00121
00122
00123
00124
00125
00126
00127 Strings existingTriggerList;
00128 existingInitMsg.hltTriggerNames(existingTriggerList);
00129 if (inputTriggerList != existingTriggerList) {
00130 addToList = false;
00131 throw cms::Exception("InitMsgCollection", "testAndAddIfUnique:")
00132 << "INIT messages from the \"" << inputOMLabel << "\" and \""
00133 << existingOMLabel << "\" output modules have "
00134 << "different HLT full trigger lists!" << std::endl;
00135 }
00136
00137
00138 Strings existingSelectionList;
00139 existingInitMsg.hltTriggerSelections(existingSelectionList);
00140
00141
00142 if (inputOMLabel == existingOMLabel) {
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 if (EventSelector::testSelectionOverlap(inputSelectionList,
00154 existingSelectionList,
00155 existingTriggerList) !=
00156 evtSel::ExactMatch) {
00157 addToList = false;
00158 throw cms::Exception("InitMsgCollection", "testAndAddIfUnique:")
00159 << "INIT messages from the \"" << inputOMLabel
00160 << "\" output module in different filter units have "
00161 << "different HLT trigger selections!" << std::endl;
00162 }
00163
00164
00165 std::auto_ptr<SendJobHeader> header =
00166 StreamerInputSource::deserializeRegistry(initMsgView);
00167 std::auto_ptr<SendJobHeader> refheader =
00168 StreamerInputSource::deserializeRegistry(existingInitMsg);
00169 if (! registryIsSubset(*header, *refheader) ||
00170 ! registryIsSubset(*refheader, *header)) {
00171 addToList = false;
00172 throw cms::Exception("InitMsgCollection", "testAndAddIfUnique:")
00173 << "INIT messages from the \"" << inputOMLabel
00174 << "\" output module in different filter units have "
00175 << "different product lists!" << std::endl;
00176 }
00177
00178
00179
00180
00181
00182
00183 addToList = false;
00184 return addToList;
00185 }
00186 else {
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 if (EventSelector::testSelectionOverlap(inputSelectionList,
00197 existingSelectionList,
00198 existingTriggerList) !=
00199 evtSel::NoOverlap) {
00200 addToList = false;
00201 throw cms::Exception("InitMsgCollection", "testAndAddIfUnique:")
00202 << "INIT messages from the \"" << inputOMLabel << "\" and \""
00203 << existingOMLabel << "\" output modules have "
00204 << "overlapping HLT trigger selections: ("
00205 << stringsToText(inputSelectionList, 10) << ") and ("
00206 << stringsToText(existingSelectionList, 10) << ")."
00207 << std::endl;
00208 }
00209 }
00210 }
00211
00212
00213 if (addToList) {
00214 this->add(initMsgView);
00215 }
00216 }
00217
00218
00219 return addToList;
00220 }
00221
00238 InitMsgSharedPtr
00239 InitMsgCollection::getElementForSelection(Strings const& triggerSelection)
00240 {
00241 boost::mutex::scoped_lock sl(listLock_);
00242
00243 InitMsgSharedPtr serializedProds;
00244 if (initMsgList_.size() > 0) {
00245
00246
00247 InitMsgSharedPtr workingMessage = initMsgList_[0];
00248 InitMsgView existingInitMsg(&(*workingMessage)[0]);
00249 Strings fullTriggerList;
00250 existingInitMsg.hltTriggerNames(fullTriggerList);
00251 if (! EventSelector::selectionIsValid(triggerSelection,
00252 fullTriggerList)) {
00253 std::string msg = "The specified trigger selection list (";
00254 msg.append(stringsToText(triggerSelection, 10));
00255 msg.append(") contains paths not in the full trigger list!");
00256 throw cms::Exception("InitMsgCollection", "getElementForSelection:")
00257 << msg << std::endl;
00258 }
00259
00260
00261 std::vector<InitMsgSharedPtr>::const_iterator msgIter;
00262 for (msgIter = initMsgList_.begin(); msgIter != initMsgList_.end(); msgIter++) {
00263 workingMessage = *msgIter;
00264 InitMsgView workingInitMsg(&(*workingMessage)[0]);
00265
00266 Strings workingSelectionList;
00267 workingInitMsg.hltTriggerSelections(workingSelectionList);
00268
00269 evtSel::OverlapResult overlapResult =
00270 EventSelector::testSelectionOverlap(triggerSelection,
00271 workingSelectionList,
00272 fullTriggerList);
00273 if (overlapResult == evtSel::ExactMatch ||
00274 overlapResult == evtSel::PartialOverlap) {
00275 if (serializedProds.get() == NULL) {
00276 serializedProds = workingMessage;
00277 }
00278 else {
00279 std::string msg = "The specified trigger selection list (";
00280 msg.append(stringsToText(triggerSelection, 10));
00281 msg.append(") matches triggers from more than one HLT output module!");
00282 throw cms::Exception("InitMsgCollection", "getElementForSelection:")
00283 << msg << std::endl;
00284 }
00285 }
00286 }
00287 }
00288
00289 return serializedProds;
00290 }
00291
00292 #endif
00293
00309 bool InitMsgCollection::addIfUnique(InitMsgView const& initMsgView)
00310 {
00311 boost::mutex::scoped_lock sl(listLock_);
00312
00313
00314 std::string inputOMLabel = initMsgView.outputModuleLabel();
00315 std::string trimmedOMLabel = boost::algorithm::trim_copy(inputOMLabel);
00316 if (trimmedOMLabel.empty()) {
00317 throw cms::Exception("InitMsgCollection", "addIfUnique:")
00318 << "Invalid INIT message: the HLT output module label is empty!"
00319 << std::endl;
00320 }
00321
00322
00323 bool addToList = true;
00324
00325
00326 if (initMsgList_.size() == 0) {
00327 this->add(initMsgView);
00328 }
00329
00330
00331 else {
00332
00333
00334 std::vector<InitMsgSharedPtr>::const_iterator msgIter;
00335 for (msgIter = initMsgList_.begin(); msgIter != initMsgList_.end(); msgIter++) {
00336 InitMsgSharedPtr serializedProds = *msgIter;
00337 InitMsgView existingInitMsg(&(*serializedProds)[0]);
00338 std::string existingOMLabel = existingInitMsg.outputModuleLabel();
00339
00340
00341 if (inputOMLabel == existingOMLabel) {
00342
00343 addToList = false;
00344 break;
00345 }
00346 }
00347
00348
00349 if (addToList) {
00350 this->add(initMsgView);
00351 }
00352 }
00353
00354
00355 return addToList;
00356 }
00357
00377 InitMsgSharedPtr
00378 InitMsgCollection::getElementForOutputModule(std::string requestedOMLabel)
00379 {
00380 boost::mutex::scoped_lock sl(listLock_);
00381 InitMsgSharedPtr serializedProds;
00382
00383
00384
00385
00386
00387 if (requestedOMLabel.empty()) {
00388 if (initMsgList_.size() == 1) {
00389 serializedProds = initMsgList_.back();
00390 }
00391 else if (initMsgList_.size() > 1) {
00392 std::string msg = "Invalid INIT message lookup: the requested ";
00393 msg.append("HLT output module label is empty but there are multiple ");
00394 msg.append("HLT output modules to choose from.");
00395 throw cms::Exception("InitMsgCollection", "getElementForOutputModule:")
00396 << msg << std::endl;
00397 }
00398 }
00399
00400 else {
00401
00402 std::vector<InitMsgSharedPtr>::const_iterator msgIter;
00403 for (msgIter = initMsgList_.begin(); msgIter != initMsgList_.end(); msgIter++) {
00404 InitMsgSharedPtr workingMessage = *msgIter;
00405 InitMsgView existingInitMsg(&(*workingMessage)[0]);
00406 std::string existingOMLabel = existingInitMsg.outputModuleLabel();
00407
00408
00409 if (requestedOMLabel == existingOMLabel) {
00410 serializedProds = workingMessage;
00411 break;
00412 }
00413 }
00414 }
00415
00416 return serializedProds;
00417 }
00418
00425 InitMsgSharedPtr InitMsgCollection::getLastElement()
00426 {
00427 boost::mutex::scoped_lock sl(listLock_);
00428
00429 InitMsgSharedPtr ptrToLast;
00430 if (initMsgList_.size() > 0) {
00431 ptrToLast = initMsgList_.back();
00432 }
00433 return ptrToLast;
00434 }
00435
00443 InitMsgSharedPtr InitMsgCollection::getElementAt(unsigned int index)
00444 {
00445 boost::mutex::scoped_lock sl(listLock_);
00446
00447 InitMsgSharedPtr ptrToElement;
00448 if (index >= 0 && index < initMsgList_.size()) {
00449 ptrToElement = initMsgList_[index];
00450 }
00451 return ptrToElement;
00452 }
00453
00457 void InitMsgCollection::clear()
00458 {
00459 boost::mutex::scoped_lock sl(listLock_);
00460 initMsgList_.clear();
00461 outModNameTable_.clear();
00462 }
00463
00469 int InitMsgCollection::size()
00470 {
00471 boost::mutex::scoped_lock sl(listLock_);
00472 return initMsgList_.size();
00473 }
00474
00480 std::string InitMsgCollection::getSelectionHelpString()
00481 {
00482
00483 if (initMsgList_.size() == 0) {
00484 return "No information is available about the available triggers.";
00485 }
00486
00487
00488 std::string helpString;
00489 helpString.append("The full list of trigger paths is the following:");
00490
00491
00492
00493 InitMsgSharedPtr serializedProds = initMsgList_[0];
00494 InitMsgView existingInitMsg(&(*serializedProds)[0]);
00495 Strings existingTriggerList;
00496 existingInitMsg.hltTriggerNames(existingTriggerList);
00497 for (unsigned int idx = 0; idx < existingTriggerList.size(); idx++) {
00498 helpString.append("\n " + existingTriggerList[idx]);
00499 }
00500
00501
00502 helpString.append("\nThe registered HLT output modules and their ");
00503 helpString.append("trigger selections are the following:");
00504
00505
00506 std::vector<InitMsgSharedPtr>::const_iterator msgIter;
00507 for (msgIter = initMsgList_.begin(); msgIter != initMsgList_.end(); msgIter++) {
00508 serializedProds = *msgIter;
00509 InitMsgView workingInitMsg(&(*serializedProds)[0]);
00510 helpString.append("\n *** Output module \"");
00511 helpString.append(workingInitMsg.outputModuleLabel());
00512 helpString.append("\" ***");
00513 Strings workingSelectionList;
00514 workingInitMsg.hltTriggerSelections(workingSelectionList);
00515 for (unsigned int idx = 0; idx < workingSelectionList.size(); idx++) {
00516 helpString.append("\n " + workingSelectionList[idx]);
00517 }
00518 }
00519
00520
00521 return helpString;
00522 }
00523
00530 std::string InitMsgCollection::getOutputModuleName(uint32 outputModuleId)
00531 {
00532 if (outModNameTable_.find(outputModuleId) == outModNameTable_.end())
00533 {
00534 return "";
00535 }
00536 else {
00537 return outModNameTable_[outputModuleId];
00538 }
00539 }
00540
00551 std::string InitMsgCollection::stringsToText(Strings const& list,
00552 unsigned int maxCount)
00553 {
00554 std::string resultString = "";
00555 unsigned int elementCount = list.size();
00556 if (maxCount > 0 && maxCount < elementCount) {elementCount = maxCount;}
00557 for (unsigned int idx = 0; idx < elementCount; idx++)
00558 {
00559 resultString.append(list[idx]);
00560 if (idx < (elementCount-1)) {
00561 resultString.append(", ");
00562 }
00563 }
00564 if (elementCount < list.size())
00565 {
00566 resultString.append(", ...");
00567 }
00568 return resultString;
00569 }
00570
00576 void InitMsgCollection::add(InitMsgView const& initMsgView)
00577 {
00578
00579 InitMsgSharedPtr serializedProds(new InitMsgBuffer(initMsgView.size()));
00580 initMsgList_.push_back(serializedProds);
00581 std::copy(initMsgView.startAddress(),
00582 initMsgView.startAddress()+initMsgView.size(),
00583 &(*serializedProds)[0]);
00584
00585
00586 outModNameTable_[initMsgView.outputModuleId()] =
00587 initMsgView.outputModuleLabel();
00588
00589
00590
00591 OtherMessageView fullSetView(&(*serializedFullSet_)[0]);
00592 unsigned int oldBodySize = fullSetView.bodySize();
00593 unsigned int oldBufferSize = serializedFullSet_->size();
00594 unsigned int newBodySize = oldBodySize + initMsgView.size();
00595 unsigned int newBufferSize = oldBufferSize + initMsgView.size();
00596
00597
00598 serializedFullSet_->resize(newBufferSize);
00599 OtherMessageBuilder fullSetMsg(&(*serializedFullSet_)[0],
00600 Header::INIT_SET,
00601 newBodySize);
00602 uint8 *copyPtr = fullSetMsg.msgBody() + oldBodySize;
00603 std::copy(initMsgView.startAddress(),
00604 initMsgView.startAddress()+initMsgView.size(),
00605 copyPtr);
00606 }