7 from itertools
import groupby
8 from operator
import attrgetter
9 from TrigConfMuctpi.XMLReader
import MioctGeometryXMLReader
10 from math
import pi
as PI
16 def __init__( self, eta=0, phi=0, phimin=0, phimax=0, etamin=0, etamax=0,
17 etacode=0, phicode=0, roiid=0 ):
30 newroi =
cls( eta=
float(roi[
'eta']), phi=
float(roi[
'phi']), phimin=
float(roi[
'phimin']), phimax=
float(roi[
'phimax']), etamin=
float(roi[
'etamin']), etamax=
float(roi[
'etamax']),
31 etacode=
int(roi[
'etacode'],16), phicode=
int(roi[
'phicode'],16), roiid=
int(roi[
'roiid']))
34 s =
' ' * depth +
'<ROI eta="%f" phi="%f" etacode="0x%s" phicode="0x%s" etamin="%f" etamax="%f" phimin="%f" phimax="%f" roiid="%i"/>\n' % (self.
eta, self.
phi, self.
etacode, self.
phicode, self.
etamin, self.
etamax, self.
phimin, self.
phimax, self.
roiid )
44 self.
id =
int(name.lstrip(
'BECFA'))
49 return self.
name.startswith(
'B')
51 stats[
'rois'] += len(self.
rois)
55 s =
' '*depth +
'<Sector connector="%s" name="%s">\n' % (self.
connector, self.
name)
56 s +=
' '*depth +
' <!-- contains %i ROIs -->\n' % len(self.
rois)
57 s +=
' '*depth +
' <!-- mapping from ROI to coding scheme -->\n'
59 s += roi.asXML(depth + 4 )
60 s +=
' '*depth +
"</Sector>\n"
65 def __init__(self, etacode, phicode, eta, phi, ieta, iphi, etamin, etamax , phimin, phimax):
79 newtc =
cls( etacode=
int(tc[
'etacode'],16), phicode=
int(tc[
'phicode'],16),
81 ieta=
float(tc[
'ieta']), iphi=
float(tc[
'iphi']),
82 etamin=
float(tc[
'etamin']), etamax=
float(tc[
'etamax']), phimin=
float(tc[
'phimin']), phimax=
float(tc[
'phimax']) )
85 return ' '*depth +
'<TopoCell etacode="0x%s" phicode="0x%s" eta="%f" phi="%f" ieta="%i" iphi="%i" etamin="%f" etamax="%f" phimin="%f" phimax="%f"/>\n' % (self.
etacode, self.
phicode,
98 for (etacode,phicode), roisInCell
in groupby(
sorted(allrois, key=attrgetter(
'etacode',
'phicode')), key=attrgetter(
'etacode',
'phicode')):
100 (eta, phi, ieta, iphi, etamin, etamax, phimin, phimax) = cls.
getTopoCellPosition(etacode, phicode, roisInCell)
101 newDecodes.addTopoCell(
TopoCell(etacode=etacode, phicode=phicode, eta=eta, phi=phi, ieta=ieta, iphi=iphi, etamin=etamin, etamax=etamax, phimin=phimin, phimax=phimax) )
115 cellsEta = [(
min(e.etamin,e.etamax),
max(e.etamin,e.etamax))
for e
in rois]
116 etamins, etamaxs = zip(*cellsEta)
117 etamin =
min( [
min(e.etamin,e.etamax)
for e
in rois] )
118 etamax =
max( [
max(e.etamin,e.etamax)
for e
in rois] )
119 eta = (etamin+etamax)/2
123 cellsPhi = [(e.phimin, e.phimax)
for e
in rois]
126 upperedge = any([e.phi>6.2
for e
in rois])
127 loweredge = any([e.phi<0.2
for e
in rois])
128 splitTopoCell = upperedge
and loweredge
132 maxAtLowerEdge =
max([e.phimax
for e
in rois
if e.phi<1])
133 minAtUpperEdge =
min([e.phimin
for e
in rois
if e.phi>5])
134 centerTopoCell = minAtUpperEdge + maxAtLowerEdge
135 if centerTopoCell>=2*PI:
136 phimin = minAtUpperEdge - 2 * PI
137 phimax = maxAtLowerEdge
139 phimin = minAtUpperEdge
140 phimax = maxAtLowerEdge + 2 * PI
141 phi = (phimin+phimax)/2
144 phimins, phimaxs = zip(*cellsPhi)
145 phimin =
min(phimins)
146 phimax =
max(phimaxs)
147 phi = (phimin+phimax)/2
152 if ieta== 12: ieta= 11
153 if ieta==-12: ieta=-11
159 if abs(ieta)
in [2,5]:
160 if phi>2.05
and phi<2.35: iphi += 1
161 if phi>2.75
and phi<3.25: iphi += 1
162 if phi>3.45: iphi += 1
165 if phi>2.05
and phi<2.35: iphi += 1
166 if phi>2.75
and phi<3.25: iphi += 1
167 if phi>3.45
and phi<4.95: iphi += 1
168 if phi>5.05: iphi += 1
170 if abs(ieta)
in [15,18]:
171 if phi>2.65: iphi += 1
174 if phi>2.15
and phi<2.35: iphi += 1
175 if phi>2.65
and phi<3.25: iphi += 1
176 if phi>3.35: iphi += 1
179 if phi>0.05
and phi<5.35: iphi += 1
180 if phi>5.35: iphi += 2
182 return (eta, phi, ieta, iphi, etamin, etamax, phimin, phimax)
187 stats[
'decodes'] += 1
188 stats[
'topocells'] += len(self.
topocells)
190 s =
' '*depth +
'<Decode>\n'
192 s += tc.asXML(depth+4)
193 s +=
' '*depth +
'</Decode>\n'
202 self.
sectordic = dict([ (s.connector, s)
for s
in sectors ])
208 raise RuntimeError(
"Sector with connector %i already exists" % sector.connector)
210 self.
sectordic[sector.connector] = sector
213 stats[
'sectors'] += len(self.
sectors)
215 sector.getStats(stats)
219 sectorNames = [s.name
for s
in self.
sectors]
220 s =
' '*depth +
'<MIOCT id="%s" slot="%i">\n' % (self.
id, self.
slot)
221 s +=
' '*depth +
' <!-- contains sectors %s -->\n' %
", ".
join(
sorted(sectorNames))
223 s += sector.asXML(depth + 4)
226 s +=
' '*depth +
"</MIOCT>"
232 allROIsInMioct += sector.rois
233 self.
decodes = Decodes.fromAllRois(allROIsInMioct)
245 raise RuntimeError(
"MIOCT with ID %i already exists" % mioct.id)
250 f =
open(outfilename,
"write")
251 print(
'<?xml version="1.0" ?>\n', file=f)
252 print(
'<!DOCTYPE MuCTPiGeometry SYSTEM "MUCTPIGeometry.dtd">\n', file=f)
253 print(
'<MuCTPiGeometry>', file=f)
255 print(mioct.asXML(4), file=f)
256 print(
' <PtEncoding>', file=f)
257 print(
' <PtCodeElement pt="1" code="0" value="4"/>', file=f)
258 print(
' <PtCodeElement pt="2" code="1" value="6"/>', file=f)
259 print(
' <PtCodeElement pt="3" code="2" value="10"/>', file=f)
260 print(
' <PtCodeElement pt="4" code="2" value="11"/>', file=f)
261 print(
' <PtCodeElement pt="5" code="2" value="15"/>', file=f)
262 print(
' <PtCodeElement pt="6" code="2" value="20"/>', file=f)
263 print(
' </PtEncoding>', file=f)
264 print(
"</MuCTPiGeometry>", file=f)
266 print(
"Wrote %s" % outfilename)
268 stats[
'miocts'] = len(self.
miocts)
270 mioct.getStats(stats)
272 stats = {
'miocts' : 0,
'sectors' : 0,
'rois' : 0,
'decodes' : 0,
'topocells' : 0}
275 print(
"#MIOCTs : %i" % stats[
'miocts'])
276 print(
"#Sectors : %i" % stats[
'sectors'])
277 print(
"#Decodes : %i" % stats[
'decodes'])
278 print(
"#ROIs : %i" % stats[
'rois'])
279 print(
"#Topocells : %i" % stats[
'topocells'])
286 sectorName =
"B%02i" % sectorID
287 sectorConnector = (sectorID+2) % 4
289 mioctID = ( (sectorID+2) % 32 ) / 4
290 mioctSlot = mioctID + 4
293 mioctSlot = mioctID + 6
295 return mioctID, mioctSlot, sectorConnector, sectorName
300 xmlgeometry = MioctGeometryXMLReader(fn)
302 for MIOCT
in xmlgeometry.getMIOCTs():
304 for sector
in MIOCT.Sectors:
307 for roiElem
in sector.ROIs:
308 rois += [ ROI.fromROIelement(roiElem) ]
309 sectors += [
Sector(name=sector[
'name'], connector=
int(sector[
'connector']), rois=rois) ]
310 miocts += [
Mioct( id=
int(MIOCT[
'id']), slot=
int(MIOCT[
'slot']), sectors=sectors) ]
312 for tc
in MIOCT.Decode.TopoCells:
313 decodes.addTopoCell( TopoCell.fromTopoCellElement(tc) )
314 miocts[-1].decodes=decodes
315 return MuonGeometry(
"full geometry 2015", miocts=miocts)
321 for mioct
in geometry.miocts:
322 for sector
in mioct.sectors:
323 if sector.isBarrel():
324 mapping[sector.id] = dict( [ (roi.roiid, (roi.etacode, roi.phicode))
for roi
in sector.rois ] )
331 """ provides the new mapping for the feet and elevator region
332 The numbers can be found in doc/roi_map_R2.pdf
338 if sectorId
in [23,24,55,56]:
342 etaMap = { 23 : [ [0,1,2,3,5,7], [4,6,8,9,10,11],
range(12,20) + [21,23], [20,22] +
range(24,28) ],
343 24 : [ [0,1,2,3,4,6], [5,7,8,9,10,11],
range(12,20) + [20,22], [21,23] +
range(24,28) ] }
344 etaMap[55] = etaMap[24]
345 etaMap[56] = etaMap[23]
347 for ec, tt
in enumerate(etaMap[sectorId]):
353 if sectorId
in [23,55]:
354 if roiId
in [2,3,6,7,10,11,18,19,22,23,27]:
356 if roiId
in [0,1,4,5,8,9,12,13,14,15,16,17,20,21,25]:
358 elif sectorId
in [24,56]:
359 if roiId
in [0,1,4,5,8,9,12,13,14,15,16,17,20,21,24]:
361 if roiId
in [2,3,6,7,10,11,18,19,22,23,26]:
365 if roiId == 27: phicode = 2
366 elif roiId == 25: phicode = 3
368 if roiId == 24: phicode = 4
369 elif roiId == 26: phicode = 5
371 if roiId == 24: phicode = 3
372 elif roiId == 26: phicode = 2
374 if roiId == 27: phicode = 5
375 elif roiId == 25: phicode = 4
379 elif [21,22,25,26,53,54,57,58]:
383 etaMap = { 21 : [
range(0,8),
range(8,16) + [17,19], [16,18] +
range(20,32) ],
385 etaMap[25] = etaMap[21]
386 etaMap[26] = etaMap[22]
387 etaMap[53] = etaMap[22]
388 etaMap[54] = etaMap[21]
389 etaMap[57] = etaMap[53]
390 etaMap[58] = etaMap[54]
392 for ec, tt
in enumerate(etaMap[sectorId]):
398 if sectorId
in [21,53]:
399 if roiId
in [2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31]:
401 elif roiId
in [0,1,4,5,8,9,12,13,16,17,20,21,24,25,28,29]:
403 elif sectorId
in [22,54]:
404 if roiId
in [0,1,4,5,8,9,12,13,16,17,20,21,24,25,28,29]:
406 elif roiId
in [2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31]:
408 elif sectorId
in [25,57]:
409 if roiId
in [2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31]:
411 elif roiId
in [0,1,4,5,8,9,12,13,16,17,20,21,24,25,28,29]:
413 elif sectorId
in [26,58]:
414 if roiId
in [0,1,4,5,8,9,12,13,16,17,20,21,24,25,28,29]:
416 elif roiId
in [2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31]:
420 raise RuntimeError(
"No etacode for SL %i and ROI %i" % (sectorId, roiId))
422 raise RuntimeError(
"No phicode for SL %i and ROI %i" % (sectorId, roiId))
424 return (etacode,phicode)
433 print(
"read2016RPCGeomData: Reading %s", fn)
436 if line.lstrip().startswith(
"#"):
442 etamin =
float(ls[3])
443 etamax =
float(ls[4])
444 phimin =
float(ls[5])
445 phimax =
float(ls[6])
446 if max(phimin, phimax) < 0:
449 eta = (etamin + etamax) / 2
450 phi = (phimin + phimax) / 2
452 sectorId = sector + 32 * side
453 if sectorId
in [21,22,23,24,25,26,53,54,55,56,57,58]:
456 (etacode, phicode) = oldMapping[sectorId][roiid]
458 roi =
ROI( eta=eta, phi=phi, phimin=phimin, phimax=phimax, etamin=etamin, etamax=etamax, etacode=etacode, phicode=phicode, roiid=roiid )
462 mioct = rpcGeometry2016.getMioct(mioctId)
464 mioct = rpcGeometry2016.addMioct(
Mioct(id=mioctId, slot=mioctSlot))
466 sector = mioct.getSector(sectorConnector)
468 sector = mioct.addSector(
Sector(name=sectorName, connector=sectorConnector) )
472 return rpcGeometry2016
476 newGeometry.name =
"updated full geometry for 2016"
477 for mioct
in newGeometry.miocts:
478 oldMioct = oldGeometry.getMioct(mioct.id)
479 for sector
in oldMioct.sectors:
480 if sector.isBarrel():
continue
481 mioct.addSector(sector)
482 mioct.fillTopoCells()
487 attr = [
"connector",
"name"]
488 s =
' '*depth +
"<%s %s>\n" % (sector.tag,
" ".
join([
'%s="%s"' % (a, sector[a])
for a
in attr]) )
489 s +=
' '*depth +
' <!-- contains %i ROIs -->\n' % len(sector.ROIs)
490 s +=
' '*depth +
' <!-- mapping from ROI to coding scheme -->\n'
491 for roi
in sorted(sector.ROIs, key=
lambda roi:
int(roi[
'roiid'])):
493 s +=
' '*depth +
"</%s>\n" % sector.tag
494 stats[
'rois'] += len(sector.ROIs)
498 attr = [
"eta",
"phi",
"etacode",
"phicode",
"etamin",
"etamax",
"phimin",
"phimax",
"roiid"]
499 s =
' ' * depth +
"<ROI %s/>\n" % (
" ".
join([
'%s="%s"' % (a, roi[a])
for a
in attr]) )
504 (connector, name, rois) = xxx_todo_changeme
505 s =
' '*depth +
'<Sector connector="%s" name="%s">\n' % (connector, name)
506 s +=
' '*depth +
' <!-- contains %i ROIs -->\n' % len(rois)
507 s +=
' '*depth +
' <!-- mapping from ROI to coding scheme -->\n'
510 s +=
' '*depth +
"</Sector>\n"
511 stats[
'rois'] += len(rois)
515 roi[
'eta'] = (
float(roi[
'etamin']) +
float(roi[
'etamax'])) / 2
516 roi[
'phi'] = (
float(roi[
'phimin']) +
float(roi[
'phimax'])) / 2
517 s =
' ' * depth +
'<ROI eta="%f" phi="%f" etacode="0x%s" phicode="0x%s" etamin="%f" etamax="%f" phimin="%f" phimax="%f" roiid="%i"/>\n' % (roi[
"eta"], roi[
"phi"], roi[
"etacode"], roi[
"phicode"], roi[
"etamin"], roi[
"etamax"], roi[
"phimin"], roi[
"phimax"], roi[
"roiid"] )
533 muonGeometry2015.printStats()
540 muonGeometry2016.printStats()
544 muonGeometry2016.printStats()
547 muonGeometry2016.writeXML(
"TestMioctGeometry2016.xml")
552 if __name__==
"__main__":
554 parser = argparse.ArgumentParser( description=__doc__,
555 formatter_class = argparse.RawTextHelpFormatter)
557 parser.add_argument(
'-i', dest=
'infile', default=
"../data/TestMioctGeometry2016.dat", type=str,
558 help=
'name of input RPC muon geometry file for 2016 [../data/TestMioctGeometry2016.dat]')
560 parser.add_argument(
'-i1', dest=
'infile2015', default=
"../data/TestMioctGeometry.xml", type=str,
561 help=
'name of input RPC muon geometry file used in 2015 [../data/TestMioctGeometry.xml]')
563 args = parser.parse_args()
565 sys.exit(
main(args) )