The Gaudi Framework  v36r6 (b1ee9983)
GaudiMP.pTools.FileRecordsAgent Class Reference

Public Member Functions

def __init__ (self, gmpComponent)
 
def localCmp (self, tupA, tupB)
 
def SendFileRecords (self)
 
def Receive (self)
 
def Rebuild (self)
 
def MergeFSRobject (self, sourceNode, path, ob)
 
def ProcessTimeSpanFSR (self, path, ob)
 
def ProcessEventCountFSR (self, path, ob)
 
def MergeLumiFSR (self, path, keyedC)
 

Public Attributes

 fsr
 
 q
 
 log
 
 objectsIn
 
 objectsOut
 

Private Attributes

 _gmpc
 

Detailed Description

Definition at line 240 of file pTools.py.

Constructor & Destructor Documentation

◆ __init__()

def GaudiMP.pTools.FileRecordsAgent.__init__ (   self,
  gmpComponent 
)

Definition at line 241 of file pTools.py.

241  def __init__(self, gmpComponent):
242  self._gmpc = gmpComponent
243  self.fsr = self._gmpc.fsr
244  self.q = self._gmpc.fq
245  self.log = self._gmpc.log
246  self.objectsIn = [] # used for collecting FSR store objects
247  self.objectsOut = []
248 

Member Function Documentation

◆ localCmp()

def GaudiMP.pTools.FileRecordsAgent.localCmp (   self,
  tupA,
  tupB 
)

Definition at line 249 of file pTools.py.

249  def localCmp(self, tupA, tupB):
250  # sort tuples by a particular element
251  # for the sort() method
252  ind = 0
253  valA = tupA[ind]
254  valB = tupB[ind]
255  if valA < valB:
256  return -1
257  elif valA > valB:
258  return 1
259  else:
260  return 0
261 

◆ MergeFSRobject()

def GaudiMP.pTools.FileRecordsAgent.MergeFSRobject (   self,
  sourceNode,
  path,
  ob 
)

Definition at line 394 of file pTools.py.

394  def MergeFSRobject(self, sourceNode, path, ob):
395  # Merge Non-Empty Keyed Container from Worker>0
396  if path == "/FileRecords/TimeSpanFSR":
397  # TimeSpanFSR is a straightforward case
398  self.ProcessTimeSpanFSR(path, ob)
399  elif path == "/FileRecords/EventCountFSR":
400  # Event Counter is also easy
401  self.ProcessEventCountFSR(path, ob)
402  # now other cases may not be so easy...
403  elif (
404  "KeyedContainer" in ob.__class__.__name__
405  and "LumiFSR" in ob.__class__.__name__
406  ):
407  # Keyed Container of LumiFSRs : extract and re-register
408  self.MergeLumiFSR(path, ob)
409  else:
410  self.log.info("Skipping Merge of %s at %s" % (ob.__class__.__name__, path))
411 

◆ MergeLumiFSR()

def GaudiMP.pTools.FileRecordsAgent.MergeLumiFSR (   self,
  path,
  keyedC 
)

Definition at line 438 of file pTools.py.

438  def MergeLumiFSR(self, path, keyedC):
439  from ROOT import string
440 
441  # Fetch the first lumi
442  keyedContainer = self.fsr.retrieveObject(path)
443  # The LumiFSR KeyedContainers only have one object
444  assert keyedContainer.numberOfObjects() == 1
445  l = keyedContainer.containedObject(0)
446  baseLumi = LumiFSR(l)
447  # Now deal with the argument Non-empty Keyed Container of LumiFSRs
448  nCont = keyedC.numberOfObjects()
449  for i in range(nCont):
450  obj = keyedC.containedObject(i)
451  nextLumi = LumiFSR(obj)
452  baseLumi.merge(nextLumi)
453  # Now Rebuild and ReRegister
454  newLumi = gbl.LHCb.LumiFSR()
455  for r in baseLumi.runs:
456  newLumi.addRunNumber(r)
457  for f in baseLumi.files:
458  newLumi.addFileID(string(f))
459  for k in baseLumi.keys:
460  increment, integral = baseLumi.info[k]
461  newLumi.addInfo(k, increment, integral)
462  # clear existing Keyed Container
463  self.fsr[path].clear()
464  # Add newly merged lumiFSR
465  self.fsr[path].add(newLumi)
466  return SUCCESS
467 
468 
469 # =============================================================================
470 
471 

◆ ProcessEventCountFSR()

def GaudiMP.pTools.FileRecordsAgent.ProcessEventCountFSR (   self,
  path,
  ob 
)

Definition at line 434 of file pTools.py.

434  def ProcessEventCountFSR(self, path, ob):
435  self.log.debug("Event Count Input Addition")
436  self.fsr[path].setInput(self.fsr[path].input() + ob.input())
437 

◆ ProcessTimeSpanFSR()

def GaudiMP.pTools.FileRecordsAgent.ProcessTimeSpanFSR (   self,
  path,
  ob 
)

Definition at line 412 of file pTools.py.

412  def ProcessTimeSpanFSR(self, path, ob):
413  ob2 = self.fsr.retrieveObject(path)
414  if ob.containedObjects().size():
415  sz = ob.containedObjects().size()
416  cob = ob2.containedObjects()[0]
417  min = cob.earliest()
418  max = cob.latest()
419  for j in range(sz):
420  cob = ob.containedObjects()[j]
421  self.log.debug("Adding TimeSpanFSR")
422  if cob.earliest() < min:
423  min = cob.earliest()
424  if cob.latest() > max:
425  max = cob.latest()
426  # this is annoying: it has to be rebuilt, without a key & added
427  continue
428  tsfsr = gbl.LHCb.TimeSpanFSR()
429  tsfsr.setEarliest(min)
430  tsfsr.setLatest(max)
431  self.fsr[path].clear()
432  self.fsr[path].add(tsfsr)
433 

◆ Rebuild()

def GaudiMP.pTools.FileRecordsAgent.Rebuild (   self)

Definition at line 345 of file pTools.py.

345  def Rebuild(self):
346  # objects is a list of (path, serializedObject) tuples
347  for sourceNode, path, serialob in self.objectsIn:
348  self.log.debug("Working with %s" % (path))
349  ob = pickle.loads(serialob)
350  if hasattr(ob, "update"):
351  ob.update()
352  if hasattr(ob, "numberOfObjects"):
353  nCont = ob.numberOfObjects()
354  self.log.debug(
355  "\t %s has containedObjects : %i" % (type(ob).__name__, nCont)
356  )
357  if sourceNode == 0:
358  self.log.debug("Registering Object to : %s" % (path))
359  self.fsr.registerObject(path, ob)
360  else:
361  self.log.debug("Merging Object to : %s" % (path))
362  self.MergeFSRobject(sourceNode, path, ob)
363  # As RecordStream has been split into Worker and Writer parts, the
364  # count for output is wrong... fix that here, as every event received
365  # by the writer is written (validation testing occurs on the worker)
366 
367  self.log.info("FSR Store Rebuilt. Correcting EventCountFSR")
368  if bool(self.fsr._idp): # There might not be an FSR stream (Gauss)
369  ecount = "/FileRecords/EventCountFSR"
370  if self.fsr[ecount]:
371  self.fsr[ecount].setOutput(self._gmpc.nIn)
372  self.log.info(
373  "Event Counter Output set : %s : %i"
374  % (ecount, self.fsr[ecount].output())
375  )
376  # Do some reporting
377  self.log.debug("FSR store reconstructed!")
378  lst = self.fsr.getHistoNames()
379  if lst:
380  for l in lst:
381  ob = self.fsr.retrieveObject(l)
382  if hasattr(ob, "configureDirectAccess"):
383  ob.configureDirectAccess()
384  if hasattr(ob, "containedObjects"):
385  # if ob.numberOfObjects() :
386  self.log.debug(
387  "\t%s (cont. objects : %i)" % (l, ob.numberOfObjects())
388  )
389  else:
390  self.log.debug("\t%s" % (l))
391  self.log.info("FSR Store fully rebuilt.")
392  return SUCCESS
393 

◆ Receive()

def GaudiMP.pTools.FileRecordsAgent.Receive (   self)

Definition at line 325 of file pTools.py.

325  def Receive(self):
326  # Receive contents of all Workers FileRecords Transient Stores
327  self.log.info("Receiving FSR store data...")
328  nc = self._gmpc.nWorkers
329  while nc > 0:
330  objects = self.q.get()
331  if objects == "END_FSR":
332  nc -= 1
333  continue
334  if nc == 0:
335  break
336  # but if it's regular objects...
337  for o in objects:
338  self.objectsIn.append(o)
339  # Now sort it by which worker it came from
340  # an object is : (nodeID, path, pickledObject)
341  self.objectsIn.sort(cmp=self.localCmp)
342  self.log.info("All FSR data received")
343  return SUCCESS
344 

◆ SendFileRecords()

def GaudiMP.pTools.FileRecordsAgent.SendFileRecords (   self)

Definition at line 262 of file pTools.py.

262  def SendFileRecords(self):
263  # send the FileRecords data as part of finalisation
264 
265  # Take Care of FileRecords!
266  # There are two main things to consider here
267  # 1) The DataObjects in the FileRecords Transient Store
268  # 2) The fact that they are Keyed Containers, containing other objects
269  #
270  # The Lead Worker, nodeID=0, sends everything in the FSR store, as
271  # a completeness guarantee,
272  #
273  # send in form ( nodeID, path, object)
274  self.log.info("Sending FileRecords...")
275  lst = self.fsr.getHistoNames()
276 
277  # Check Validity
278  if not lst:
279  self.log.info("No FileRecords Data to send to Writer.")
280  self.q.put("END_FSR")
281  return SUCCESS
282 
283  # no need to send the root node
284  if "/FileRecords" in lst:
285  lst.remove("/FileRecords")
286 
287  for l in lst:
288  o = self.fsr.retrieveObject(l)
289  if hasattr(o, "configureDirectAccess"):
290  o.configureDirectAccess()
291  # lead worker sends everything, as completeness guarantee
292  if self._gmpc.nodeID == 0:
293  self.objectsOut.append((0, l, pickle.dumps(o)))
294  else:
295  # only add the Event Counter
296  # and non-Empty Keyed Containers (ignore empty ones)
297  if l == "/FileRecords/EventCountFSR":
298  tup = (self._gmpc.nodeID, l, pickle.dumps(o))
299  self.objectsOut.append(tup)
300  elif "KeyedContainer" in o.__class__.__name__:
301  # It's a Keyed Container
302  nObjects = o.numberOfObjects()
303  if nObjects:
304  self.log.debug(
305  "Keyed Container %s with %i objects" % (l, nObjects)
306  )
307  tup = (self._gmpc.nodeID, l, pickle.dumps(o))
308  self.objectsOut.append(tup)
309  else:
310  self.log.info("Ignoring %s in FSR" % o.__class__.__name__)
311 
312  self.log.debug("Done with FSR store, just to send to Writer.")
313 
314  if self.objectsOut:
315  self.log.debug("%i FSR objects to Writer" % (len(self.objectsOut)))
316  for ob in self.objectsOut:
317  self.log.debug("\t%s" % (ob[0]))
318  self.q.put(self.objectsOut)
319  else:
320  self.log.info("Valid FSR Store, but no data to send to Writer")
321  self.log.info("SendFSR complete")
322  self.q.put("END_FSR")
323  return SUCCESS
324 

Member Data Documentation

◆ _gmpc

GaudiMP.pTools.FileRecordsAgent._gmpc
private

Definition at line 242 of file pTools.py.

◆ fsr

GaudiMP.pTools.FileRecordsAgent.fsr

Definition at line 243 of file pTools.py.

◆ log

GaudiMP.pTools.FileRecordsAgent.log

Definition at line 245 of file pTools.py.

◆ objectsIn

GaudiMP.pTools.FileRecordsAgent.objectsIn

Definition at line 246 of file pTools.py.

◆ objectsOut

GaudiMP.pTools.FileRecordsAgent.objectsOut

Definition at line 247 of file pTools.py.

◆ q

GaudiMP.pTools.FileRecordsAgent.q

Definition at line 244 of file pTools.py.


The documentation for this class was generated from the following file:
details::size
constexpr auto size(const T &, Args &&...) noexcept
Definition: AnyDataWrapper.h:22
gaudirun.output
output
Definition: gaudirun.py:521
compareOutputFiles.LumiFSR
def LumiFSR(lumi)
Definition: compareOutputFiles.py:347
Gaudi::Functional::details::get
auto get(const Handle &handle, const Algo &, const EventContext &) -> decltype(details::deref(handle.get()))
Definition: FunctionalDetails.h:444
gaudirun.type
type
Definition: gaudirun.py:160
GaudiPython.Persistency.add
def add(instance)
Definition: Persistency.py:49
Gaudi::Functional::details::put
auto put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
Definition: FunctionalDetails.h:173
Gaudi::Functional::details::zip::range
decltype(auto) range(Args &&... args)
Zips multiple containers together to form a single range.
Definition: FunctionalDetails.h:102