ATLAS Offline Software
Loading...
Searching...
No Matches
JobOptionTableLoader.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
7
9#include "./DBHelper.h"
10
11#include <CoralBase/Attribute.h>
12#include <CoralBase/AttributeList.h>
13
14#include "RelationalAccess/SchemaException.h"
15#include "RelationalAccess/ITransaction.h"
16#include "RelationalAccess/ITable.h"
17#include "RelationalAccess/ISchema.h"
18#include "RelationalAccess/ICursor.h"
19#include "RelationalAccess/IQuery.h"
20
21#include "boost/regex.hpp"
22
23#include <set>
24#include <iostream>
25#include <stdexcept>
26#include <sstream>
27#include <algorithm>
28#include <iterator>
29
30using namespace std;
31using namespace TrigConf;
32
33bool
35 int& masterTableID,
36 int& triggerMenuID,
37 int& l2SetupID,
38 int& efSetupID ) {
39
40 unique_ptr< coral::IQuery > q( m_session.nominalSchema().newQuery() );
41
42 // tables
43 q->addToTableList ( "SUPER_MASTER_TABLE", "SM" );
44 q->addToTableList ( "HLT_MASTER_TABLE", "HM" );
45
46 // Bind variables
47 coral::AttributeList bindList;
48 bindList.extend<int>("smid");
49 bindList[0].data<int>() = SuperMasterKey;
50
51 // the select condition
52 string theCondition = "SM.SMT_HLT_MASTER_TABLE_ID = HM.HMT_ID AND SM.SMT_ID = :smid";
53
54 q->setCondition( theCondition, bindList );
55
56 // output fields
57 coral::AttributeList attList;
58 attList.extend<int> ( "HM.HMT_ID" );
59 attList.extend<int> ( "HM.HMT_TRIGGER_MENU_ID" );
60 if(isRun1()) {
61 attList.extend<int> ( "HM.HMT_L2_SETUP_ID" );
62 attList.extend<int> ( "HM.HMT_EF_SETUP_ID" );
63 } else {
64 attList.extend<int> ( "HM.HMT_SETUP_ID" );
65 }
66 fillQuery(q.get(),attList);
67
68 // query
69 coral::ICursor& cursor = q->execute();
70
71 // get the HLT master-table id
72 if( ! cursor.next() )
73 return false;
74
75 const coral::AttributeList& row = cursor.currentRow();
76
77 masterTableID = row["HM.HMT_ID"].data<int>();
78 triggerMenuID = row["HM.HMT_TRIGGER_MENU_ID"].data<int>();
79 if(isRun1()) {
80 l2SetupID = row["HM.HMT_L2_SETUP_ID"].data<int>();
81 efSetupID = row["HM.HMT_EF_SETUP_ID"].data<int>();
82 } else {
83 l2SetupID = efSetupID = row["HM.HMT_SETUP_ID"].data<int>();
84 }
85 return true;
86}
87
88
89bool
91
92 unsigned int batchSize = 500;
93 set<int>::const_iterator current = compIDsToLoad.begin();
94 vector< SplitParam > splitparams;
95
96
97 while(current!=compIDsToLoad.end()) {
98 loadComponentNamesAndParameters(JOTable, compIDsToLoad, splitparams, current, batchSize);
99 }
100
101
102 TRG_MSG_INFO("Split parameters => " << splitparams.size());
103 TRG_MSG_INFO("Non-split parameters => " << JOTable.jobOptionVector().size());
104 unsigned int countSplitParam = assembleSplitParameters2(JOTable, splitparams);
105 TRG_MSG_INFO("Assembled split parameters => " << countSplitParam);
106
107 return true;
108}
109
110bool
112 const set<int>& compIDsToLoad,
113 vector<SplitParam>& splitparams,
114 set<int>::const_iterator & current,
115 unsigned int batchSize) {
116
117 unique_ptr< coral::IQuery > q( m_session.nominalSchema().newQuery() );
118 q->setRowCacheSize( 500 );
119
120 q->addToTableList ( "HLT_COMPONENT", "CP" );
121 q->addToTableList ( "HLT_CP_TO_PA", "CP2PA" );
122 q->addToTableList ( "HLT_PARAMETER", "PA" );
123
124
125 // bind
126 coral::AttributeList bind;
127
128 std::string cond( buildCond_IN_("CP.HCP_ID", compIDsToLoad, current, batchSize) );
129 cond += " AND CP2PA.HCP2PA_COMPONENT_ID = CP.HCP_ID";
130 cond += " AND CP2PA.HCP2PA_PARAMETER_ID = PA.HPA_ID";
131 q->setCondition( cond , bind );
132
133 // output and their types
134 coral::AttributeList attList;
135 attList.extend<std::string>( "CP.HCP_ALIAS" );
136 attList.extend<std::string>( "CP.HCP_TYPE" );
137 attList.extend<std::string>( "PA.HPA_NAME" );
138 attList.extend<std::string>( "PA.HPA_VALUE" );
139 fillQuery(q.get(),attList);
140
141 coral::ICursor& cursor = q->execute();
142
143 while( cursor.next() ) {
144
145 const coral::AttributeList& row = cursor.currentRow();
146
147 string alias = row["CP.HCP_ALIAS"].data<std::string>();
148 string type = "type"; //row["CP.HCP_TYPE"].data<std::string>();
149 string name = row["PA.HPA_NAME"].data<std::string>();
150 string value = row["PA.HPA_VALUE"].data<std::string>();
151
152 if( value == "~" ) value = "";
153
154 //if the parameter contains __ipc__ then its split - need to merge (after finding what to merge it with!)
155 if(name.find("__IPC__",0) != string::npos){
156 splitparams.push_back( SplitParam(alias, name, type, "set", value) );
157 } else {
158 JOTable.addJobOption( JobOption( alias, name, type, "set", value) );
159 }
160 }
161
162 return true;
163}
164
165
166std::set<int>
168
169 std::set<int> compIDs;
170
171 std::unique_ptr< coral::IQuery > q( m_session.nominalSchema().newQuery() );
172 q->setRowCacheSize( 1000 );
173
174 // tables
175 q->addToTableList ( "HLT_ST_TO_CP", "ST2CP" );
176
177 // bind setup id
178 coral::AttributeList bind;
179 bind.extend<int>("setupid");
180 bind[0].data<int>() = setup_id;
181
182 std::string cond("ST2CP.HST2CP_SETUP_ID = :setupid");
183 q->setCondition( cond , bind );
184
185 // output and their types
186 coral::AttributeList attList;
187 attList.extend<int>( "ST2CP.HST2CP_COMPONENT_ID" );
188 fillQuery(q.get(),attList);
189
190 // execute
191 coral::ICursor& cursor = q->execute();
192 while( cursor.next() ) {
193 const coral::AttributeList& row = cursor.currentRow();
194 int id = row["ST2CP.HST2CP_COMPONENT_ID"].data<int>();
195 compIDs.insert(id);
196 }
197
198 TRG_MSG_INFO("Loaded I-Components => " << compIDs.size());
199 return compIDs;
200}
201
202
203
204std::set<int>
206
207 std::set<int> compIDs;
208
209 std::unique_ptr< coral::IQuery > q( m_session.nominalSchema().newQuery() );
210 q->setRowCacheSize( 1000 );
211
212 q->addToTableList( "HLT_TM_TO_TC", "TM2TC" );
213 q->addToTableList( "HLT_TRIGGER_CHAIN", "TC" );
214 q->addToTableList( "HLT_TC_TO_TS", "TC2TS" );
215 q->addToTableList( "HLT_TS_TO_TE", "TS2TE" );
216 q->addToTableList( "HLT_TE_TO_CP", "TE2CP" );
217
218 // bind menu ID
219 coral::AttributeList bind;
220 bind.extend<int>("menuid");
221 bind[0].data<int>() = menu_id;
222
223
224 // condition
225 std::string cond("TM2TC.HTM2TC_TRIGGER_MENU_ID = :menuid");
226 cond += " AND TM2TC.HTM2TC_TRIGGER_CHAIN_ID = TC.HTC_ID";
227 cond += " AND TM2TC.HTM2TC_TRIGGER_CHAIN_ID = TC2TS.HTC2TS_TRIGGER_CHAIN_ID";
228 cond += " AND TC2TS.HTC2TS_TRIGGER_SIGNATURE_ID = TS2TE.HTS2TE_TRIGGER_SIGNATURE_ID";
229 cond += " AND TS2TE.HTS2TE_TRIGGER_ELEMENT_ID = TE2CP.HTE2CP_TRIGGER_ELEMENT_ID";
230
231 // triggerLevel
232 if(triggerLevel!=2) { // 2 means combined
233 cond += " AND TC.HTC_L2_OR_EF = ";
234 cond += ( triggerLevel==0 ? "'L2'" : "'EF'" );
235 }
236
237 q->setCondition( cond , bind );
238
239 // output
240 coral::AttributeList attList;
241 attList.extend<int>( "TE2CP.HTE2CP_COMPONENT_ID" );
242 fillQuery(q.get(),attList);
243
244 // execute
245 coral::ICursor& cursor = q->execute();
246 while( cursor.next() ) {
247 const coral::AttributeList& row = cursor.currentRow();
248 int id = row["TE2CP.HTE2CP_COMPONENT_ID"].data<int>();
249 compIDs.insert(id);
250 }
251
252 TRG_MSG_INFO("Loaded M-Components => " << compIDs.size());
253
254 return compIDs;
255}
256
257
258/***********
259 *
260 * turns field and a set<int>=(x1,...,x2531) into a string
261 *
262 * (field IN (x1,x2,...,x1000) OR field IN (x1001,x1002,...,x2000) OR field IN (x2001,x2002,...,x2531))
263 *
264 * this is needed since ORACLE has a limit of 1000 entries within IN(...)
265 ***/
266std::string
267TrigConf::JobOptionTableLoader::buildCond_IN_(const std::string& field, const std::set<int>& IDs, std::set<int>::const_iterator & current, unsigned int batchSize) {
268
269 std::stringstream ss;
270 ss << "(" << field << " IN (";
271
272 unsigned int count(0), totalCount(0);
273 set<int>::iterator last = IDs.end(); --last;
274 for(; current!=last && totalCount!=batchSize-1; ++current) {
275 totalCount++;
276 ss << *current;
277 if(++count==1000) {
278 ss << ") OR " << field << " IN (";
279 count=0;
280 } else {
281 ss << ",";
282 }
283 }
284 ss << *current++ << "))";
285
286 return ss.str();
287}
288
289
290namespace {
291 vector<int> createSortedVector(const set<int>& compIDs) {
292 vector<int> sortedVector(compIDs.size());
293 copy(compIDs.begin(), compIDs.end(), sortedVector.begin());
294 sort(sortedVector.begin(),sortedVector.end());
295 return sortedVector;
296 }
297
298 vector<string> concatAndSplit(const vector<int>& v, uint maxStringSize) {
299
300 // create a single long string of comma-separated numbers
301 vector<string> split;
302
303 string s("");s.reserve(8000);
304 uint count(0);
305
306 for(int i:v) {
307
308 s+=to_string(i) + ",";
309 count++;
310
311 if(count<1000 && s.size()<maxStringSize ) // oracle allows max 1000 items in (list)
312 continue;
313
314 s.erase(s.end()-1); // erase last comma
315
316 split.push_back( s );
317
318 s="";
319 count=0;
320 }
321
322 // the last entries in the loop
323 if(s!="") {
324 s.erase(s.end()-1); // erase last comma
325 split.push_back( std::move(s) );
326 }
327
328 return split;
329 }
330
331}
332
333std::set<int>
335
336 std::set<int> childCompIDs; // the children IDs
337
338 TRG_MSG_DEBUG("Number of parents " << compIDs.size());
339
340 vector<int> sortedParentIDs = createSortedVector(compIDs);
341
342 vector<string> splitParentIDs = concatAndSplit(sortedParentIDs, 7500);
343
344 for(const string& idList : splitParentIDs) {
345
346 // condition
347 string cond = "HCP2CP_PARENT_COMP_ID IN (" + idList + ")";
348
349 coral::ITable& table = m_session.nominalSchema().tableHandle("HLT_CP_TO_CP");
350 std::unique_ptr< coral::IQuery > q( table.newQuery() );
351
352 coral::AttributeList bind;
353 q->setCondition( cond, bind );
354
355 // output
356 coral::AttributeList attList;
357 attList.extend<int>( "HCP2CP_CHILD_COMP_ID" );
358 fillQuery(q.get(),attList);
359
360 // distinct
361 q->setDistinct();
362
363 // execute
364 coral::ICursor& cursor = q->execute();
365
366 // fill output
367 while( cursor.next() ) {
368 const coral::AttributeList& row = cursor.currentRow();
369 int id = row["HCP2CP_CHILD_COMP_ID"].data<int>();
370 childCompIDs.insert(id);
371 }
372
373 }
374
375 // no more children, can stop recursion
376 if(childCompIDs.size()==0)
377 return childCompIDs;
378
379 // get all children recursively
380 set<int> allSubChildrenIDs = getChildCompIDs(childCompIDs);
381
382 // add to set of all children
383 childCompIDs.insert(allSubChildrenIDs.begin(),allSubChildrenIDs.end());
384
385 return childCompIDs;
386}
387
388
389bool
391
392 JobOptionTable& jot = dynamic_cast<JobOptionTable&>(data);
393 try {
394 return load(jot);
395 }
396 catch( const std::exception& e ) {
397 TRG_MSG_FATAL("std::exception: " << e.what());
398 throw;
399 }
400 return false;
401}
402
403
404/*************
405 *
406 * Reassemble the split parameters - this isn't a very pretty way, probably should be rewritten
407 *
408 *************/
409unsigned int
410TrigConf::JobOptionTableLoader::assembleSplitParameters( JobOptionTable& jot, const std::vector< SplitParam >& splitparams ) {
411
412 unsigned int paramCount = 0;
413
414 // Loop over the vectors and match the alias and parameter names (excluding the __IPC__)
415 std::string mergedvalue ="";
416 std::string aliasname ="";
417 std::string paraname ="";
418
419
420 //ignore those we have already matched
421 vector< SplitParam > alreadymatched_v;
422
423 for (unsigned int sit=0; sit<splitparams.size(); sit++) {
424
425 const SplitParam & splitpar = splitparams.at(sit);
426
427 std::string actualname = splitpar.actualname;
428 // std::cout << splitpar.alias << " " << splitpar.name << std::endl;
429
430 // see if already matched - paraname and the alias!
431 bool matched = false;
432 for (unsigned int mit=0; mit<alreadymatched_v.size(); mit++){
433 SplitParam matchtemp = alreadymatched_v.at(mit);
434 matched = ( matchtemp.actualname==actualname && matchtemp.alias == splitpar.alias );
435 if(matched) break;
436 }
437
438
439 if(!matched) {
440 //have we gone on to the next name - if so, we have a merged parameter now
441 if( paraname!=actualname || aliasname!=splitpar.alias ){
442
443 if(aliasname!=""){
444 //MAKE THE NEW JOBOPTION!
445 JobOption jo( aliasname, paraname, "type", "set", mergedvalue);
446 jot.addJobOption(jo);
447 paramCount++;
448 }
449 aliasname = splitpar.alias;
450 paraname = actualname;
451 mergedvalue="";
452 }
453
454 alreadymatched_v.push_back( splitpar );
455 mergedvalue = splitpar.value;
456
457 //now look for a match here
458 for (unsigned int sit2=sit+1; sit2<splitparams.size(); sit2++){
459 const SplitParam& newtemp2 = splitparams.at(sit2);
460 std::string actualname2 = newtemp2.actualname;
461
462 if(actualname2==actualname && splitpar.alias==newtemp2.alias ){
463 mergedvalue+= newtemp2.value;
464 TRG_MSG_VERBOSE("Found split parameters " << splitpar.alias << " : " << splitpar.name << " - " << newtemp2.name);
465 TRG_MSG_VERBOSE(splitpar.value << " - " << newtemp2.value);
466 }
467 }
468 }
469 }
470
471 if(aliasname!=""){
472 //have to take care of the last one!
473 //MAKE THE NEW JOBOPTION!
474 JobOption jo( aliasname, paraname, "type", "set", mergedvalue);
475 jot.addJobOption(jo);
476 paramCount++;
477 }
478 return paramCount;
479
480}
481
482
483namespace {
484 class AssembledPar {
485 public:
486 AssembledPar(const std::string& compalias, const std::string& parname) :
487 comp_alias(compalias),
488 par_name(parname)
489 {}
490 std::string comp_alias;
491 std::string par_name;
492 };
493
494 struct APlessthan {
495 bool operator()(const AssembledPar& p1, const AssembledPar& p2) const {
496 int alias_cmp = p1.comp_alias.compare(p2.comp_alias);
497 if(alias_cmp>0) return false;
498 if(alias_cmp<0) return true;
499 return p1.par_name.compare(p2.par_name)<0;
500 }
501 };
502}
503
504unsigned int
505TrigConf::JobOptionTableLoader::assembleSplitParameters2( JobOptionTable& jot, const std::vector< SplitParam >& splitparams ) {
506
507 std::map<AssembledPar, std::vector<std::string>, APlessthan > assembled_params;
508
509 boost::regex pname_exp("(.*)__IPC__(\\d+)");
510 boost::cmatch matches;
511
512 // for(unsigned int i=0; i<splitparams.size(); ++i) {
513 for(const SplitParam & splitpar: splitparams ) {
514 //const SplitParam & splitpar = splitparams[i];
515
516 if(boost::regex_match(splitpar.name.c_str(), matches, pname_exp)) {
517
518 const std::string& comp_alias = splitpar.alias;
519 std::string par_name(matches[1].first, matches[1].second);
520 unsigned int pos = static_cast<unsigned int>(std::stoul(std::string(matches[2].first, matches[2].second))) - 1; // start with __IPC__01
521
522 std::vector<std::string>& values = assembled_params[ AssembledPar(comp_alias, par_name) ];
523
524 if(values.size()<=pos) values.resize(pos+1);
525 values[pos]= splitpar.value;
526
527 } else {
528 std::cout << "ERROR, can't parse " << splitpar.name << std::endl;
529 }
530
531 }
532
533 for(auto par: assembled_params) {
534
535 const string& comp_alias = par.first.comp_alias;
536 const string& par_name = par.first.par_name;
537 vector<string>& values = par.second;
538 stringstream ss;
539 copy(values.begin(), values.end(), std::ostream_iterator<std::string>(ss));
540 jot.addJobOption( JobOption( comp_alias, par_name, "type", "set", ss.str()) );
541 }
542
543 return assembled_params.size();
544}
545
546
547bool
549
550 if(jot.smk()==0) {
551 TRG_MSG_ERROR("requested SMK is 0");
552 return false;
553 }
554
556
557 TRG_MSG_INFO("Start loading job options with smk " << jot.smk());
558
559 startSession();
560
561 int masterTableID(0);
562 int triggerMenuID(0);
563 int l2SetupID(0);
564 int efSetupID(0);
565 if( ! loadHLTMasterTable( jot.smk(),
566 masterTableID,
567 triggerMenuID,
568 l2SetupID,
569 efSetupID ) )
570 {
571 TRG_MSG_ERROR("Could not load menu and setup IDs for SMK " << jot.smk());
572 return false;
573 }
574
575 jot.setHltMasterTableId( masterTableID );
576 TRG_MSG_INFO("HLT masterkey: " << jot.hltMasterTableId());
577 TRG_MSG_INFO("Menu ID : " << triggerMenuID);
578 if(l2SetupID==efSetupID) {
579 TRG_MSG_INFO("Setup ID : " << l2SetupID);
580 } else {
581 TRG_MSG_INFO("L2 Setup ID : " << l2SetupID);
582 TRG_MSG_INFO("EF Setup ID : " << efSetupID);
583 }
584
585 int level = jot.triggerLevel()==0; // triggerLevel: 0 - L2, 1 - EF, 2 - HLT(combined L2+EF)
586 if( l2SetupID == efSetupID ||
587 (l2SetupID != 0 && efSetupID==0) )
588 level=2; // combined
589
590 int setupId = (level==0 || level==2) ? l2SetupID : efSetupID;
591
592 std::set<int> compIDsToLoad = loadComponentIDsFromSetup(setupId);
593
594
595 TRG_MSG_INFO("Direct components => " << compIDsToLoad.size());
596
597 std::set<int> childCompIDs = getChildCompIDs( compIDsToLoad );
598
599 TRG_MSG_INFO("All children => " << childCompIDs.size());
600
601 compIDsToLoad.insert(childCompIDs.begin(), childCompIDs.end());
602
603 TRG_MSG_INFO("All components => " << compIDsToLoad.size());
604
605 loadComponentNamesAndParameters(jot, compIDsToLoad);
606
607 jot.sort();
608
610
611 // some stats:
612 TRG_MSG_INFO("JobOptionTableLoader: Total parameters : " << jot.jobOptionVector().size());
613
614 return true;
615}
616
617
static std::string to_string(const std::vector< T > &v)
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
unsigned int uint
static Double_t ss
void commitSession()
commit session if not already done
Definition DBLoader.cxx:45
coral::ISessionProxy & m_session
CORAL interface to database session.
Definition DBLoader.h:68
unsigned int triggerDBSchemaVersion()
Definition DBLoader.cxx:76
void startSession()
start session if not already active
Definition DBLoader.cxx:35
std::string buildCond_IN_(const std::string &field, const std::set< int > &IDs, std::set< int >::const_iterator &current, unsigned int batchSize)
virtual bool load(TrigConfData &data)
bool loadComponentNamesAndParameters(TrigConf::JobOptionTable &JOTable, const std::set< int > &compIDsToLoad)
std::set< int > loadComponentIDsFromMenu(const int menu_id, int triggerLevel)
std::set< int > loadComponentIDsFromSetup(const int setup_id)
bool loadHLTMasterTable(int SuperMasterKey, int &masterTableID, int &triggerMenuID, int &l2SetupID, int &efSetupID)
std::set< int > getChildCompIDs(const std::set< int > &compIDs)
unsigned int assembleSplitParameters(JobOptionTable &jot, const std::vector< SplitParam > &splitparams)
unsigned int assembleSplitParameters2(JobOptionTable &jot, const std::vector< SplitParam > &splitparams)
table to hold the complete list of JobOption entries for a single configuration, from which the JobOp...
void setHltMasterTableId(int id)
setter of the HLT master table configuration key
void addJobOption(const JobOption &jo)
adds a job option to the table
int triggerLevel() const
accessor to the trigger level
std::vector< JobOption > & jobOptionVector()
accessor to the vector of job options
void sort()
sort alphabetically by component and property name
int hltMasterTableId() const
accessor to the HLT master table configuration key
hold a single job option (parameter and value)
Definition JobOption.h:32
unsigned int smk() const
STL iterator class.
STL iterator class.
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177
Forward iterator to traverse the main components of the trigger configuration.
Definition Config.h:22
void fillQuery(coral::IQuery *q, coral::AttributeList &attList)
Definition DBHelper.cxx:13
std::vector< std::string > split(const std::string &line, const std::string &del=" ")
STL namespace.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.