3 from __future__
import print_function
4 from builtins
import range
5 import os, sys, optparse, math
8 for i
in range(len(copyargs)):
11 if copyargs[i].
find(
" ") != -1:
12 copyargs[i] =
"\"%s\"" % copyargs[i]
13 commandline =
" ".
join(copyargs)
17 usage =
"""./%(prog)s DIRNAME ITERATIONS INITIALGEOM INPUTFILES [options]
19 Creates (overwrites) a directory for each of the iterations and creates (overwrites)
20 submitJobs.sh with the submission sequence and dependencies.
22 DIRNAME directories will be named DIRNAME01, DIRNAME02...
23 ITERATIONS number of iterations
24 INITIALGEOM SQLite file containing muon geometry with tag names
25 DTAlignmentRcd, DTAlignmentErrorExtendedRcd, CSCAlignmentRcd, CSCAlignmentErrorExtendedRcd
26 INPUTFILES Python file defining 'fileNames', a list of input files as
27 strings (create with findQualityFiles.py)""" % vars()
29 parser = optparse.OptionParser(usage)
30 parser.add_option(
"--validationLabel",
31 help=
"[REQUIRED] the label to be used to mark a run; the results will be put into a LABEL_DATESTAMP.tgz tarball",
34 dest=
"validationLabel")
35 parser.add_option(
"-j",
"--jobs",
36 help=
"approximate number of \"gather\" subjobs",
40 parser.add_option(
"-s",
"--submitJobs",
41 help=
"alternate name of submitJobs.sh script (please include .sh extension); a file with this name will be OVERWRITTEN",
43 default=
"submitJobs.sh",
45 parser.add_option(
"-b",
"--big",
46 help=
"if invoked, subjobs will also be run on cmscaf1nd",
49 parser.add_option(
"--globalTag",
50 help=
"GlobalTag for alignment/calibration conditions (typically all conditions except muon and tracker alignment)",
52 default=
"CRAFT0831X_V1::All",
54 parser.add_option(
"--trackerconnect",
55 help=
"connect string for tracker alignment (frontier://... or sqlite_file:...)",
58 dest=
"trackerconnect")
59 parser.add_option(
"--trackeralignment",
60 help=
"name of TrackerAlignmentRcd tag",
63 dest=
"trackeralignment")
64 parser.add_option(
"--trackerAPEconnect",
65 help=
"connect string for tracker APEs (frontier://... or sqlite_file:...)",
68 dest=
"trackerAPEconnect")
69 parser.add_option(
"--trackerAPE",
70 help=
"name of TrackerAlignmentErrorExtendedRcd tag (tracker APEs)",
72 default=
"AlignmentErrorsExtended",
74 parser.add_option(
"--gprcdconnect",
75 help=
"connect string for GlobalPositionRcd (frontier://... or sqlite_file:...)",
79 parser.add_option(
"--gprcd",
80 help=
"name of GlobalPositionRcd tag",
82 default=
"GlobalPosition",
84 parser.add_option(
"--iscosmics",
85 help=
"if invoked, use cosmic track refitter instead of the standard one",
88 parser.add_option(
"--station123params",
89 help=
"alignable parameters for DT stations 1, 2, 3 (see SWGuideAlignmentAlgorithms#Selection_of_what_to_align)",
92 dest=
"station123params")
93 parser.add_option(
"--station4params",
94 help=
"alignable parameters for DT station 4",
97 dest=
"station4params")
98 parser.add_option(
"--cscparams",
99 help=
"alignable parameters for CSC chambers",
103 parser.add_option(
"--minTrackPt",
104 help=
"minimum allowed track transverse momentum (in GeV)",
108 parser.add_option(
"--maxTrackPt",
109 help=
"maximum allowed track transverse momentum (in GeV)",
113 parser.add_option(
"--minTrackP",
114 help=
"minimum allowed track momentum (in GeV)",
118 parser.add_option(
"--maxTrackP",
119 help=
"maximum allowed track momentum (in GeV)",
123 parser.add_option(
"--minTrackerHits",
124 help=
"minimum number of tracker hits",
127 dest=
"minTrackerHits")
128 parser.add_option(
"--maxTrackerRedChi2",
129 help=
"maximum tracker chi^2 per degrees of freedom",
132 dest=
"maxTrackerRedChi2")
133 parser.add_option(
"--notAllowTIDTEC",
134 help=
"if invoked, do not allow tracks that pass through the tracker's TID||TEC region (not recommended)",
136 dest=
"notAllowTIDTEC")
137 parser.add_option(
"--twoBin",
138 help=
"if invoked, apply the \"two-bin method\" to control charge-antisymmetric errors",
141 parser.add_option(
"--weightAlignment",
142 help=
"if invoked, segments will be weighted by ndf/chi^2 in the alignment",
144 dest=
"weightAlignment")
145 parser.add_option(
"--minAlignmentSegments",
146 help=
"minimum number of segments required to align a chamber",
149 dest=
"minAlignmentHits")
150 parser.add_option(
"--notCombineME11",
151 help=
"if invoked, treat ME1/1a and ME1/1b as separate objects",
153 dest=
"notCombineME11")
154 parser.add_option(
"--maxEvents",
155 help=
"maximum number of events",
159 parser.add_option(
"--skipEvents",
160 help=
"number of events to be skipped",
164 parser.add_option(
"--maxResSlopeY",
165 help=
"maximum residual slope y component",
169 parser.add_option(
"--ring2only",
170 help=
"if invoked, use only ring 2 results to align all rings in corresponding disks",
173 parser.add_option(
"--createMapNtuple",
174 help=
"if invoked while mapplots are switched on, a special ntuple would be created",
176 dest=
"createMapNtuple")
177 parser.add_option(
"--inputInBlocks",
178 help=
"if invoked, assume that INPUTFILES provides a list of files already groupped into job blocks, -j has no effect in that case",
180 dest=
"inputInBlocks")
181 parser.add_option(
"--json",
182 help=
"If present with JSON file as argument, use JSON file for good lumi mask. "+\
183 "The latest JSON file is available at /afs/cern.ch/cms/CAF/CMSCOMM/COMM_DQM/certification/Collisions11/7TeV/Prompt/",
187 parser.add_option(
"--preFilter",
188 help=
"if invoked, MuonAlignmentPreFilter module would be invoked in the Path's beginning. Can significantly speed up gather jobs.",
191 parser.add_option(
"--useTrackerMuons",
192 help=
"use tracker muons approach instead of the default global muons tracks based one",
194 dest=
"useTrackerMuons")
195 parser.add_option(
"--muonCollectionTag",
196 help=
"InputTag of muons collection to use in tracker muons based approach",
199 dest=
"muonCollectionTag")
200 parser.add_option(
"--maxDxy",
201 help=
"maximum track impact parameter with relation to beamline",
205 parser.add_option(
"--minNCrossedChambers",
206 help=
"minimum number of muon chambers that a track is required to cross",
209 dest=
"minNCrossedChambers")
211 if len(sys.argv) < 5:
212 raise SystemError(
"Too few arguments.\n\n"+parser.format_help())
214 DIRNAME = sys.argv[1]
215 ITERATIONS =
int(sys.argv[2])
216 INITIALGEOM = sys.argv[3]
217 INPUTFILES = sys.argv[4]
219 options, args = parser.parse_args(sys.argv[5:])
220 globaltag = options.globaltag
221 trackerconnect = options.trackerconnect
222 trackeralignment = options.trackeralignment
223 trackerAPEconnect = options.trackerAPEconnect
224 trackerAPE = options.trackerAPE
225 gprcdconnect = options.gprcdconnect
226 gprcd = options.gprcd
227 iscosmics =
str(options.iscosmics)
228 station123params = options.station123params
229 station4params = options.station4params
230 cscparams = options.cscparams
231 muonCollectionTag = options.muonCollectionTag
232 minTrackPt = options.minTrackPt
233 maxTrackPt = options.maxTrackPt
234 minTrackP = options.minTrackP
235 maxTrackP = options.maxTrackP
236 maxDxy = options.maxDxy
237 minTrackerHits =
str(options.minTrackerHits)
238 maxTrackerRedChi2 = options.maxTrackerRedChi2
239 minNCrossedChambers = options.minNCrossedChambers
240 allowTIDTEC =
str(
not options.notAllowTIDTEC)
241 twoBin =
str(options.twoBin)
242 weightAlignment =
str(options.weightAlignment)
243 minAlignmentHits =
str(options.minAlignmentHits)
244 combineME11 =
str(
not options.notCombineME11)
245 maxEvents = options.maxEvents
246 skipEvents = options.skipEvents
247 validationLabel = options.validationLabel
248 maxResSlopeY = options.maxResSlopeY
249 preFilter =
not not options.preFilter
250 useTrackerMuons = options.useTrackerMuons
252 createMapNtuple=
False
253 if options.createMapNtuple: createMapNtuple=
True
256 if options.ring2only: ring2only =
"--ring2only"
258 if options.inputInBlocks: inputInBlocks =
"--inputInBlocks"
260 json_file = options.json
262 if validationLabel ==
'':
263 print(
"\nOne or more of REQUIRED options is missing!\n")
270 njobs = options.subjobs
271 if (options.inputInBlocks):
272 njobs = len(fileNamesBlocks)
274 print(
"while --inputInBlocks is specified, the INPUTFILES has no blocks!")
277 stepsize =
int(math.ceil(1.*len(fileNames)/njobs))
281 bsubfile = [
"#!/bin/sh",
""]
287 INITIALXML = INITIALGEOM +
'.xml'
288 if INITIALGEOM[-3:]==
'.db':
289 INITIALXML = INITIALGEOM[:-3] +
'.xml'
290 print(
"Converting",INITIALGEOM,
"to",INITIALXML,
" ...will be done in several seconds...")
291 exit_code = os.system(
"./Alignment/MuonAlignmentAlgorithms/scripts/convertSQLiteXML.py %s %s" % (INITIALGEOM,INITIALXML))
293 print(
"problem: conversion exited with code:", exit_code)
300 for iteration
in range(1, ITERATIONS+1):
302 inputdb = INITIALGEOM
303 inputdbdir = directory[:]
304 inputxml = INITIALXML
306 inputdb = director +
".db"
307 inputdbdir = directory[:]
308 inputxml = director +
".xml"
310 directory =
"%s%02d/" % (DIRNAME, iteration)
311 director = directory[:-1]
312 directory1 =
"%s01/" % DIRNAME
313 director1 = directory1[:-1]
314 os.system(
"rm -rf %s; mkdir %s" % (directory, directory))
315 os.system(
"cp gather_cfg.py %s" % directory)
318 bsubfile.append(
"cd %s" % directory)
320 for jobnumber
in range(njobs):
321 gather_fileName =
"%sgather%03d.sh" % (directory, jobnumber)
322 if not options.inputInBlocks:
323 inputfiles =
" ".
join(fileNames[jobnumber*stepsize:(jobnumber+1)*stepsize])
325 inputfiles =
" ".
join(fileNamesBlocks[jobnumber])
327 copyplots =
"plotting*.root"
330 if trackerconnect[0:12] ==
"sqlite_file:": copytrackerdb +=
"%s " % trackerconnect[12:]
331 if trackerAPEconnect[0:12] ==
"sqlite_file:": copytrackerdb +=
"%s " % trackerAPEconnect[12:]
332 if gprcdconnect[0:12] ==
"sqlite_file:": copytrackerdb +=
"%s " % gprcdconnect[12:]
334 if len(inputfiles) > 0:
335 file(gather_fileName,
"w").
write(
"""#/bin/sh
338 export ALIGNMENT_CAFDIR=`pwd`
341 eval `scramv1 run -sh`
342 export ALIGNMENT_AFSDIR=`pwd`
344 export ALIGNMENT_INPUTFILES='%(inputfiles)s'
345 export ALIGNMENT_ITERATION=%(iteration)d
346 export ALIGNMENT_JOBNUMBER=%(jobnumber)d
347 export ALIGNMENT_MAPPLOTS=True
348 export ALIGNMENT_SEGDIFFPLOTS=True
349 export ALIGNMENT_CURVATUREPLOTS=False
350 export ALIGNMENT_GLOBALTAG=%(globaltag)s
351 export ALIGNMENT_INPUTDB=%(inputdb)s
352 export ALIGNMENT_TRACKERCONNECT=%(trackerconnect)s
353 export ALIGNMENT_TRACKERALIGNMENT=%(trackeralignment)s
354 export ALIGNMENT_TRACKERAPECONNECT=%(trackerAPEconnect)s
355 export ALIGNMENT_TRACKERAPE=%(trackerAPE)s
356 export ALIGNMENT_GPRCDCONNECT=%(gprcdconnect)s
357 export ALIGNMENT_GPRCD=%(gprcd)s
358 export ALIGNMENT_ISCOSMICS=%(iscosmics)s
359 export ALIGNMENT_STATION123PARAMS=%(station123params)s
360 export ALIGNMENT_STATION4PARAMS=%(station4params)s
361 export ALIGNMENT_CSCPARAMS=%(cscparams)s
362 export ALIGNMENT_MUONCOLLECTIONTAG=%(muonCollectionTag)s
363 export ALIGNMENT_MINTRACKPT=%(minTrackPt)s
364 export ALIGNMENT_MAXTRACKPT=%(maxTrackPt)s
365 export ALIGNMENT_MINTRACKP=%(minTrackP)s
366 export ALIGNMENT_MAXTRACKP=%(maxTrackP)s
367 export ALIGNMENT_MAXDXY=%(maxDxy)s
368 export ALIGNMENT_MINTRACKERHITS=%(minTrackerHits)s
369 export ALIGNMENT_MAXTRACKERREDCHI2=%(maxTrackerRedChi2)s
370 export ALIGNMENT_MINNCROSSEDCHAMBERS=%(minNCrossedChambers)s
371 export ALIGNMENT_ALLOWTIDTEC=%(allowTIDTEC)s
372 export ALIGNMENT_TWOBIN=%(twoBin)s
373 export ALIGNMENT_WEIGHTALIGNMENT=%(weightAlignment)s
374 export ALIGNMENT_MINALIGNMENTHITS=%(minAlignmentHits)s
375 export ALIGNMENT_COMBINEME11=%(combineME11)s
376 export ALIGNMENT_MAXEVENTS=%(maxEvents)s
377 export ALIGNMENT_SKIPEVENTS=%(skipEvents)s
378 export ALIGNMENT_MAXRESSLOPEY=%(maxResSlopeY)s
379 export ALIGNMENT_DO_DT='False'
380 export ALIGNMENT_DO_CSC='True'
381 export ALIGNMENT_JSON=%(json_file)s
382 export ALIGNMENT_CREATEMAPNTUPLE=%(createMapNtuple)s
383 export ALIGNMENT_PREFILTER=%(preFilter)s
384 export ALIGNMENT_USETRACKERMUONS=%(useTrackerMuons)s
386 if [ \"zzz$ALIGNMENT_JSON\" != \"zzz\" ]; then
387 cp -f $ALIGNMENT_JSON $ALIGNMENT_CAFDIR/
390 cp -f %(directory)sgather_cfg.py %(inputdbdir)s%(inputdb)s %(copytrackerdb)s $ALIGNMENT_CAFDIR/
391 cd $ALIGNMENT_CAFDIR/
395 cp -f %(copyplots)s $ALIGNMENT_AFSDIR/%(directory)s
397 os.system(
"chmod +x %s" % gather_fileName)
398 bsubfile.append(
"echo %sgather%03d.sh" % (directory, jobnumber))
400 if last_align
is None: waiter =
""
401 else: waiter =
"-w \"ended(%s)\"" % last_align
402 if options.big: queue =
"cmscaf1nd"
403 else: queue =
"cmscaf1nh"
405 bsubfile.append(
"bsub -R \"type==SLC5_64\" -q %s -J \"%s_gather%03d\" %s gather%03d.sh" % (queue, director, jobnumber, waiter, jobnumber))
407 bsubnames.append(
"ended(%s_gather%03d)" % (director, jobnumber))
410 if trackerconnect[0:12] ==
"sqlite_file:": copytrackerdb +=
"%s " % trackerconnect[12:]
411 if trackerAPEconnect[0:12] ==
"sqlite_file:": copytrackerdb +=
"%s " % trackerAPEconnect[12:]
412 if gprcdconnect[0:12] ==
"sqlite_file:": copytrackerdb +=
"%s " % gprcdconnect[12:]
414 file(
"%salign.sh" % directory,
"w").
write(
"""#!/bin/sh
417 export ALIGNMENT_CAFDIR=`pwd`
422 eval `scramv1 run -sh`
423 export ALIGNMENT_AFSDIR=`pwd`
425 # combine _plotting.root files into one:
426 nfiles=$(ls %(directory)splotting0*.root 2> /dev/null | wc -l)
427 if [ \"$nfiles\" != \"0\" ]; then
429 for fn in %(directory)splotting0*.root
431 FILESIZE=$(stat -c%%s "$fn")
432 if [ $FILESIZE -gt 1000 ]; then
438 #hadd -f1 %(directory)s%(director)s_plotting.root %(directory)splotting0*.root
439 hadd -f1 %(directory)s%(director)s_plotting.root $flist
440 #if [ $? == 0 ]; then rm %(directory)splotting0*.root; fi
443 # copy plotting and db files to CAFDIR
444 cp -f %(directory)s%(director)s_plotting.root $ALIGNMENT_CAFDIR/files
445 cp -f inertGlobalPositionRcd.db %(inputdbdir)s%(inputdb)s %(inputdbdir)s%(inputxml)s %(copytrackerdb)s $ALIGNMENT_CAFDIR/
447 # copy the scripts to CAFDIR
448 cd Alignment/MuonAlignmentAlgorithms/scripts/
449 cp -f plotscripts.py $ALIGNMENT_CAFDIR/
450 cp -f mutypes.py $ALIGNMENT_CAFDIR/
451 cp -f alignmentValidation.py $ALIGNMENT_CAFDIR/
452 cp -f phiedges_fitfunctions.C $ALIGNMENT_CAFDIR/
453 cp -f convertSQLiteXML.py $ALIGNMENT_CAFDIR/
454 cp -f alignCSCRings.py $ALIGNMENT_CAFDIR/
455 cp -f signConventions.py $ALIGNMENT_CAFDIR/
458 cd $ALIGNMENT_CAFDIR/
461 # run alignment validation to produce map plots and sin fit results
462 ./alignmentValidation.py -l %(validationLabel)s -i $ALIGNMENT_CAFDIR --i1 files --iN files --i1prefix %(director)s --iNprefix %(director)s -o $ALIGNMENT_CAFDIR/out --csc --map --segdiff --createDirSructure
464 # align CSC rings using the fit results from the previous step
465 ./alignCSCRings.py -d $ALIGNMENT_CAFDIR/out -l %(validationLabel)s -x %(inputxml)s %(ring2only)s
467 # convert ring-aligned xml geometry into sqlite
468 ./convertSQLiteXML.py %(inputxml)s.ring.xml %(director)s.db
470 # convert the new sqlite into proper chambers and layers xml
471 ./convertSQLiteXML.py %(director)s.db %(director)s.xml
473 #copy all good stuff to $ALIGNMENT_AFSDIR/%(directory)s
474 tar czf %(director)s_%(validationLabel)s.tgz out
475 cp -f %(director)s_%(validationLabel)s.tgz $ALIGNMENT_AFSDIR/%(directory)s
476 cp -f out/tmp_test_results_map__%(validationLabel)s.pkl $ALIGNMENT_AFSDIR/%(directory)s%(director)s.pkl
477 cp -f %(inputxml)s.ring.xml $ALIGNMENT_AFSDIR/%(directory)s
478 cp -f %(director)s.xml $ALIGNMENT_AFSDIR/%(directory)s
479 cp -f %(director)s.db $ALIGNMENT_AFSDIR/%(directory)s
481 # if it's last iteration, apply chamber motion policy
482 #if [ \"$ALIGNMENT_ITERATION\" == 2 ]; then
483 # #nfiles=$(ls %(directory)splotting0*.root 2> /dev/null | wc -l)
487 os.system(
"chmod +x %salign.sh" % directory)
489 bsubfile.append(
"echo %salign.sh" % directory)
490 if options.big: queue =
"cmscaf1nd"
491 else: queue =
"cmscaf1nh"
492 bsubfile.append(
"bsub -R \"type==SLC5_64\" -q %s -J \"%s_align\" -w \"%s\" align.sh" % (queue, director,
" && ".
join(bsubnames)))
494 last_align =
"%s_align" % director
497 if iteration == ITERATIONS:
499 directory1 =
"%s01/" % DIRNAME
500 director1 = directory1[:-1]
502 file(
"%svalidation.sh" % directory,
"w").
write(
"""#!/bin/sh
505 export ALIGNMENT_CAFDIR=`pwd`
511 eval `scramv1 run -sh`
512 ALIGNMENT_AFSDIR=`pwd`
514 # copy the scripts to CAFDIR
515 cd Alignment/MuonAlignmentAlgorithms/scripts/
516 cp -f plotscripts.py $ALIGNMENT_CAFDIR/
517 cp -f mutypes.py $ALIGNMENT_CAFDIR/
518 cp -f alignmentValidation.py $ALIGNMENT_CAFDIR/
519 cp -f phiedges_fitfunctions.C $ALIGNMENT_CAFDIR/
520 cp -f createTree.py $ALIGNMENT_CAFDIR/
521 cp -f signConventions.py $ALIGNMENT_CAFDIR/
523 cp Alignment/MuonAlignmentAlgorithms/test/browser/tree* $ALIGNMENT_CAFDIR/out/
525 # copy the results to CAFDIR
526 cp -f %(directory1)s%(director1)s_%(validationLabel)s.tgz $ALIGNMENT_CAFDIR/tmp/
527 cp -f %(directory)s%(director)s_%(validationLabel)s.tgz $ALIGNMENT_CAFDIR/tmp/
529 cd $ALIGNMENT_CAFDIR/
530 tar xzvf tmp/%(director1)s_%(validationLabel)s.tgz
532 mv out/iterN out/iter1
533 mv out/tmp_test_results_map__%(validationLabel)s.pkl out/tmp_test_results_map__%(validationLabel)s_1.pkl
534 tar xzvf tmp/%(director)s_%(validationLabel)s.tgz
537 echo \" ### Start running ###\"
540 # run simple diagnostic
541 ./alignmentValidation.py -l %(validationLabel)s -i $ALIGNMENT_CAFDIR --i1 files --iN files --i1prefix %(director1)s --iNprefix %(director)s -o $ALIGNMENT_CAFDIR/out --csc --diagnostic
543 # fill the tree browser structure:
544 ./createTree.py -i $ALIGNMENT_CAFDIR/out
546 timestamp=`date \"+%%y-%%m-%%d %%H:%%M:%%S\"`
547 echo \"%(validationLabel)s.plots (${timestamp})\" > out/label.txt
550 timestamp=`date +%%Y%%m%%d%%H%%M%%S`
551 tar czf %(validationLabel)s_${timestamp}.tgz out
552 cp -f %(validationLabel)s_${timestamp}.tgz $ALIGNMENT_AFSDIR/
555 os.system(
"chmod +x %svalidation.sh" % directory)
557 bsubfile.append(
"echo %svalidation.sh" % directory)
558 bsubfile.append(
"bsub -R \"type==SLC5_64\" -q cmscaf1nd -J \"%s_validation\" -w \"ended(%s)\" validation.sh" % (director, last_align))
560 bsubfile.append(
"cd ..")
565 os.system(
"chmod +x %s" % options.submitJobs)