def findSample(args): # signal if 'HTo2XTo4Mu' in args.NAME or 'HTo2XTo2Mu2J' in args.NAME: samples = getattr(DH, 'get' + args.NAME + 'Samples')() SIGNALPOINT = tuple(args.SIGNALPOINT) DKEY = 'PAT' if args.GENONLY: DKEY = 'GEN' if args.AODONLY: DKEY = 'AOD' DATASET = DEFAULT_DATASETS[args.NAME][DKEY] for data in samples: if data.signalPoint() == SIGNALPOINT and DATASET in data.datasets: return data else: print '[DATAHANDLER ERROR]: No {} dataset found with signal point {} and process {}'.format( args.NAME, SIGNALPOINT, DATASET) exit() # DoubleMuon data elif args.NAME.startswith('DoubleMuon'): samples = DH.getDoubleMuonDataSamples() for data in samples: if data.name == args.NAME: return data # Cosmics data elif args.NAME.startswith('Cosmics'): samples = DH.getCosmicsDataSamples() for data in samples: if data.name == args.NAME: return data # NoBPTX data elif args.NAME.startswith('NoBPTX'): samples = DH.getNoBPTXDataSamples() for data in samples: if data.name == args.NAME: return data # background else: samples = DH.getBackgroundSamples() for data in samples: if data.name == args.NAME: return data # if nothing found yet, raise error print '[DATAHANDLER ERROR]: "' + args.NAME + '" is not a known dataset name; see .dat files in dat/' exit()
import re, itertools import DisplacedDimuons.Common.DataHandler as DH ##### Place the output of this script, "SignalMCSamples.dat", in ../dat ##### It is required by the DataHandler library for signal samples ##### and therefore by Tupler and by Analysis # gets HTo2LongLivedTo4mu and HTo2LongLivedTo2mu2jets dataset strings AODDatasetStrings = DH.DASQueryList( 'dataset=/HTo2LongLivedTo*_MH-*_MFF-*_CTau-*/escalant-April2019reHLT-AOD-v1*/* instance=prod/phys03' ) # gets PAT Tuple datasets -- there may be many of these, and the regexes may have to be tweaked to be unique PATDatasetStrings = DH.DASQueryList( 'dataset=/HTo2LongLivedTo*_MH-*_MFF-*_CTau-*/stempl-MC2016_*reHLT_Apr2019-v4*/* instance=prod/phys03' ) # matches dataset string with six groups: final state (4mu or 2mu2jets), mH, mX, cTau (digits 1-4), process string (\S*), weird hash ID (\w*) # apply these to AODDatasetStrings rxAOD = re.compile( r'/HTo2LongLivedTo(4mu|2mu2jets)_MH-(\d{1,4})_MFF-(\d{1,4})_CTau-(\d{1,4})mm\S*pythia8/escalant-(\S*)-(\w*)/USER' ) # matches PAT Tupler dataset string with five groups: final state (4mu or 2mu2jets), mH, mX, cTau (digits 1-4), weird hash ID (\w*) # apply these to PATDatasetStrings # rxPAT = re.compile(r'/HTo2LongLivedTo(4mu|2mu2jets)_MH-(\d{1,4})_MFF-(\d{1,4})_CTau-(\d{1,4})mm\S*pythia8/stempl-MC2016_\S*_reHLT\S*_Jun2019-v4-(\w*)/USER') rxPAT = re.compile( r'/HTo2LongLivedTo(4mu|2mu2jets)_MH-(\d{1,4})_MFF-(\d{1,4})_CTau-(\d{1,4})mm\S*pythia8/stempl-MC2016_\S*_reHLT_Apr2019-v4-(\w*)/USER' ) # fill a list with split up metadata that will be sorted
import DisplacedDimuons.Common.DataHandler as DH FINALSTATE = '4Mu' SIGNALPOINT = (125, 20, 13) PROCESS = 'AODSIM-ReHLT_V37-v1' datasets = getattr(DH, 'getHTo2XTo' + FINALSTATE + 'Samples')() for data in datasets: if data.signalPoint() == SIGNALPOINT: if PROCESS in data.datasets: fleList = DH.DASQueryList( 'file,lumi,events dataset={} instance={}'.format( data.datasets[PROCESS], data.instances[PROCESS])) totalE = 0 for rstring in fleList: cols = rstring.split() f = cols[0] l = map(int, cols[1].strip('[').strip(']').split(',')) e = map(int, cols[2].strip('[').strip(']').split(',')) totalE += sum(e) print 'HTo2XTo{} : {} : {} :: {} events'.format( FINALSTATE, SIGNALPOINT, PROCESS, totalE) else: raise Exception( 'No HTo2XTo{} dataset found with signal point {} and process {}' .format(FINALSTATE, SIGNALPOINT, PROCESS))
dest='TRIGGER', action='store_true', help='apply trigger to signal') PARSER.add_argument('--cuts', dest='CUTS', default='', help='cut string') PARSER.add_argument('--skim', dest='SKIM', action='store_true', help='whether to use the skim file') # important setSample function # this function takes the inputs from ARGS and selects the unique matching Dataset from DataHandler # this Dataset object contains many important parameters: nEvents, negFrac, systFrac, etc # and they are available to the Analyzer object through the member variable SAMPLE # so if e.g. a weight in the analyze() function is desired, it is as simple as # using self.SAMPLE.nEvents or self.SAMPLE.negFrac SAMPLES = DH.getAllSamples() def setSample(ARGS): if ARGS.NAME.startswith('HTo2X') or ARGS.NAME.startswith('reHLT_HTo2X'): if ARGS.SIGNALPOINT is None: raise Exception('Need a signal point for HTo2X MC signal.') ARGS.SAMPLE = SAMPLES[ARGS.NAME + '_' + Utilities.SPStr(ARGS.SIGNALPOINT)] else: ARGS.SAMPLE = SAMPLES[ARGS.NAME] # Analyzer class, one instance per sample, runs over a tree, calls analysis functions class Analyzer(object): # constructor:
for mH, mX, cTau in SIGNALPOINTS: verbose('GEN ONLY SIGNAL {} : {} {} {}'.format('HTo2XTo2Mu2J', mH, mX, cTau)) bash.call('python runNTupler.py HTo2XTo2Mu2J --signalpoint {mH} {mX} {cTau} --genonly {MODE}'.format(**locals()), shell=True) # submit all HTo2XTo2Mu2J signal aod only jobs if Do_2Mu2J_AODOnly: for mH, mX, cTau in SIGNALPOINTS: verbose('AOD ONLY SIGNAL {} : {} {} {}'.format('HTo2XTo2Mu2J', mH, mX, cTau)) bash.call('python runNTupler.py HTo2XTo2Mu2J --signalpoint {mH} {mX} {cTau} --aodonly {MODE}'.format(**locals()), shell=True) # submit all HTo2XTo2Mu2J signal PAT Tuple jobs if Do_2Mu2J: for mH, mX, cTau in SIGNALPOINTS: verbose('SIGNAL {} : {} {} {}'.format('HTo2XTo2Mu2J', mH, mX, cTau)) bash.call('python runNTupler.py HTo2XTo2Mu2J --signalpoint {mH} {mX} {cTau} {MODE}'.format(**locals()), shell=True) # submit all background MC jobs if Do_Background: mcSamples = DH.getBackgroundSamples() for data in mcSamples: verbose('BACKGROUND : {}'.format(data.name)) if data.datasets['PAT'] == '_': continue bash.call('python runNTupler.py {NAME} {MODE}'.format(NAME=data.name, MODE=MODE), shell=True) # submit all data jobs if Do_Data: dataSamples = DH.getDoubleMuonDataSamples() for data in dataSamples: verbose('DATA : {}'.format(data.name)) bash.call('python runNTupler.py {NAME} {MODE}'.format(NAME=data.name, MODE=MODE), shell=True)