def BranchObj(self, bname, typestr = None): obj = None if None == typestr: # ok, branch for reading b = self.tree.FindBranch(bname) if None == b: raise Exception('Unknown branch name \'%s\' in ' \ 'TTree \'%a\' requested.' % (bname, self.tree.GetName())) l = b.GetLeaf(bname) if None == l: raise Exception('Unknown leaf in branch in \'%s\' in ' \ 'TTree \'%a\' requested.' % (bname, self.tree.GetName())) typestr = l.GetTypeName() obj = getTypeFactory(typestr)() self.tree.SetBranchAddress(bname, obj) else: # new branch for writing b = self.tree.FindBranch(bname) if None != b: raise Exception('Branch \'%s\' already exists in ' \ 'TTree \'%s\'.' % (bname, self.tree.GetName())) obj = getTypeFactory(typestr)() bcallargs = (bname, obj) if isinstance(obj, ctypes._SimpleCData): # ok a POD type most likely, so ROOT needs telling what kind of # branch it's supposed to create if type(obj) not in self.__typedictPOD__: raise Exception('Unknown data type for branch \'%s\' in '\ 'tree \'%s\'' % (bname, self.tree.GetName())) bcallargs += ('%s/%s' % (bname, self.__typedictPOD__[type(obj)]),) self.tree.Branch(*bcallargs) self.branches[bname] = obj return obj
def createTree(filename, treename): from ROOT import TFile, TRandom3 from ROOT import DotLock, TimeStamp, VersionedObject from TypeHelper import getTypeFactory from GUITree import Tree # acquire write lock dl = DotLock(filename) # open file for writing (overwriting destination if it exists) f = TFile(filename, 'RECREATE') # be a bit more aggressive when compressing data: we're not CPU-limited # when writing tuple files, but we're happy to get by using up less disk # bandwidth f.SetCompressionSettings(ROOT.ROOT.CompressionSettings(ROOT.ROOT.kLZMA, 6)) # create tree with given structure t = Tree(treename, 'Velo DQ Tree prototype', { # define branch names and types 'runnr': 'UInt_t', # this never gets updated, so no VersionedObject here 'checked': 'VersionedObject<UShort_t, TimeStamp, std::greater<TimeStamp> >', 'comment': 'VersionedObject<std::string, TimeStamp, std::greater<TimeStamp> >', 'meanpedestal': 'VersionedObject<Float_t, TimeStamp, std::greater<TimeStamp> >', 'occupancy': 'VersionedObject<std::map<int,std::vector<Float_t> >, TimeStamp, std::greater<TimeStamp> >' }) # construct list of valid Velo sensor numbers sensors = tuple(xrange(0, 42)) sensors += tuple(xrange(64, 64 + 42)) sensors += tuple(xrange(128, 132)) # get RNG to generate some data to put into the tuple rnd = TRandom3() # fill tree, 64 entries for i in xrange(0, 64): # clear out data from last run t.comment.clear() t.occupancy.clear() t.meanpedestal.clear() # fill new run # step 1: generate time stamp (now) now = TimeStamp() # step 2: fill branches t.runnr = 100000 + i print 'Generating dummy DQ data for run %u' % t.runnr t.checked[now] = 0 t.comment[now] = 'initial DQ for run %u: UNCHECKED' % t.runnr t.meanpedestal[now] = rnd.Uniform(-5., 5.) # simulate about 3 permille dead, 5 permille noisy channels, and have # that fluctuate a bit fdead = rnd.Uniform(0.003, 0.002) if fdead < 0.: fdead = 0. fnoisy = rnd.Uniform(0.005,0.003) if fnoisy < 0.: fnoisy = 0. # ok, put the per-strip occupancies in for sensor in sensors: # vector of per-strip occupancies ov = getTypeFactory('std::vector<Float_t>')(2048, 0.) for strip in xrange(0, 2048): # simulate dead, noisy and normal strips tmp = rnd.Uniform(0., 1.) if tmp > (fdead + fnoisy): ov[strip] = rnd.Gaus(0.01, 0.0025) elif tmp > fnoisy: ov[strip] = rnd.Uniform(0., 1.) else: pass # zero anyway # put that strip vector for the current sensor into the current # version t.occupancy[now][sensor] = ov # step 3: fill tree t.Fill() # make sure tree is written to file t.Write() # close file del t f.Close() del f