ATLAS Offline Software
Loading...
Searching...
No Matches
drawFromPickle.py
Go to the documentation of this file.
1#!/bin/env python
2
3# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
4
5# Draw the triggers that have been written to a txt file as a dictionary.
6#
7# See PadWithHits.h for a description of the 'simplified' pickle mechanism.
8# See the 'pickle()' method of each (cpp) class for a list of the attributed being stored.
9#
10# davide.gerbaudo@gmail.com
11# April 2013
12#
13# Imported from https://svnweb.cern.ch/trac/atlasusr/browser/ataffard/UpgradeNSW/NSWAna/NSWNtuple/trunk/python/drawFromPickle.py
14# By Alaettin Serhan Mete (amete@cern.ch) in April 2016
15
16import math
17import os
18import sys
19import ROOT as r
20r.gROOT.SetBatch(1)
21r.PyConfig.IgnoreCommandLineOptions = True
22r.gStyle.SetPadTickX(1)
23r.gStyle.SetPadTickY(1)
24
25
26#_________________________________________________
27# define some units, constants, and aliases
28mm = 1.0
29cm = 10.
30cm2mm = 10.
31mm2cm = 0.1
32repv = r.Math.RhoEtaPhiVector
33xyzv = r.Math.XYZVector
34#_________________________________________________
35sectorDphi = 2.0*math.pi/16.
36sin, cos, tan, atan, exp = math.sin, math.cos, math.tan, math.atan, math.exp
37def midSectorPhi(sec) : return (sec-1)*sectorDphi # sector N starts from 1
38def average(lst) : return sum(lst)/len(lst)
39def eta2theta(eta) : return 2.0*atan(exp(-eta))
40def xyFromEtaPhiZ(eta, phi, z) :
41 theta = eta2theta(eta)
42 r = z*tan(theta)
43 return r*cos(phi), r*sin(phi)
44def tuple2vec(tpl) : return xyzv(tpl[0], tpl[1], tpl[2])
45#_________________________________________________
47 """
48 Use the kargs trick to set all the attributes except the ones
49 that are my classes, and not basic types. See for example:
50 http://stackoverflow.com/questions/1098549/proper-way-to-use-kwargs-in-python
51 """
52 def __init__(self, **kargs) :
53 for k,v in kargs.iteritems() : setattr(self, k, v)
54#_________________________________________________
56 def __init__(self, **kargs) :
57 super(PadWithHits, self).__init__(**kargs)
58 self.cornerXyz = [tuple2vec(t) for t in self.cornerXyz] # convert (x,y,z) tuple to vector
60 self.rotatedCornerXyz = [self.rotateVecToSec5(v) for v in self.cornerXyz]
62 self.minX, self.maxX = self.determineXminmax()
63 self.minY, self.maxY = self.determineYminmax()
64 self.minZ, self.maxZ = self.determineZminmax()
65 self.minH, self.maxH = self.determineHminmax()
66 self.minPhi, self.maxPhi = self.determinePhiminmax()
67 def color(layer) : return [r.kBlack, r.kRed, r.kBlue, r.kViolet, r.kGreen][layer]
68 def width(isPivot) : return 2 if isPivot else 1
69 self.lineColor = color(self.layer)
70 self.lineWidth = width(self.isPivot())
71 def setFont(self, font) : self.font = font
72 def isPivot(self) : return self.multiplet in [0,2] # ASM 28/04/2016 : Check that this is correct
73 def rotateVecToSec5(self, vec) :
74 "Rotate a vector to sector5 coordinates (note: delta phi depends only on the sector)"
75 deltaPhi = midSectorPhi(self.sector) - midSectorPhi(5)
76 return repv(vec.rho(), vec.eta(), vec.phi()).SetPhi(vec.phi() - deltaPhi)
78 z = average([p.z() for p in self.cornerXyz]) # although the corners should be at the same z...
79 x, y = xyFromEtaPhiZ(self.avgEta, self.avgPhi, z)
80 return xyzv(x, y, z)
82 xs = [p.x() for p in self.cornerXyz]
83 return min(xs), max(xs)
85 ys = [p.y() for p in self.cornerXyz]
86 return min(ys), max(ys)
88 zs = [p.z() for p in self.cornerXyz]
89 return min(zs), max(zs)
91 phis = [p.phi() for p in self.cornerXyz]
92 return min(phis), max(phis)
93 def determineHminmax(self): return self.loHei, self.hiHei
94 def draw(self, view='yx') :
95 self.drawEdges(self.lineColor, self.lineWidth, view)
96 self.drawCharge(self.lineColor, view)
97 def drawEdges(self, color, width, view='yx') :
98 lineColor = color
99 lineWidth = width
100 corners = self.rotatedCornerXyz if view=='hz' else self.cornerXyz
101 segments, lines = [], []
102 # see Pad::fillCornerCoords to remember which corner is where
103 if view=='yx' : segments = [(corners[i], corners[j]) for i,j in [(0, 1), (1, 3), (2, 3), (0, 2)]]
104 elif view=='hz' : segments = [(corners[i], corners[j]) for i,j in [(0, 1)]]
105 elif view=='zphi' : segments = [(corners[i], corners[j]) for i,j in [(0, 2)]]
106 l = r.TLine
107 if view=='yx' : lines = [l(p1.x(), p1.y(), p2.x(), p2.y()) for p1,p2 in segments]
108 elif view=='hz' : lines = [l(p1.z(), p1.y(), p2.z(), p2.y()) for p1,p2 in segments]
109 elif view=='zphi' : lines = [l(p1.phi(), p1.z(), p2.phi(), p2.z()) for p1,p2 in segments]
110 for l in lines :
111 l.SetLineColor(lineColor)
112 l.SetLineWidth(lineWidth)
113 l.Draw()
114 if hasattr(self, '_lines') : self._lines.append(lines)
115 else : self._lines = lines
116 self.printPadCoord(view, lines[0])
117 def printPadCoord(self, view, line) :
118 if view not in ['hz','zphi'] : return
119 coord = {'hz':'ieta', 'zphi':'iphi'}[view]
120 leftOrRight = self.layer%2
121 angle = 90. if view=='hz' else 0.
122 xs = sorted([line.GetX1(), line.GetX2()], reverse=leftOrRight)
123 ys = sorted([line.GetY1(), line.GetY2()], reverse=leftOrRight)
124 def outside(xx) : return xx[1] + 0.75*(xx[1]-xx[0])
125 x = average(xs) if view=='hz' else outside(xs)
126 y = average(ys) if view=='zphi' else outside(ys)
127 text = r.TLatex(x, y, "%d" % getattr(self, coord))
128 text.SetTextAlign(22)
129 text.SetTextAngle(angle)
130 text.SetTextColor(line.GetLineColor())
131 if hasattr(self, 'font') : text.SetTextFont(self.font)
132 text.Draw()
133 if hasattr(self, '_labels') : self._labels.append(text)
134 else : self._labels = [text]
135 def drawCharge(self, color, view='yx') :
136 v = self.rotatedAvgChargeXyz if view=='hz' else self.avgChargeXyz
137 x, y = 0., 0.
138 if view=='yx' : x, y = v.x(), v.y()
139 elif view=='hz' : x, y = v.z(), v.y()
140 elif view=='zphi' : x, y = v.phi(), v.z()
141 marker = r.TMarker(x, y, r.kMultiply)
142 marker.SetMarkerColor(color)
143 marker.Draw()
144 if hasattr(self, '_markers') : self._markers.append(marker)
145 else : self._markers = [marker]
146 def drawCloud() : print 'drawCloud not implemented yet'
147 if len(self.hitIndices)>1 : drawCloud()
148
149#_________________________________________________
151 def __init__(self, pads=[], **kargs) :
152 self.pads = [PadWithHits(**ka) for ka in pads]
153 super(SingleWedgePadTrigger, self).__init__(**kargs)
154 def setFont(self, font) :
155 self.font = font
156 for p in self.pads : p.setFont(font)
157 def isPivot(self) : return self.pads[0].isPivot()
158 def isConfirm(self) : return not self.isPivot()
159 def sector(self) : return self.pads[0].sector
160 def draw(self, view) :
161 for p in self.pads : p.draw(view)
162 def minMaxPadPar(self, parNames=['',]) :
163 values = [getattr(p, pname) for p in self.pads for pname in parNames]
164 return min(values), max(values)
165 def minMaxPadX(self) : return self.minMaxPadPar(['minX','maxX'])
166 def minMaxPadY(self) : return self.minMaxPadPar(['minY','maxY'])
167 def minMaxPadZ(self) : return self.minMaxPadPar(['minZ','maxZ'])
168 def minMaxPadH(self) : return self.minMaxPadPar(['minH','maxH'])
169 def minMaxPadPhi(self) : return self.minMaxPadPar(['minPhi','maxPhi'])
170 def minMaxPadVar(self, var) :
171 if var=='x' : return self.minMaxPadX()
172 elif var=='y' : return self.minMaxPadY()
173 elif var=='z' : return self.minMaxPadZ()
174 elif var=='h' : return self.minMaxPadH()
175 elif var=='phi' : return self.minMaxPadPhi()
176 def drawLabelsLeft(self, x, y, dy) :
177 text = r.TLatex( x, y, '')
178 text.SetNDC()
179 if hasattr(self, 'font') : text.SetTextFont(self.font)
180 if hasattr(self, '_labels') : self._labels.append(text)
181 else : self._labels = [text]
182 text.DrawLatex(x, y, "Sector %d"%self.sector())
183 y = y + dy
184 text.DrawLatex(x, y, (('Pivot' if self.isPivot() else '') +
185 ('Confirm' if self.isConfirm() else '') +
186 ", %d/4"%len(self.pads) +
187 ' : '+self.pattern))
188 y = y + dy
189 ieta, iphi = self.halfPadIndices
190 text.DrawLatex(x, y, "Half-pad indices : (%d, %d)"%(ieta, iphi))
191
192 return y+dy
193
194#_________________________________________________
196 def __init__(self, wedgeTrigs=[], **kargs) :
197 self.wedgeTrigs = [SingleWedgePadTrigger(**ka) for ka in wedgeTrigs]
198 super(SectorTriggerCandidate, self).__init__(**kargs)
199 self.possibleViews = ['yx', 'hz', 'zphi']
200 self.xVars = dict(zip(self.possibleViews, ['x', 'z', 'phi']))
201 self.yVars = dict(zip(self.possibleViews, ['y', 'h', 'z'] ))
202 def sector(self) : return self.wedgeTrigs[0].sector()
203 def setFont(self, font) :
204 self.font = font
205 for w in self.wedgeTrigs : w.setFont(font)
206 def adjustRanges(self, padMaster, view='yx'):
207 possibleViews = self.possibleViews
208 xVar, yVar = self.xVars[view], self.yVars[view]
209 marginX = dict(zip(possibleViews, [20*cm, 20*cm, math.pi/32]))[view]
210 marginY = dict(zip(possibleViews, [10*cm, 20*cm, 10*cm] ))[view]
211 xMin, xMax = self.minMaxPadVar(xVar)
212 yMin, yMax = self.minMaxPadVar(yVar)
213 xMin, xMax = xMin-marginX, xMax+marginX
214 yMin, yMax = yMin-marginY, yMax+marginY
215 self.xyRanges = ((xMin, xMax), (yMin, yMax))
216 padMaster.GetXaxis().SetRangeUser(xMin, xMax)
217 padMaster.GetYaxis().SetRangeUser(yMin, yMax)
218 self.setFont(padMaster.GetTitleFont())
219 def draw(self, padMaster, view='yx', onlyPivot=False, onlyConfirm=False) :
220 possibleViews = self.possibleViews
221 assert view in possibleViews, "Invalid view %s"%view
222 xVar = dict(zip(possibleViews, ['x', 'z', 'phi']))[view]
223 yVar = dict(zip(possibleViews, ['y', 'h', 'z'] ))[view]
224 gridX = dict(zip(possibleViews, [0, 0, 1] ))[view]
225 gridY = dict(zip(possibleViews, [0, 1, 0] ))[view]
226 padMaster.Draw()
227 r.gPad.SetGridx(gridX)
228 r.gPad.SetGridy(gridY)
229 wedgeTrigs = [w for w in self.wedgeTrigs if (not (onlyConfirm or onlyPivot) or
230 (onlyConfirm and w.isConfirm()) or
231 (onlyPivot and w.isPivot()))]
232 for w in wedgeTrigs : w.draw(view)
233 self.drawLabels(view, padMaster, wedgeTrigs)
234 if view=='yx' : self.drawSectorPostmark(self.xyRanges)
235 def minMaxPadVar(self, var) :
236 minMaxVals = [w.minMaxPadVar(var) for w in self.wedgeTrigs]
237 mins, maxs = [m[0] for m in minMaxVals], [m[1] for m in minMaxVals]
238 return min(mins), max(maxs)
239 def drawLabels(self, view, padMaster, wedgeTriggers) :
240 if view!='yx' : return
241 xMin, xMax = padMaster.GetXaxis().GetXmin(), padMaster.GetXaxis().GetXmax()
242 yMin, yMax = padMaster.GetYaxis().GetXmin(), padMaster.GetYaxis().GetXmax()
243 x, y, dy = 0.125, 0.85, -0.05
244 for w in wedgeTriggers : y = w.drawLabelsLeft(x, y, dy)
245 def drawSectorPostmark(self, xyRanges=((-1.0, +1.0), (-1.0, +1.0))) :
246 (xMin, xMax), (yMin, yMax) = xyRanges
247 def topTwelwthRange(vMin, vMax) : return vMax-(vMax-vMin)/12.0, vMax
248 xMin, xMax = topTwelwthRange(xMin, xMax)
249 yMin, yMax = topTwelwthRange(yMin, yMax)
250 hdx, hdy = 0.5*(xMax-xMin), 0.5*(yMax-yMin)
251 R = math.sqrt(hdx*hdx +hdy*hdy)
252 midPhi = midSectorPhi(self.sector())
253 minPhi, maxPhi = math.degrees(midPhi-0.5*sectorDphi), math.degrees(midPhi+0.5*sectorDphi)
254 circle = r.TEllipse(0.5*(xMin+xMax), 0.5*(yMin+yMax), R, R)
255 circle.SetLineColor(r.kBlack)
256 circle.SetFillStyle(0)
257 circle.Draw()
258 slice = r.TCrown(0.5*(xMin+xMax), 0.5*(yMin+yMax), 0.2*R, 1.0*R, minPhi, maxPhi)
259 slice.SetFillColor(r.kBlack)
260 slice.SetFillStyle(1001)
261 slice.Draw()
262 if hasattr(self, '_markers') : self._markers.append(slice)
263 else : self._markers = [slice]
264 self._markers.append(circle)
265
266#_________________________________________________
267
268if __name__=='__main__' :
269 # expect a list of candidates in the file
270 filename = sys.argv[1]
271 candidates = eval(open(filename).read())
272 outputBaseName = os.path.splitext(filename)[0]
273 print "found %d sector trigger candidates"%len(candidates)
274 xRangeMin, xRangeMax = -500*cm, +500*cm
275 yRangeMin, yRangeMax = -500*cm, +500*cm
276 zRangeMin, zRangeMax = -800*cm, +800*cm
277 hRangeMin, hRangeMax = 0*cm, yRangeMax
278 phiRangeMin, phiRangeMax = -2*math.pi, +2*math.pi
279 padMasterYx = r.TH2F('padMasterYx', ';x [mm]; y [mm]', 200, xRangeMin, xRangeMax, 200, yRangeMin, yRangeMax)
280 padMasterHz = r.TH2F('padMasterHz', ';z [mm]; h [mm]', 200, zRangeMin, zRangeMax, 200, hRangeMin, hRangeMax)
281 padMasterZphi = r.TH2F('padMasterZphi',';phi [rad];z [mm]', 200, phiRangeMin, phiRangeMax, 200, zRangeMin, zRangeMax)
282 can = r.TCanvas('can')
284 h.SetStats(0)
285 h.GetXaxis().CenterTitle()
286 h.GetYaxis().CenterTitle()
287 for h in [padMasterYx, padMasterHz, padMasterZphi] : formatPadMaster(h)
288 for i,c in enumerate(candidates) :
290 can.Clear()
291 can.Divide(2, 2)
292
293 can.cd(1)
294 view, padMaster ='zphi', padMasterZphi
295 sCan.adjustRanges(padMaster, view)
296 sCan.draw(padMaster, view)
297
298 can.cd(2)
299 view, padMaster = 'hz', padMasterHz
300 sCan.adjustRanges(padMaster, view)
301 sCan.draw(padMaster, view)
302
303 view, padMaster = 'yx', padMasterYx
304 sCan.adjustRanges(padMaster, view)
305 can.cd(3)
306 sCan.draw(padMaster, view, onlyPivot=True)
307 can.cd(4)
308 sCan.draw(padMaster, view, onlyConfirm=True)
309
310 can.SaveAs("%s_%03d.png"%(outputBaseName, i))
const double width
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
printPadCoord(self, view, line)
drawCharge(self, color, view='yx')
drawEdges(self, color, width, view='yx')
adjustRanges(self, padMaster, view='yx')
__init__(self, wedgeTrigs=[], **kargs)
drawSectorPostmark(self, xyRanges=((-1.0,+1.0),(-1.0,+1.0)))
drawLabels(self, view, padMaster, wedgeTriggers)
draw(self, padMaster, view='yx', onlyPivot=False, onlyConfirm=False)
xyFromEtaPhiZ(eta, phi, z)
IovVectorMap_t read(const Folder &theFolder, const SelectionCriterion &choice, const unsigned int limit=10)