ATLAS Offline Software
Loading...
Searching...
No Matches
SortedCollectionCreator.py
Go to the documentation of this file.
1# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
2
3__author__ = "Marcin Nowak"
4__doc__ = """
5Create a sorted collection of Event references from a set of Athnea files containing EventInfoTags
6(or from other compatible APR Event collections)
7"""
8
9
11 """Creates a sorted (APR) collection of event references from input files"""
12
13 def __init__(self, name="sortEvents"):
14 from AthenaCommon import Logging
15 Logging.log.name = name
16 self.name = name
17 self.info = Logging.log.info
18 self.debug = Logging.log.debug
19 self.verbose = Logging.log.verbose
20 self.collDescription = None
21 self.collSvc = None
22
23 def loadRoot(self):
24 """import ROOT, create CollectionSvc"""
25 import ROOT
26 self.pool = ROOT.pool
27 self.collSvc = self.pool.CollectionService()
28 self.collSvc.setMessageSvcQuiet()
29
30 def readCollectionDescription(self, collection):
31 """read Collection Description and remember it"""
32 desc = collection.description()
33 self.debug("Reading Collection Description from {}".format(desc.name()))
34 # read attributes' names and types from the description and remember them
35 for an in range(0, desc.numberOfAttributeColumns()):
36 attr = desc.attributeColumn(an)
37 name = attr.name()
38 self.attrNames.append(name)
39 self.attrTypes[name] = attr.type()
40 # make a local copy of the description
41 self.collDescription = self.pool.CollectionDescription( desc )
42
43
44 def readInputCollections(self, inputCollections):
45 """read all input collections into memory"""
46 from PyUtils import PoolFile
47 self.collDescription = None
48 self.allRows = []
49 self.attrNames = []
50 self.attrTypes = {}
51 for inFileName in inputCollections:
52 self.debug("Opening {}".format(inFileName))
53 iColl = self.collSvc.open( "Input", PoolFile.PoolOpts.CollectionType.RootCollection, inFileName)
54 self.debug("{} opened".format(inFileName))
55 if self.collDescription is None:
57 self.info("Reading Events from {}".format(inFileName))
58
59 cursor = iColl.cursor()
60
61 while cursor.next():
62 row = cursor.currentRow()
63 # put the token first in the attribute list, for convenience
64 t = [ row.token().toString() ]
65 for nam in self.attrNames:
66 t.append( row.attributeList()[nam].data[ self.attrTypes[nam] ]() )
67 self.allRows.append(t)
68
69 iColl.close()
70
71 for t in self.allRows:
72 self.verbose( (t[1:], t[0]) )
73 self.verbose('='*80)
74 self.info("Finished reading input collections, total events read: {}".format(len(self.allRows)) )
75
76 def sortEvents(self, sortAttrName, sortReverse=False):
77 """sort the events based on an attribute name"""
78 self.info("Sorting on attribute {}, sort order {}".format(sortAttrName, ("Descending" if sortReverse else "Ascending") ))
79 # add 1 to offsets because the Ref is first
80 attrPos = self.attrNames.index(sortAttrName)+1
81 self.allRows.sort( key=lambda t: t[attrPos], reverse=sortReverse )
82
83 for t in self.allRows:
84 self.verbose( (t[1:], t[0]) )
85 self.verbose('='*80)
86
87 def writeCollection(self, outputCollection, outputCollectionType):
88 """write sorted collection into a Collection file"""
89 self.info("Writing Event collection {}".format(outputCollection))
90 self.collDescription.setName("Sorting")
91 self.collDescription.setType(outputCollectionType)
92 self.collDescription.setConnection(outputCollection)
93 # create the output collection (file)
94 dstColl = self.collSvc.create(self.collDescription)
95 row = self.pool.CollectionRowBuffer()
96 dstColl.initNewRow( row )
97 for t in self.allRows:
98 row.token().fromString( t[0] )
99 for idx,nam in enumerate(self.attrNames):
100 type = self.attrTypes[nam]
101 row.attributeList()[nam].setValue[type]( t[idx+1] )
102 dstColl.insertRow( row )
103
104 dstColl.commit()
105 dstColl.close()
106
107 def execute(self, inputCollections, outputCollection, outputCollectionType, sortAttribute="LumiBlockN",
108 sortOrder="Ascending"):
109 sort_opts = ("Ascending", "Descending")
110 self.info("Executing SortedCollectionCreator, inputs={}, output='{}' ({}), sort by: {}, order: {}"
111 .format(inputCollections, outputCollection, outputCollectionType, sortAttribute, sortOrder))
112 if isinstance(inputCollections, str):
113 inputs = [inputCollections]
114 else:
115 inputs = inputCollections
116 if sortOrder.lower() not in [opt.lower() for opt in sort_opts]:
117 raise Exception(self.name + ": Accepted sortOrder values are: " + str(sort_opts))
118 sortReverse = ( sortOrder.lower()[0] == "d" )
119 self.loadRoot()
120 self.readInputCollections(inputs)
121 self.sortEvents(sortAttribute, sortReverse)
122 self.writeCollection(outputCollection, outputCollectionType)
123
124 def executeInSubprocess(self, *args, **kwargs):
125 import multiprocessing
126 process = multiprocessing.Process( target=self.execute, args=args, kwargs=kwargs)
127 self.debug("Sorting Events in a subprocess")
128 process.start()
129 process.join() # Wait for completion
130 return process.exitcode
131
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
writeCollection(self, outputCollection, outputCollectionType)
execute(self, inputCollections, outputCollection, outputCollectionType, sortAttribute="LumiBlockN", sortOrder="Ascending")
Definition index.py:1