00001 """
00002 High level configuration tools for LHCb applications
00003 """
00004 __version__ = "$Id: DstConf.py,v 1.10 2009/04/06 15:26:29 cattanem Exp $"
00005 __author__ = "Marco Cattaneo <Marco.Cattaneo@cern.ch>"
00006
00007 from Gaudi.Configuration import *
00008 import GaudiKernel.ProcessJobOptions
00009
00010 class DstConf(ConfigurableUser):
00011 __slots__ = {
00012 "DstType" : "NONE"
00013 , "SimType" : "None"
00014 , "EnableUnpack" : False
00015 , "PackType" : "TES"
00016 , "PackSequencer" : None
00017 , "Writer" : "DstWriter"
00018 , "OutputName" : ""
00019 }
00020
00021 _propertyDocDct = {
00022 'DstType' : """ Type of dst, can be ['DST','RDST'] """
00023 ,'SimType' : """ Type of simulation output, can be ['None','Minimal','Full'] """
00024 ,'EnableUnpack' : """ Flag to set up on demand unpacking of DST containers """
00025 ,'PackType' : """ Type of packing for the DST, can be ['NONE','TES','MDF'] """
00026 ,'PackSequencer' : """ Sequencer in which to run the packing algorithms """
00027 ,'Writer' : """ Name of OutputStream writing the DST """
00028 ,'OutputName' : """ Name of the output file, for MDF writing """
00029 }
00030
00031 KnownDstTypes = ['NONE', 'DST','RDST']
00032 KnownPackTypes = ['NONE', 'TES','MDF']
00033
00034 def _doWrite( self ):
00035 """
00036 Define the file content and write it out
00037 """
00038 dType = self.getProp( "DstType" ).upper()
00039 if dType not in self.KnownDstTypes:
00040 raise TypeError( "Unknown DST type '%s'"%dType )
00041 if dType == 'NONE': return
00042
00043 pType = self.getProp( "PackType" ).upper()
00044 if pType not in self.KnownPackTypes:
00045 raise TypeError( "Unknown packing type '%s'"%pType )
00046
00047 items = []
00048 optItems = []
00049 self._defineOutputData( dType, pType, items, optItems )
00050
00051 if pType == 'MDF':
00052 if dType == 'DST': raise TypeError( "Only RDST are supported with MDF packing" )
00053 self._doWriteMDF( items )
00054 else:
00055 self._doWritePOOL( items, optItems )
00056
00057
00058 def _defineOutputData( self, dType, pType, items, optItems ):
00059 """
00060 Define content of the output dataset
00061 """
00062
00063
00064 if pType == 'NONE':
00065 recDir = "Rec"
00066 else:
00067 recDir = "pRec"
00068 if not hasattr( self, "PackSequencer" ):
00069 raise TypeError( "Packing requested but PackSequencer not defined" )
00070
00071
00072 if pType == 'MDF':
00073 depth = ""
00074 else:
00075 depth = "#1"
00076
00077 items += [ "/Event/DAQ/ODIN" + depth
00078 , "/Event/Rec/Header" + depth
00079 , "/Event/Rec/Status" + depth
00080 , "/Event/" + recDir + "/Track/Best" + depth
00081 , "/Event/" + recDir + "/Calo/Electrons" + depth
00082 , "/Event/" + recDir + "/Calo/Photons" + depth
00083 , "/Event/" + recDir + "/Calo/MergedPi0s" + depth
00084 , "/Event/" + recDir + "/Calo/SplitPhotons" + depth
00085 , "/Event/" + recDir + "/ProtoP/Charged" + depth
00086 , "/Event/" + recDir + "/ProtoP/Neutrals" + depth
00087 , "/Event/" + recDir + "/Vertex/Primary" + depth
00088 , "/Event/" + recDir + "/Vertex/V0" + depth ]
00089
00090
00091 if dType == "DST":
00092 items += [ "/Event/" + recDir + "/Track/Muon" + depth ]
00093
00094
00095 if pType != "MDF":
00096 items += [ "/Event/DAQ/RawEvent#1" ]
00097
00098
00099 optItems += [ "/Event/Phys/Selections#1" ]
00100
00101
00102 if self.getProp("SimType").capitalize() != "None":
00103
00104 items += [ "/Event/Gen/Header#1"
00105 , "/Event/MC/Header#1"
00106 , "/Event/pSim/MCVertices#1" ]
00107
00108 if self.getProp("SimType").capitalize() == "Full":
00109 items += [
00110
00111 "/Event/Link/Rec/Track/Best#1"
00112
00113
00114 , "/Event/Gen/Collisions#1"
00115 , "/Event/Gen/HepMCEvents#1"
00116 , "/Event/pSim/MCParticles#1"
00117
00118
00119 , "/Event/MC/DigiHeader#1"
00120 , "/Event/MC/TrackInfo#1"
00121 , "/Event/MC/Rich/DigitSummaries#1"
00122 , "/Event/MC/Muon/DigitsInfo#1"
00123 , "/Event/Link/Raw/Velo/Clusters#1"
00124 , "/Event/Link/Raw/TT/Clusters#1"
00125 , "/Event/Link/Raw/IT/Clusters#1"
00126 , "/Event/Link/Raw/OT/Times#1"
00127 , "/Event/Link/Raw/Ecal/Digits#1"
00128 , "/Event/Link/Raw/Muon/Digits#1"
00129 , "/Event/Link/Trig/L0/FullCalo#1" ]
00130
00131
00132 optItems += [ "/Event/Prev/MC/Header#1"
00133 , "/Event/PrevPrev/MC/Header#1"
00134 , "/Event/Next/MC/Header#1"
00135 , "/Event/Link/Raw/Hcal/Digits#1"
00136 ]
00137
00138 def _doWritePOOL( self, items, optItems ):
00139 """
00140 Write a DST (or RDST) in POOL format
00141 """
00142 writer = OutputStream( self.getProp("Writer") )
00143 ApplicationMgr().OutStream.append( writer )
00144 writer.Preload = False
00145 writer.ItemList += items
00146 writer.OptItemList += optItems
00147 log.info( "%s.ItemList=%s"%(self.getProp("Writer"),items) )
00148 log.info( "%s.OptItemList=%s"%(self.getProp("Writer"),optItems) )
00149
00150
00151 def _doWriteMDF( self, items ):
00152 """
00153 Write an RDST in MDF format
00154 """
00155 from Configurables import WritePackedDst, LHCb__MDFWriter
00156
00157 MDFpacker = WritePackedDst('MdfPacker')
00158 MDFpacker.Containers += items
00159
00160 MDFwr = LHCb__MDFWriter('MdfWriter')
00161 MDFwr.Connection = self.getProp( "OutputName" ) + '.mdf'
00162 MDFwr.Compress = 2
00163 MDFwr.GenerateMD5 = True
00164 MDFwr.BankLocation = '/Event/DAQ/DstEvent'
00165
00166 GaudiSequencer("WriteMDFSeq").Members += [ MDFpacker, MDFwr ]
00167
00168 def _doPack( self ):
00169 """
00170 Set up the sequence to create the packed containers
00171 """
00172 packDST = self.getProp("PackSequencer")
00173 from Configurables import PackTrack, PackCaloHypo, PackProtoParticle, PackRecVertex, PackTwoProngVertex
00174 packDST.Members = [ PackTrack()
00175 , PackCaloHypo( name = "PackElectrons",
00176 InputName = "/Event/Rec/Calo/Electrons",
00177 OutputName = "/Event/pRec/Calo/Electrons")
00178 , PackCaloHypo( name = "PackPhotons",
00179 InputName = "/Event/Rec/Calo/Photons",
00180 OutputName = "/Event/pRec/Calo/Photons")
00181 , PackCaloHypo( name = "PackMergedPi0s",
00182 InputName = "/Event/Rec/Calo/MergedPi0s",
00183 OutputName = "/Event/pRec/Calo/MergedPi0s")
00184 , PackCaloHypo( name = "PackSplitPhotons",
00185 InputName = "/Event/Rec/Calo/SplitPhotons",
00186 OutputName = "/Event/pRec/Calo/SplitPhotons")
00187 , PackProtoParticle( name = "PackCharged",
00188 InputName = "/Event/Rec/ProtoP/Charged",
00189 OutputName = "/Event/pRec/ProtoP/Charged")
00190 , PackProtoParticle( name = "PackNeutrals",
00191 InputName = "/Event/Rec/ProtoP/Neutrals",
00192 OutputName = "/Event/pRec/ProtoP/Neutrals")
00193 , PackRecVertex()
00194 , PackTwoProngVertex()
00195 ]
00196 if self.getProp( "DstType" ).upper() == "DST":
00197 packDST.Members += [ PackTrack( name = "PackMuons",
00198 InputName = "/Event/Rec/Track/Muon",
00199 OutputName = "/Event/pRec/Track/Muon") ]
00200
00201
00202 if self.getProp( "PackType" ).upper() == "MDF":
00203 packDST.Members += [ GaudiSequencer("WriteMDFSeq") ]
00204
00205 def _doUnpack( self ):
00206 """
00207 Set up DataOnDemandSvc to unpack a packed (r)DST
00208 """
00209 from Configurables import UnpackTrack, UnpackCaloHypo, UnpackProtoParticle, UnpackRecVertex, UnpackTwoProngVertex
00210
00211 unpackTracks = UnpackTrack()
00212 unpackMuons = UnpackTrack( name = "UnpackMuons",
00213 OutputName = "/Event/Rec/Track/Muon",
00214 InputName = "/Event/pRec/Track/Muon")
00215 unpackVertex = UnpackRecVertex()
00216 unpackV0 = UnpackTwoProngVertex()
00217 unpackElectrons = UnpackCaloHypo( name = "UnpackElectrons",
00218 OutputName = "/Event/Rec/Calo/Electrons",
00219 InputName = "/Event/pRec/Calo/Electrons")
00220 unpackPhotons = UnpackCaloHypo( name = "UnpackPhotons",
00221 OutputName = "/Event/Rec/Calo/Photons",
00222 InputName = "/Event/pRec/Calo/Photons")
00223 unpackMergedPi0s = UnpackCaloHypo( name = "UnpackMergedPi0s",
00224 OutputName = "/Event/Rec/Calo/MergedPi0s",
00225 InputName = "/Event/pRec/Calo/MergedPi0s")
00226 unpackSplitPhotons = UnpackCaloHypo( name = "UnpackSplitPhotons",
00227 OutputName = "/Event/Rec/Calo/SplitPhotons",
00228 InputName = "/Event/pRec/Calo/SplitPhotons")
00229 unpackCharged = UnpackProtoParticle(name = "UnpackCharged",
00230 OutputName = "/Event/Rec/ProtoP/Charged",
00231 InputName = "/Event/pRec/ProtoP/Charged")
00232 unpackNeutrals = UnpackProtoParticle(name = "UnpackNeutrals",
00233 OutputName = "/Event/Rec/ProtoP/Neutrals",
00234 InputName = "/Event/pRec/ProtoP/Neutrals")
00235
00236 DataOnDemandSvc().AlgMap[ "/Event/Rec/Track/Best" ] = unpackTracks
00237 DataOnDemandSvc().AlgMap[ "/Event/Rec/Track/Muon" ] = unpackMuons
00238 DataOnDemandSvc().AlgMap[ "/Event/Rec/Calo/Electrons" ] = unpackElectrons
00239 DataOnDemandSvc().AlgMap[ "/Event/Rec/Calo/Photons" ] = unpackPhotons
00240 DataOnDemandSvc().AlgMap[ "/Event/Rec/Calo/MergedPi0s" ] = unpackMergedPi0s
00241 DataOnDemandSvc().AlgMap[ "/Event/Rec/Calo/SplitPhotons" ] = unpackSplitPhotons
00242 DataOnDemandSvc().AlgMap[ "/Event/Rec/ProtoP/Charged" ] = unpackCharged
00243 DataOnDemandSvc().AlgMap[ "/Event/Rec/ProtoP/Neutrals" ] = unpackNeutrals
00244 DataOnDemandSvc().AlgMap[ "/Event/Rec/Vertex/Primary" ] = unpackVertex
00245 DataOnDemandSvc().AlgMap[ "/Event/Rec/Vertex/V0" ] = unpackV0
00246
00247
00248 if self.getProp("SimType").capitalize() != "None":
00249 from Configurables import UnpackMCParticle, UnpackMCVertex
00250 DataOnDemandSvc().AlgMap[ "/Event/MC/Particles" ] = UnpackMCParticle()
00251 DataOnDemandSvc().AlgMap[ "/Event/MC/Vertices" ] = UnpackMCVertex()
00252
00253
00254 def __apply_configuration__(self):
00255 if self.getProp( "EnableUnpack" ) : self._doUnpack()
00256 if hasattr( self, "PackSequencer" ): self._doPack()
00257 GaudiKernel.ProcessJobOptions.PrintOn()
00258 self._doWrite()
00259 GaudiKernel.ProcessJobOptions.PrintOff()