Skip to content

Commit

Permalink
Added unit test functionality, removed dependence on Alignment/Tracke…
Browse files Browse the repository at this point in the history
…rAlignment package
  • Loading branch information
mteroerd committed Jun 20, 2023
1 parent e708d9b commit 580d39b
Show file tree
Hide file tree
Showing 14 changed files with 277 additions and 546 deletions.
2 changes: 1 addition & 1 deletion Alignment/APEEstimation/python/ApeEstimator_cfi.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
minGoodHitsPerTrack = cms.uint32(0),

#File containing TrackerTree with ideal Geometry
TrackerTreeFile = cms.string(os.environ['CMSSW_BASE'] + '/src/Alignment/TrackerAlignment/hists/TrackerTree.root'),
TrackerTreeFile = cms.string(os.environ['CMSSW_BASE'] + '/src/Alignment/APEEstimation/hists/TrackerTree.root'),

#Sectors defining set of modules for common overview plots resp. APE values
Sectors = cms.VPSet(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import FWCore.ParameterSet.Config as cms

maxEvents = cms.untracked.PSet( input = cms.untracked.int32(-1) )
readFiles = cms.untracked.vstring()
secFiles = cms.untracked.vstring()
source = cms.Source ("PoolSource",fileNames = readFiles, secondaryFileNames = secFiles)


readFiles.extend( [
"/store/mc/Run3Winter22DRPremix/WJetsToLNu_TuneCP5_13p6TeV-madgraphMLM-pythia8/ALCARECO/TkAlMuonIsolated-TRKALCADesign_design_geometry_122X_mcRun3_2021_design_v9-v2/2520000/0027e6ed-2626-4ede-97a5-f0a44164b81b.root",
"/store/mc/Run3Winter22DRPremix/WJetsToLNu_TuneCP5_13p6TeV-madgraphMLM-pythia8/ALCARECO/TkAlMuonIsolated-TRKALCADesign_design_geometry_122X_mcRun3_2021_design_v9-v2/2520000/00899b9d-32ab-46f2-b77b-0b0a8d666027.root",
"/store/mc/Run3Winter22DRPremix/WJetsToLNu_TuneCP5_13p6TeV-madgraphMLM-pythia8/ALCARECO/TkAlMuonIsolated-TRKALCADesign_design_geometry_122X_mcRun3_2021_design_v9-v2/2520000/07851676-0c65-4630-bbab-7406defeb670.root",
"/store/mc/Run3Winter22DRPremix/WJetsToLNu_TuneCP5_13p6TeV-madgraphMLM-pythia8/ALCARECO/TkAlMuonIsolated-TRKALCADesign_design_geometry_122X_mcRun3_2021_design_v9-v2/2520000/0a54c512-0f69-44e1-90bc-16da035cbe02.root",
] );



secFiles.extend( [
] )

2 changes: 0 additions & 2 deletions Alignment/APEEstimation/scripts/initialise.bash
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

DIRBASE="$CMSSW_BASE/src/Alignment/APEEstimation"

mkdir $CMSSW_BASE/src/Alignment/TrackerAlignment/hists/

mkdir $DIRBASE/hists/
mkdir $DIRBASE/hists/workingArea/
mkdir $DIRBASE/hists/workingArea/apeObjects/
Expand Down
3 changes: 3 additions & 0 deletions Alignment/APEEstimation/test/BuildFile.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<environment>
<test name="ApeTest" command="bash unitTest.sh"/>
</environment>
46 changes: 9 additions & 37 deletions Alignment/APEEstimation/test/SkimProducer/skimProducer_cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,11 @@
import sys
options = VarParsing.VarParsing ('standard')
options.register('sample', 'data1', VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.string, "Input sample")
options.register('useTrackList', False, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.bool, "Use list of preselected tracks")
options.register('isTest', False, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.bool, "Test run")

# get and parse the command line arguments
options.parseArguments()

print("Input sample: ", options.sample)
print("Use list of preselected tracks: ", options.useTrackList)
print("Test run: ", options.isTest)


##
Expand Down Expand Up @@ -79,11 +75,6 @@
outputName = 'MinBias.root'
#outputPath = "workingArea"
trackSelection = "MinBias"
if options.sample == 'data2':
process.load("Alignment.APEEstimation.samples.Data_TkAlMinBias_Run2018C_PromptReco_v3_cff")
outputName = 'MinBias1.root'
#outputPath = "workingArea"
trackSelection = "MinBias"
if options.sample == 'data3':
process.load("Alignment.APEEstimation.samples.Data_TkAlMuonIsolated_22Jan2013C_v1_cff")
outputName = 'Data_TkAlMuonIsolated_22Jan2013C.root'
Expand All @@ -104,22 +95,15 @@
outputPath = '/eos/cms/store/caf/user/jschulz/Skims/MC/UL2016ReRecoRealistic'
outputName = 'Mc_TkAlMuonIsolated_WJetsToLNu_2016.root'
trackSelection = "SingleMu"
if options.sample == 'zmumu':
process.load("")
outputName = ''
trackSelection = "DoubleMu"
if options.sample == 'zmumu10':
process.load("Alignment.APEEstimation.samples.Mc_TkAlMuonIsolated_Summer12_zmumu10_cff")
outputName = 'Mc_TkAlMuonIsolated_Summer12_zmumu10.root'
trackSelection = "DoubleMu"
if options.sample == 'zmumu20':
process.load("Alignment.APEEstimation.samples.Mc_TkAlMuonIsolated_Summer12_zmumu20_cff")
outputName = 'Mc_TkAlMuonIsolated_Summer12_zmumu20.root'
trackSelection = "DoubleMu"
if options.sample == 'zmumu50':
process.load("Alignment.APEEstimation.samples.DYToMuMu_M-50_Tune4C_13TeV-pythia8_Spring14dr-TkAlMuonIsolated-castor_PU_S14_POSTLS170_V6-v1_ALCARECO_cff")
outputName = 'Mc_DYToMuMu_M-50_Tune4C_13TeV-pythia8_Spring14dr-TkAlMuonIsolated-castor_PU_S14_POSTLS170_V6-v1.root'
trackSelection = "DoubleMu"

# For unit tests
if options.sample == 'UnitTest':
process.load("Alignment.APEEstimation.samples.MC_UnitTest_TkAlMuonIsolated_cff")
outputName = 'MC_UnitTest_TkAlMuonIsolated.root'
outputFile = 1000000
maxEvents = 100000
globalTag = "auto:phase1_2022_design"
trackSelection = "SingleMu"


print("Using output name %s"%(outputName))
Expand Down Expand Up @@ -148,7 +132,6 @@
## Number of Events (should be after input file)
##
process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(maxEvents) )
if options.isTest: process.maxEvents.input = 1001


##
Expand Down Expand Up @@ -177,13 +160,6 @@

process.MuSkim = trackSelector

##
## If preselected track list is used
##
if options.useTrackList:
process.MuSkim.src = 'TrackList'
process.TriggerSelectionSequence *= process.TrackList

import Alignment.CommonAlignment.tools.trackselectionRefitting as trackselRefit
process.seqTrackselRefit = trackselRefit.getSequence(process, trackSelector.src.getModuleLabel())

Expand Down Expand Up @@ -226,10 +202,6 @@
process.out.outputCommands.extend(process.ApeSkimEventContent.outputCommands)


if options.isTest:
process.out.fileName = os.environ['CMSSW_BASE'] + '/src/Alignment/APEEstimation/hists/test_apeSkim.root'


##
## Outpath
##
Expand Down
6 changes: 3 additions & 3 deletions Alignment/APEEstimation/test/SkimProducer/startSkim.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def condorSubmitSkim(sample, caf=False):
def localStartSkim(sample):
base = os.environ['CMSSW_BASE']

execString = "cmsRun {base}/src/Alignment/APEEstimation/test/SkimProducer/skimProducer_cfg.py isTest=False useTrackList=False sample={sample}".format(sample=sample, base=base)
execString = "cmsRun {base}/src/Alignment/APEEstimation/test/SkimProducer/skimProducer_cfg.py sample={sample}".format(sample=sample, base=base)
print(execString)
toExec = execString.split(" ")

Expand All @@ -73,7 +73,7 @@ def localStartSkim(sample):

def get_output(proc):
while True:
line = proc.stdout.readline().rstrip()
line = proc.stdout.readline().rstrip().decode()
if not line:
break
yield line
Expand Down Expand Up @@ -153,7 +153,7 @@ def main(argv):

if len(args.samples) == 0:
print("Usage: python startSkim.py -s <sample>")
sys.exit()
sys.exit(1)

finalSamples = []
for sample in args.samples:
Expand Down
60 changes: 30 additions & 30 deletions Alignment/APEEstimation/test/autoSubmitter/autoSubmitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class Dataset:
def __init__(self, config, name):
dsDict = dict(config.items("dataset:{}".format(name)))
self.name = name
self.baseDirectory = dsDict["baseDirectory"]
self.baseDirectory = dsDict["baseDirectory"].replace("$CMSSW_BASE", os.environ['CMSSW_BASE'])

self.fileList = []
names = dsDict["fileNames"].split(" ")
Expand All @@ -54,7 +54,7 @@ def __init__(self, config, name):
if "isCosmics" in dsDict:
self.isCosmics = (dsDict["isCosmics"] == "True")

self.conditions, dummy, self.validConditions = loadConditions(dsDict)
self.conditions, self.validConditions = loadConditions(dsDict)

# check if any of the sources used for conditions is invalid
if not self.validConditions:
Expand All @@ -72,9 +72,6 @@ def __init__(self, config, name):
alDict = dict(config.items("alignment:{}".format(name)))
self.name = name

alignmentName = None
if "alignmentName" in alDict:
self.alignmentName = alDict["alignmentName"]
self.globalTag = "None"
if "globalTag" in alDict:
self.globalTag = alDict["globalTag"]
Expand All @@ -85,19 +82,13 @@ def __init__(self, config, name):
if "isDesign" in alDict:
self.isDesign= (alDict["isDesign"] == "True")

# If self.hasAlignmentCondition is true, no other Alignment-Object is loaded in apeEstimator_cfg.py using the alignmentName
self.conditions, self.hasAlignmentCondition, self.validConditions = loadConditions(alDict)
# If self.hasAlignmentCondition is true, no other Alignment-Object is loaded in apeEstimator_cfg.py using the
self.conditions, self.validConditions = loadConditions(alDict)

# check if any of the sources used for conditions is invalid
if not self.validConditions:
print("Invalid conditions defined for alignment {}".format(self.name))

# check if at least one of the two ways to define the alignment was used
# for baseline (Design) measurements, this is not needed, as we usually take conditions from GT
if self.alignmentName == None and not self.hasAlignmentCondition and not self.isDesign:
print("Error: No alignment object name or record was defined for alignment {}".format(self.name))
sys.exit()


class ApeMeasurement:
name = "workingArea"
Expand Down Expand Up @@ -139,7 +130,7 @@ def __init__(self, name, config, settings):
if self.alignment.isDesign:
self.maxIterations = 0

self.conditions, dummy, self.validConditions = loadConditions(settings)
self.conditions, self.validConditions = loadConditions(settings)

# see if sanity checks passed
if not self.alignment.validConditions or not self.dataset.validConditions or not self.dataset.existingFiles or not self.validConditions:
Expand Down Expand Up @@ -188,9 +179,7 @@ def submitJobs(self):
for condition in allConditions:
fi.write(conditionsTemplate.format(record=condition["record"], connect=condition["connect"], tag=condition["tag"]))

alignmentNameToUse = self.alignment.alignmentName
if self.alignment.hasAlignmentCondition:
alignmentNameToUse = "fromConditions"
alignmentNameToUse = "fromConditions"

lastIter = (self.curIteration==self.maxIterations) and not self.alignment.isDesign

Expand Down Expand Up @@ -437,6 +426,7 @@ def runIteration(self):
self.finishIteration()
save("measurements", measurements)
# go to next iteration or finish measurement

if self.status_ == STATE_BJOBS_FAILED or \
self.status_ == STATE_MERGE_FAILED or \
self.status_ == STATE_SUMMARY_FAILED or \
Expand All @@ -452,6 +442,9 @@ def runIteration(self):
else:
global failed_measurements
failed_measurements[self.name] = self
if unitTest:
os._exit(self.status_)

self.setStatus(STATE_NONE)
save("failed", failed_measurements)
save("measurements", measurements)
Expand Down Expand Up @@ -479,6 +472,8 @@ def main():
help='Number of threads running in parallel')
parser.add_argument("-C", "--caf",action="store_true", dest="caf", default=False,
help="Use CAF queue for condor jobs")
parser.add_argument("-u", "--unitTest", action="store_true", dest="unitTest", default=False,
help='If this is used, as soon as a measurement fails, the program will exit and as exit code the status of the measurement, i.e., where it failed')
args = parser.parse_args()

global base
Expand All @@ -487,6 +482,9 @@ def main():
global threadcounter
global lock
global use_caf
global unitTest

unitTest = args.unitTest

use_caf = args.caf
enableCAF(use_caf)
Expand Down Expand Up @@ -565,7 +563,7 @@ def main():

measurement = ApeMeasurement(name, config, settings)

if measurement.status_ >= STATE_ITERATION_START and measurement.status_ <= STATE_FINISHED:
if measurement.status_ >= STATE_ITERATION_START:
measurements.append(measurement)
print("APE Measurement {} was started".format(measurement.name))

Expand All @@ -590,19 +588,21 @@ def main():
print("No APE measurements are active, exiting")
sys.exit(0)

try: # so that interrupting does not give an error message and just ends the program
time_remaining = clock_interval
while time_remaining > 0:
print("Sleeping for {} seconds, you can safely [CTRL+C] now".format(time_remaining))
time.sleep(1)
time_remaining -= 1
if not unitTest:
try: # so that interrupting does not give an error message and just ends the program
time_remaining = clock_interval
while time_remaining > 0:
print("Sleeping for {} seconds, you can safely [CTRL+C] now".format(time_remaining))
time.sleep(1)
time_remaining -= 1
sys.stdout.write("\033[F")
sys.stdout.write("\033[K")
print("")
sys.stdout.write("\033[F")
sys.stdout.write("\033[K")
print("")
sys.stdout.write("\033[F")
sys.stdout.write("\033[K")
except KeyboardInterrupt:
sys.exit(0)

except KeyboardInterrupt:
sys.exit(0)
else:
time.sleep(clock_interval)
if __name__ == "__main__":
main()
7 changes: 1 addition & 6 deletions Alignment/APEEstimation/test/autoSubmitter/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ def hasValidSource(condition):
return False

def loadConditions(dictionary):
hasAlignmentCondition = False
goodConditions = True
conditions = []
for key, value in dictionary.items():
Expand All @@ -171,8 +170,6 @@ def loadConditions(dictionary):
# structure is "condition rcd:source tag"
record = key.split(" ")[1]
connect, tag = value.split(" ")
if record == "TrackerAlignmentRcd":
hasAlignmentCondition = True
conditions.append({"record":record, "connect":replaceShortcuts(connect), "tag":tag})
elif len(value.split(" ")) == 1 and len(key.split(" ")) == 2:
# structure is "condition tag:source", so we have to guess rcd from the tag. might also be "condition tag1+tag2+...+tagN:source"
Expand All @@ -183,8 +180,6 @@ def loadConditions(dictionary):
for possibleTag, possibleRcd in records.items():
if tag.startswith(possibleTag):
conditions.append({"record":possibleRcd, "connect":replaceShortcuts(connect), "tag":tag})
if possibleRcd == "TrackerAlignmentRcd":
hasAlignmentCondition = True
foundTag = True
break
if not foundTag:
Expand All @@ -202,4 +197,4 @@ def loadConditions(dictionary):
if not condition["record"].endswith("Rcd"):
goodConditions = False
print("'{}' is not a valid record name.".format(condition["record"]))
return conditions, hasAlignmentCondition, goodConditions
return conditions, goodConditions
12 changes: 12 additions & 0 deletions Alignment/APEEstimation/test/autoSubmitter/unitTest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[dataset:wlnu]
baseDirectory=$CMSSW_BASE/src/Alignment/APEEstimation/test
fileNames=MC_UnitTest_TkAlMuonIsolated_1.root
isMC=True

[alignment:FromGT]
globalTag=auto:phase1_2022_design
isDesign=True

[ape:Design]
dataset: wlnu
alignment: FromGT
Loading

0 comments on commit 580d39b

Please sign in to comment.