6 #include <boost/core/demangle.hpp> 
    7 #include <boost/algorithm/string.hpp> 
    8 #include "Gaudi/Interfaces/IOptionsSvc.h" 
    9 #include "GaudiKernel/IToolSvc.h" 
   10 #include "GaudiKernel/System.h" 
   33                             const std::string& 
name,
 
   51   auto jobOptionsSvc = service<Gaudi::Interfaces::IOptionsSvc>(
"JobOptionsSvc",  
false);
 
   52   if (!jobOptionsSvc.isValid()) {
 
   53     ATH_MSG_WARNING(
"Could not retrieve JobOptionsSvc, will not update the EventSizeHardLimitMB property");
 
   56     if (jobOptionsSvc->has(
"DataFlowConfig.DF_MaxEventSizeMB")) {
 
   57       if (
m_eventSizeHardLimitMB.fromString(jobOptionsSvc->get(
"DataFlowConfig.DF_MaxEventSizeMB")).isSuccess()) {
 
   59                       << 
" from DataFlowConfig.DF_MaxEventSizeMB");
 
   62         ATH_MSG_ERROR(
"Could not convert DataFlowConfig.DF_MaxEventSizeMB to integer. Leaving EventSizeHardLimitMB=" 
   67       ATH_MSG_DEBUG(
"Could not retrieve DataFlowConfig.DF_MaxEventSizeMB from JobOptionsSvc. This is fine if running " 
   68                     << 
"offline, but should not happen online. Leaving EventSizeHardLimitMB=" 
   77       return StatusCode::FAILURE;
 
   86   return StatusCode::SUCCESS;
 
   93   std::vector<std::string> def;
 
   94   boost::split( def, typeKeyAuxIDs, boost::is_any_of(
";") );
 
   96   if ( def.size() < 2 ) {
 
   97     ATH_MSG_ERROR(
"Invalid EDM collection specification: " << typeKeyAuxIDs);
 
   98     return StatusCode::FAILURE;
 
  101   const std::string typeKeyAux = def[0];
 
  102   const std::string configuredType = typeKeyAux.substr( 0, typeKeyAux.find(
'#') );
 
  103   const std::string 
key = typeKeyAux.substr( typeKeyAux.find(
'#')+1, typeKeyAux.find(
'.')-typeKeyAux.find(
'#') );
 
  105   std::string transientType;
 
  106   std::string persistentType;
 
  109   if ( configuredType.find(
'_') == std::string::npos ) {
 
  110     transientType = configuredType;
 
  112     transientType  = configuredType.substr( 0, configuredType.find(
'_') );
 
  115   if ( 
m_clidSvc->getIDOfTypeName(transientType, clid).isFailure() )  {
 
  116     ATH_MSG_ERROR( 
"Can not find CLID for " << transientType << 
" that is needed for serialisation " << 
key );
 
  117     return StatusCode::FAILURE;
 
  119   ATH_MSG_VERBOSE(
"Decoded transient type: " << transientType << 
" with the CLID " << clid );
 
  120   if ( transientType == configuredType ) {
 
  121     std::string realTypeName;
 
  122     if( 
m_clidSvc->getTypeInfoNameOfID( clid, realTypeName ).isFailure() ) {
 
  123       ATH_MSG_ERROR( 
"Can not find real type name for " << transientType << 
" that is needed for serialisation " << 
key );
 
  124       return StatusCode::FAILURE;
 
  126     persistentType = transientType + 
version( realTypeName );
 
  127     ATH_MSG_VERBOSE(transientType << 
" = "<< configuredType << 
" thus obtained real type name from clid svc " << realTypeName << 
" forming persistent type name "<< persistentType );
 
  129     persistentType = configuredType;
 
  136     ATH_MSG_ERROR( 
"The type " << persistentType <<  
" is not known to ROOT serialiser" );
 
  137     return StatusCode::FAILURE;
 
  141   if ( def.size() > 2 && def[2].find(
"allowTruncation") != std::string::npos ) {
 
  146   std::vector<std::string> splitModuleIDs;
 
  147   boost::split( splitModuleIDs, def[1], boost::is_any_of(
",") );
 
  148   std::vector<uint16_t> moduleIdVec;
 
  149   for ( 
const auto& 
module: splitModuleIDs ) moduleIdVec.push_back( std::stoi( 
module ) );
 
  150   std::sort(moduleIdVec.begin(), moduleIdVec.end());
 
  152   if (moduleIdVec.empty()) {
 
  153     ATH_MSG_ERROR( 
"No HLT result module IDs given for " << typeKeyAux );
 
  154     return StatusCode::FAILURE;
 
  157   ATH_MSG_DEBUG( 
"Transient type " << transientType << 
" persistent type " << persistentType << 
" will be written to " << moduleIdVec.size() << 
" result ROBFragments with IDs: " 
  158       << moduleIdVec << 
"" );
 
  160   if ( persistentType.rfind(
"xAOD", 0) != std::string::npos ) { 
 
  162     if ( typeKeyAux.find(
'.') != std::string::npos ) { 
 
  164       const std::string allVars = typeKeyAux.substr( typeKeyAux.find(
'.')+1 );
 
  165       if (!allVars.empty()) {
 
  166         std::set<std::string> variableNames;
 
  167         boost::split( variableNames, allVars, [](
const char c){ 
return c == 
'.'; } );
 
  169           for ( 
const auto& 
el: variableNames ) {
 
  173         sel.selectAux( variableNames );
 
  182   return StatusCode::SUCCESS;
 
  189   std::vector<uint32_t> serializedLabel;
 
  192   ss.serialize( 
descr, serializedLabel );
 
  193   buffer.push_back( serializedLabel.size() );
 
  194   buffer.insert( 
buffer.end(), serializedLabel.begin(), serializedLabel.end() ); 
 
  195   return StatusCode::SUCCESS;
 
  203   const size_t neededSize = std::ceil( 
double(
sz)/
sizeof(
uint32_t) );
 
  204   const size_t existingSize = 
buffer.size();
 
  205   buffer.resize(existingSize + neededSize);
 
  207   return StatusCode::SUCCESS;
 
  218   const SG::IAuxStoreIO* auxStoreIO = dObjAux->template cast<SG::IAuxStoreIO> (
nullptr, 
true);
 
  219   if ( auxStoreIO == 
nullptr ) {
 
  220     ATH_MSG_DEBUG( 
"Can't obtain AuxContainerBase of " << 
address.key <<  
" no dynamic variables presumably" );
 
  221     return StatusCode::SUCCESS;
 
  226   if ( selected.
empty() ) {
 
  227     ATH_MSG_VERBOSE( 
"Empty set of dynamic variables to store, do nothing" );
 
  228     return StatusCode::SUCCESS;
 
  230   ATH_MSG_DEBUG(
"Ready for serialisation of " << selected.
size() << 
" dynamic variables");
 
  235     const std::type_info* tinfo = auxStoreIO->
getIOType (auxVarID);
 
  240     TClass* 
cls = TClass::GetClass (*tinfo);
 
  244       << 
"' fulltype '" << fullTypeName << 
"' aux ID '" << auxVarID << 
"' class '" << 
cls->GetName() );
 
  248       if ( 
m_clidSvc->getIDOfTypeInfoName(fullTypeName, clid).isFailure() ) { 
 
  249         ATH_MSG_ERROR(
"Unable to obtain CLID for either typeName:" << 
typeName << 
" or fullTypeName:" << fullTypeName);
 
  250         ATH_MSG_ERROR(
"Please check if this is something which should obtain a CLID via TriggerEDMCLIDs.h");
 
  251         return StatusCode::FAILURE;
 
  258     const void* rawptr = auxStoreIO->
getIOData( auxVarID );
 
  264     if ( mem == 
nullptr or 
sz == 0 ) {
 
  266       return StatusCode::FAILURE;
 
  270     std::vector<uint32_t> fragment;
 
  276     fragment[0] = fragment.size();
 
  278     delete [] 
static_cast<const char*
>( mem );
 
  280     buffer.insert( 
buffer.end(), fragment.begin(), fragment.end() );
 
  283   return StatusCode::SUCCESS;
 
  293   ATH_MSG_DEBUG( 
"Streamed to buffer at address " << mem << 
" of " << 
sz << 
" bytes" );
 
  295   if ( mem == 
nullptr or 
sz == 0 ) {
 
  297     return StatusCode::FAILURE;
 
  301   std::vector<uint32_t> fragment;
 
  304   if ( mem != 
nullptr ) 
delete [] 
static_cast<const char*
>( mem );
 
  308   fragment[0] = fragment.size();
 
  309   buffer.insert( 
buffer.end(), fragment.begin(), fragment.end() );
 
  311   return StatusCode::SUCCESS;
 
  317   std::vector<uint32_t>& 
buffer,
 
  328   if (data_interface != 
nullptr) {
 
  345   size_t baseSize = 
buffer.size();
 
  347     return StatusCode::SUCCESS;
 
  351   size_t nDynWritten = 0;
 
  353   if ( nDynWritten > 0 ) {
 
  355            << nDynWritten << 
"x DynAux : " << 
buffer.size()*
sizeof(
uint32_t) );
 
  357   return StatusCode::SUCCESS;
 
  363   std::string converterPersistentType;
 
  372   return StatusCode::SUCCESS;
 
  377   if ( dObj == 
nullptr ) {
 
  379     return StatusCode::SUCCESS;
 
  383   if ( rawptr == 
nullptr ) {
 
  384     ATH_MSG_DEBUG( 
"Data Object with key " << 
address.key << 
" can not be converted to void* for streaming" );
 
  385     return StatusCode::SUCCESS;
 
  398   ATH_MSG_ERROR(
"Unknown Address category - neither of xAODInterface, xAODAux, OldTP");
 
  399   return StatusCode::FAILURE;
 
  406     ATH_MSG_ERROR(
"Trying to fill a result which is not empty! Likely misconfiguration, returning a FAILURE");
 
  407     return StatusCode::FAILURE;
 
  418   auto debugInfoData = std::make_unique<xAOD::TrigCompositeContainer>();
 
  419   auto debugInfoAux  = std::make_unique<xAOD::TrigCompositeAuxContainer>();
 
  420   debugInfoData->setStore(debugInfoAux.get());
 
  421   ATH_CHECK(debugInfo.record(std::move(debugInfoData), std::move(debugInfoAux)));
 
  425   if (activeModules.empty()) {
 
  426     ATH_MSG_DEBUG(
"No active module IDs in this event. This is normal for events accepted " 
  427                   << 
"only to calibration streams. Skip all EDM serialisation.");
 
  428     return StatusCode::SUCCESS;
 
  432   std::vector<uint32_t> 
buffer;
 
  435   std::unordered_map<uint16_t, std::vector<uint32_t>> deferredInterfaceBuffer;
 
  438     std::vector<uint16_t> addressActiveModuleIds;
 
  440                           activeModules.begin(), activeModules.end(),
 
  441                           std::back_inserter(addressActiveModuleIds));
 
  442     if (addressActiveModuleIds.empty()) {
 
  444                     << 
"because its module IDs are not active in this event");
 
  457     ATH_MSG_DEBUG( 
"Serialised size of " << 
address.persTypeName() << 
" is " << thisFragmentSize << 
" bytes" );
 
  458     for (
const uint16_t id : addressActiveModuleIds) {
 
  470            deferredInterfaceBuffer.erase(
id);
 
  475         ATH_MSG_DEBUG(
"Module " << 
id << 
" payload after inserting " << 
address.persTypeName() << 
" has " 
  477         truncationInfoMap[
id].push_back({&
address, thisFragmentSize, 
true});
 
  481                         " truncated - could not add " << 
address.persTypeName() <<
 
  483         truncationInfoMap[
id].push_back({&
address, thisFragmentSize, 
false});
 
  491   return StatusCode::SUCCESS;
 
  496                                                 const std::vector<uint32_t>& 
data,
 
  498                                                 const std::unordered_map<
uint16_t, std::vector<uint32_t>> & deferredInterfaceBuffer)
 const {
 
  500     ATH_MSG_ERROR(
"Module ID " << 
id << 
" missing from TruncationThresholds map. Cannot determine if result needs truncation");
 
  501     return StatusCode::FAILURE;
 
  508   size_t currentTotalSizeWords = 0;
 
  510   const uint32_t currentTotalSizeBytes = currentTotalSizeWords*
sizeof(
uint32_t);
 
  517     ATH_MSG_DEBUG(
"Skipping adding data to result with module ID " << 
id << 
" because of full-result truncation");
 
  523     ATH_MSG_DEBUG(
"Skipping adding data to truncated result with module ID " << 
id);
 
  532     ATH_MSG_DEBUG(
"Adding data to result with module ID " << 
id);
 
  535   return StatusCode::SUCCESS;
 
  544     ATH_MSG_ERROR(
"HLT result truncation on total size! Limit of " 
  546                   << 
" MB exceeded. Flagging all module IDs as truncated.");
 
  552   for (
const auto& [
id, truncationInfoVec] : truncationInfoMap) {
 
  556       debugInfoCont.
push_back(debugInfoThisModule); 
 
  562       std::pair<std::string, size_t> largestRecorded{
"None", 0};
 
  563       std::pair<std::string, size_t> largestDropped{
"None", 0};
 
  564       std::pair<std::string, size_t> firstDropped{
"None", 0};
 
  565       moduleId(*debugInfoThisModule) = 
id;
 
  567       bool severeTruncation = 
false;
 
  568       bool truncated = 
false;
 
  571         sizeSum += truncationInfo.size;
 
  572         typeNameVec(*debugInfoThisModule).push_back(truncationInfo.addrPtr->persTypeName());
 
  573         sizeVec(*debugInfoThisModule).push_back(truncationInfo.size);
 
  574         isRecordedVec(*debugInfoThisModule).push_back(
static_cast<char>(truncationInfo.recorded));
 
  575         if (truncationInfo.recorded && truncationInfo.size > largestRecorded.second) {
 
  576           largestRecorded = {truncationInfo.addrPtr->persTypeName(), truncationInfo.size};
 
  578         if (!truncationInfo.recorded && truncationInfo.size > largestDropped.second) {
 
  579           largestDropped = {truncationInfo.addrPtr->persTypeName(), truncationInfo.size};
 
  581         if (!truncationInfo.recorded && !truncated) {
 
  582           firstDropped = {truncationInfo.addrPtr->persTypeName(), truncationInfo.size};
 
  586         if (!truncationInfo.recorded) {
 
  590       totalSize(*debugInfoThisModule) = sizeSum;
 
  591       msg(severeTruncation ? MSG::ERROR : MSG::WARNING)
 
  592         << 
"HLT result truncation" << (severeTruncation ? 
"." : 
" in low priority collections.")
 
  593         << 
" Module ID: " << 
id << 
", limit: " 
  595         << sizeSum/1024. << 
" kB, largest recorded collection: " << largestRecorded.first
 
  596         << 
" (" << largestRecorded.second/1024. << 
" kB), largest dropped collection: " 
  597         << largestDropped.first << 
" (" << largestDropped.second/1024. << 
" kB), " 
  598         << 
" first dropped collection: " <<firstDropped.first << 
" (" << firstDropped.second/1024. << 
" kB)" 
  605         std::stringstream 
ss;
 
  606         ss << 
"Passing chains in this event: ";
 
  614       const std::string 
prefix = severeTruncation ? 
"" : 
"Allowed";
 
  618         prefix+
"Truncation_LargestName",
 
  619         largestRecorded.second > largestDropped.second ? largestRecorded.first : largestDropped.first);
 
  621         prefix+
"Truncation_LargestSize",
 
  622         largestRecorded.second > largestDropped.second ? largestRecorded.second/1024. : largestDropped.second/1024.);
 
  627   if (!debugInfoCont.
empty()) {
 
  628     std::vector<Address> debugInfoAddressVec;
 
  629     const std::string debugInfoID = std::string(
"xAOD::TrigCompositeContainer#")+
m_debugInfoWHKey.key()+
";0";
 
  630     const std::string debugInfoAuxID = std::string(
"xAOD::TrigCompositeAuxContainer#")+
m_debugInfoWHKey.key()+
"Aux.;0";
 
  633     std::vector<uint32_t> 
buffer;
 
  641   return StatusCode::SUCCESS;
 
  645   if ( 
name.find(
"DataVector") != std::string::npos ) {
 
  649   if ( 
name.find(
'_') != std::string::npos ) {
 
  650     return name.substr( 
name.find(
'_') );
 
  656   std::set<uint16_t> activeIDs;
 
  657   for (
const eformat::helper::StreamTag& 
st : 
result.getStreamTags()) {
 
  658     if (
st.robs.empty() && 
st.dets.empty()) { 
 
  663       eformat::helper::SourceIdentifier sid(robid);
 
  664       if (sid.subdetector_id() != eformat::SubDetector::TDAQ_HLT) {
 
  667       activeIDs.insert(sid.module_id());