ATLAS Offline Software
Loading...
Searching...
No Matches
LArCondContChannels.py
Go to the documentation of this file.
1# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
2
3# File: LArConditionsCommon/python/LArCondContChannels.py
4# Author: RD Schaffer (R.D.Schaffer@cern.ch)
5
6# The LArCondContChannels class provides the translation for between
7# LArConditionsContainer group numbering and COOL channel numbering.
8#
9
10import operator
11
13 def __init__(self) :
14 self.Unknown = 0
15 self.SingleGroup = 1
20
21 # Offset values
22 #self.offsetCorrs = 3
27 self.nFT = 114
28 self.nFTandCorr = 117
29 self.ftPerGain = self.nFT
30
31 # For extended FT grouping:
32 self.nFTAcc = 117
33 self.offsetFtNegBarrelPS = 3 + self.nFTAcc #= 120
34 self.offsetFtPosBarrelPS = 35 + self.nFTAcc #= 152
35 self.offsetFtNegEndcapPS = 67 + self.nFTAcc #= 184
36 self.offsetFtPosEndCapPS = 92 + self.nFTAcc #= 209
37 self.nFTPS = 117 + self.nFTAcc #= 231
38
40 self.nGains = 3
42 self.nSubDets = 4
44
45 def isUnknown(self, type):
46 return type == self.Unknown
47
48 def isSingleGroup(self, type):
49 return type == self.SingleGroup
50
51 def isSubDetectorGrouping(self, type):
52 return type == self.SubDetectorGrouping
53
54 def isExtSubDetectorGrouping(self, type):
55 return type == self.ExtSubDetectorGrouping
56
57 def isFeedThroughGrouping(self, type):
58 return type == self.FeedThroughGrouping
59
60 def isExtFeedThroughGrouping(self, type):
61 return type == self.ExtFeedThroughGrouping
62
63
64 # folderFeedThruGroupChanSel:
65 #
66 # Return the list of COOL channels given for a subset of
67 # feedthroughs. There are four groupings of feedthroughs possible,
68 # selected by the input argument:
69 #
70 # "negBarrel" - EMB
71 # "posBarrel" - EMB
72 # "negEndcap" - EMEC, HEC, FCAL
73 # "posEndcap" - EMEC, HEC, FCAL
74 #
75 # The list of channels is of the form:
76 #
77 # <channelSelection> x:y, z, a:b </channelSelection>
78 #
79 # This should be provided in the IOVDbSvc.Folders list for each
80 # folder.
81 #
82 # Input arguments:
83 # feedThruGroup - "negBarrel", "posBarrel", "negEndcap", "posEndcap"
84 # gainList - a list of gains values: 0, 1, and/or 2, default
85 # value is all gains
86 #
87 def folderFeedThruGroupChanSel(self, feedThruGroup, gainList=[0,1,2]):
88 gains = gainList
89 if operator.isNumberType(gainList): gains = [gainList]
90 for g in gains:
91 if g < 0 or g > 2:
92 print("LArCondContChannels.folderFeedThruGroupChanSel: invalid gain value - must be 0-2 - ", g)
93 return "<channelSelection> </channelSelection>"
94
95 if feedThruGroup == "negBarrel":
96 feedThruList = []
97 posNeg = -1
98 isBarrel = True
99 for ft in range(32):
100 feedThruList += [ft]
101 chans = self.feedThruChannelSelection(feedThruList, gains, posNeg, isBarrel)
102 elif feedThruGroup == "posBarrel":
103 feedThruList = []
104 posNeg = 1
105 isBarrel = True
106 for ft in range(32):
107 feedThruList += [ft]
108 chans = self.feedThruChannelSelection(feedThruList, gains, posNeg, isBarrel)
109 elif feedThruGroup == "negEndcap":
110 feedThruList = []
111 posNeg = -1
112 isBarrel = False
113 for ft in range(25):
114 feedThruList += [ft]
115 chans = self.feedThruChannelSelection(feedThruList, gains, posNeg, isBarrel)
116 elif feedThruGroup == "posEndcap":
117 feedThruList = []
118 posNeg = 1
119 isBarrel = False
120 for ft in range(25):
121 feedThruList += [ft]
122 chans = self.feedThruChannelSelection(feedThruList, gains, posNeg, isBarrel)
123 else:
124 print("LArCondContChannels.folderFeedThruGroupChanSel: feedThru grouping, found", feedThruGroup)
125 print("Allowed values: \"negBarrel\", \"posBarrel\", \"negEndcap\", \"posEndcap\"")
126 return "<channelSelection> </channelSelection>"
127
128
129 chanSel = self.channelSelection(chans)
130 return chanSel
131
132 # Return a list of COOL channels given a list of feedthrough
133 # numbers. This list is of the form:
134 #
135 # <channelSelection> x:y, z, a:b </channelSelection>
136 #
137 # This should be provided in the IOVDbSvc.Folders list for each
138 # folder.
139 #
140 # This should be run separately for barrel/endcap and
141 # pos/neg, appending the results.
142 #
143 # Input args:
144 # Four lists of feedThrough numbers (starting from 0)
145 # for pos/neg Barrel/EndCap, e.g. [4, 8, 30]
146 # (may also just be a single number):
147 # negB_FTList - negative barrel - 0 to 31
148 # posB_FTList - positive barrel - 0 to 31
149 # negEC_FTList - negative endcap - 0 to 24
150 # posEC_FTList - positive endcap - 0 to 24
151 #
152 # gainList - list of gains (0 to 2), may be a single number or list
153 # isCorrection - False - normal conditions, True - corrections (default is False)
155 negB_FTList,
156 posB_FTList,
157 negEC_FTList,
158 posEC_FTList,
159 gainList,
160 isCorrection=False):
161 chans = []
162 # Check that the lists are not empty
163 if len(negB_FTList) == 0 and \
164 len(posB_FTList) == 0 and \
165 len(negEC_FTList) == 0 and \
166 len(posEC_FTList) == 0:
167
168 print("LArCondContChannels.folderFeedThruChannelSelection Warning: FeedThru lists are all empty - no channels selected")
169
170 elif len(gainList) == 0:
171 print("LArCondContChannels.folderFeedThruChannelSelection Warning: Gain list is empty - no channels selected")
172 else:
173 if len(negB_FTList) > 0:
174 chans += self.feedThruChannelSelection(
175 negB_FTList,
176 gainList,
177 -1,
178 True,
179 isCorrection)
180 if len(posB_FTList) > 0:
181 chans += self.feedThruChannelSelection(
182 posB_FTList,
183 gainList,
184 1,
185 True,
186 isCorrection)
187 if len(negEC_FTList) > 0:
188 chans += self.feedThruChannelSelection(
189 negEC_FTList,
190 gainList,
191 -1,
192 False,
193 isCorrection)
194 if len(posEC_FTList) > 0:
195 chans += self.feedThruChannelSelection(
196 posEC_FTList,
197 gainList,
198 1,
199 False,
200 isCorrection)
201
202 print("chans ",chans)
203 chanSel = self.channelSelection(chans)
204 return chanSel
205
206
207
208
209
211 negB_FTList,
212 posB_FTList,
213 negEC_FTList,
214 posEC_FTList,
215 gainList,
216 isCorrection=False):
217 chans = []
218 # Check that the lists are not empty
219 if len(negB_FTList) == 0 and \
220 len(posB_FTList) == 0 and \
221 len(negEC_FTList) == 0 and \
222 len(posEC_FTList) == 0:
223
224 print("LArCondContChannels.folderFeedThruChannelSelection Warning: FeedThru lists are all empty - no channels selected")
225
226 elif len(gainList) == 0:
227 print("LArCondContChannels.folderFeedThruChannelSelection Warning: Gain list is empty - no channels selected")
228 else:
229 if len(negB_FTList) > 0:
230 chans += self.extFeedThruChannelSelection(
231 negB_FTList,
232 gainList,
233 -1,
234 True,
235 isCorrection)
236 if len(posB_FTList) > 0:
237 chans += self.extFeedThruChannelSelection(
238 posB_FTList,
239 gainList,
240 1,
241 True,
242 isCorrection)
243 if len(negEC_FTList) > 0:
244 chans += self.extFeedThruChannelSelection(
245 negEC_FTList,
246 gainList,
247 -1,
248 False,
249 isCorrection)
250 if len(posEC_FTList) > 0:
251 chans += self.extFeedThruChannelSelection(
252 posEC_FTList,
253 gainList,
254 1,
255 False,
256 isCorrection)
257
258 print("chans ",chans)
259 chanSel = self.channelSelection(chans)
260 return chanSel
261
262
263
264
265
266
267 # Return a list of COOL channels given a list of feedthrough
268 # numbers. This should be run separately for barrel/endcap and
269 # pos/neg, appending the results.
270 #
271 # Input args:
272 # feedThruList - list of feedthoughs, e.g. [4, 8, 30]
273 # may be a single number or list
274 # gainList - list of gains (0 to 2), may be a single number or list
275 # posNeg - = +1 positive or = -1 negative
276 # isBarrel - flag for barrel or endcap, default=True
277 # isCorrection - False - normal conditions, True - corrections (default is False)
279 feedThruList,
280 gainList,
281 posNeg,
282 isBarrel=True,
283 isCorrection=False):
284 # allow for single values rather than lists
285 fts = feedThruList
286 if operator.isNumberType(feedThruList): fts = [feedThruList]
287 gains = gainList
288 if operator.isNumberType(gainList): gains = [gainList]
289 fts.sort()
290 # Check value for posNeg
291 if posNeg != -1 and posNeg != +1:
292 print(__name__)
293 raise RuntimeError (__name__ +"posNeg must be either +/-1, found: " + str(posNeg))
294
295 offset = 0
296 # First get offset per gain
297 if isBarrel:
298 if posNeg == -1:
299 offset = self.offsetFtNegBarrel
300 else:
301 offset = self.offsetFtPosBarrel
302 else:
303 # Endcap
304 if posNeg == -1:
305 offset = self.offsetFtNegEndcap
306 else:
307 offset = self.offsetFtPosEndCap
308
309 # Now get channels
310 chans = []
311 # Now loop over gains and add in a FT for each gain
312 for gain in gains:
313 offset1 = offset + gain*self.ftPerGain
314 # Calculate channels for FT list
315 for ft in fts:
316 chans += [ft + offset1]
317
318 # Return channels
319 return chans
320
321
322
324 feedThruList,
325 gainList,
326 posNeg,
327 isBarrel=True,
328 isCorrection=False):
329 # allow for single values rather than lists
330 fts = feedThruList
331 if operator.isNumberType(feedThruList): fts = [feedThruList]
332 gains = gainList
333 if operator.isNumberType(gainList): gains = [gainList]
334 fts.sort()
335 # Check value for posNeg
336 if posNeg != -1 and posNeg != +1:
337 print(__name__)
338 raise RuntimeError (__name__ +"posNeg must be either +/-1, found: " + str(posNeg))
339
340 offset = 0
341 # First get offset per gain
342 if isBarrel:
343 if posNeg == -1:
344 offset = self.offsetFtNegBarrel
345 offsetPS = self.offsetFtNegBarrelPS
346 else:
347 offset = self.offsetFtPosBarrel
348 offsetPS = self.offsetFtPosBarrelPS
349 else:
350 # Endcap
351 if posNeg == -1:
352 offset = self.offsetFtNegEndcap
353 offsetPS = self.offsetFtNegEndcapPS
354 else:
355 offset = self.offsetFtPosEndCap
356 offsetPS = self.offsetFtPosEndCapPS
357
358 # Now get channels
359 chans = []
360 # Now loop over gains and add in a FT for each gain
361 for gain in gains:
362 offset1 = offset + gain*self.nChannelsPerGain
363 offset1PS = offsetPS + gain*self.nChannelsPerGain
364 # Calculate channels for FT list
365 for ft in fts:
366 chans += [ft + offset1] #Standard channel
367 chans += [ft + offset1PS] #Corresponding PS channel
368 # add the EMEC in HEC channels
369 if not isBarrel:
370 if (posNeg == -1 and ft==3): # C-Side
371 chans+=[228+3+gain*self.nChannelsPerGain]
372 if (posNeg == -1 and ft==10):# C-Side
373 chans+=[230+3+gain*self.ChannelsPerGain]
374 if (posNeg == -1 and ft==16):# C-Side
375 chans+=[232+3+gain*self.ChannelsPerGain]
376 if (posNeg == -1 and ft==22):# C-Side
377 chans+=[234+3+gain*self.ChannelsPerGain]
378 if (posNeg == 1 and ft==3): # A-Side
379 chans+=[229+3+gain*self.ChannelsPerGain]
380 if (posNeg == 1 and ft==10):# A-Side
381 chans+=[231+3+gain*self.ChannelsPerGain]
382 if (posNeg == 1 and ft==16):# A-Side
383 chans+=[233+3+gain*self.ChannelsPerGain]
384 if (posNeg == 1 and ft==22):# A-Side
385 chans+=[235+3+gain*self.ChannelsPerGain]
386
387
388 # Return channels
389 return chans
390
391 # Return a string with a channel selection specification of the form
392 #
393 # <channelSelection> x:y, z, a:b </channelSelection>
394 #
395 # Input: list of channel numbers
396 def channelSelection(self, channels):
397 chans = channels
398 chans.sort()
399 chanSel = "<channelSelection>"
400 first = True
401 for c in chans:
402 if first:
403 first = False
404 else:
405 chanSel += ', '
406 chanSel += str(c)
407 chanSel += "</channelSelection>"
408 return chanSel
409
410
411 # Return then COOL channel number given the SubDet name and gain
412 #
413 # Allowed subdet names: EMB, EMEC, HEC, FCAL
414 def subDetChannelSelection(self, subDetName, gain):
415 if gain >= self.nGains:
416 print("invalid gain: range in 0 to",self.nGain-1)
417 return -1
418 offset = gain*self.nSubDets + self.subDetsOffset
419 if subDetName == "Corr":
420 return gain
421 elif subDetName == "EMB":
422 return offset
423 elif subDetName == "EMEC":
424 return offset + 1
425 elif subDetName == "HEC":
426 return offset + 2
427 elif subDetName == "FCAL":
428 return offset + 3
429
430
431 # Given a COOL channel number extract the feedThrough number and as well provide
432 # identification as to where it is (isBarrel + posNeg) and provide the gain.
433 #
434 # return a tuple of { isBarrel(True/False), posNeg (-1,1), FeedThru (0-32), gain }
435 # FeedThru == -1 if this is an invalid feedthru number, or is a correction
436 #
437 # Example usage:
438 # (isBarrel, posNeg, feedThru, gain) = decoder.decodeFeedThruChannelNumber(chan)
439 #
440 # Input arg:
441 # channelNumber - COOL channel number
442
443 def decodeFeedThruChannelNumber(self, channelNumber):
444 # initial values
445 isBarrel = True
446 posNeg = -1
447 feedThru = -1
448 gain = channelNumber
449
450 if channelNumber < self.offsetFtNegBarrel:
451 # is a correction
452 return (isBarrel, posNeg, feedThru, gain)
453
454 chanNum = channelNumber - self.offsetFtNegBarrel
455 gain = chanNum/self.ftPerGain
456 chanNum = chanNum - gain*self.ftPerGain + self.offsetFtNegBarrel
457
458 if chanNum < self.offsetFtPosBarrel:
459 # is negative barrel
460 feedThru = chanNum - self.offsetFtNegBarrel
461 elif chanNum < self.offsetFtNegEndcap:
462 # is positive barrel
463 feedThru = chanNum - self.offsetFtPosBarrel
464 posNeg = 1
465 elif chanNum < self.offsetFtPosEndCap:
466 # is negative endcap
467 feedThru = chanNum - self.offsetFtNegEndcap
468 isBarrel = False
469 else:
470 # is positive endcap
471 feedThru = chanNum - self.offsetFtPosEndCap
472 posNeg = 1
473 isBarrel = False
474
475 return (isBarrel, posNeg, feedThru, gain)
476
477
478 def decodeExtFeedThruChannelNumber(self, channelNumber):
479 # initial values
480 isBarrel = True
481 posNeg = -1
482 feedThru = -1
483 gain = channelNumber
484
485 if channelNumber < self.offsetFtNegBarrel:
486 # is a correction
487 return (isBarrel, posNeg, feedThru, gain)
488
489 chanNum = channelNumber - self.offsetFtNegBarrel
490 gain = chanNum/self.nChannelsPerGain
491 chanNum = chanNum - gain*self.nChannelsPerGain + self.offsetFtNegBarrel
492
493 if chanNum < self.offsetFtPosBarrel:
494 # is negative barrel
495 feedThru = chanNum - self.offsetFtNegBarrel
496 posNeg=-1
497 isBarrel=True
498 elif chanNum < self.offsetFtNegEndcap:
499 # is positive barrel
500 feedThru = chanNum - self.offsetFtPosBarrel
501 posNeg = 1
502 isBarrel= True
503 elif chanNum < self.offsetFtPosEndCap:
504 # is negative endcap
505 feedThru = chanNum - self.offsetFtNegEndcap
506 posNeg=-1
507 isBarrel = False
508 elif chanNum < self.nFTAcc:
509 # is positive endcap
510 feedThru = chanNum - self.offsetFtPosEndCap
511 posNeg = 1
512 isBarrel = False
513 elif chanNum < self.offsetFtNegEndcapPS:
514 feedThru = chanNum - self.offsetFtNegBarrelPS
515 posNeg=-1
516 isBarrel=True
517 elif chanNum < self.offsetFtNegEndcapPS:
518 # is positive barrel
519 feedThru = chanNum - self.offsetFtPosBarrelPS
520 posNeg = 1
521 isBarrel= True
522 elif chanNum < self.offsetFtPosEndCapPS:
523 # is negative endcap
524 feedThru = chanNum - self.offsetFtNegEndcapPS
525 posNeg=-1
526 isBarrel = False
527 elif chanNum < self.nFTPS:
528 # is positive endcap
529 feedThru = chanNum - self.offsetFtPosEndCapPS
530 posNeg = 1
531 isBarrel = False
532 elif chanNum == 228+3:
533 feedThru = 3
534 posNeg = -1
535 isBarrel = False
536 elif chanNum == 229+3:
537 feedThru = 3
538 posNeg = 1
539 isBarrel = False
540 elif chanNum == 230+3:
541 feedThru = 10
542 posNeg = -1
543 isBarrel = False
544 elif chanNum == 231+3:
545 feedThru = 10
546 posNeg = 1
547 isBarrel = False
548 elif chanNum == 232+3:
549 feedThru = 16
550 posNeg = -1
551 isBarrel = False
552 elif chanNum == 233+3:
553 feedThru = 16
554 posNeg = 1
555 isBarrel = False
556 elif chanNum == 234+3:
557 feedThru = 22
558 posNeg = -1
559 isBarrel = False
560 elif chanNum == 235+3:
561 feedThru = 22
562 posNeg = 1
563 isBarrel = False
564 else: #should never happen
565 feedThru = -999
566 posNeg = -999
567 isBarrel = False
568
569 return (isBarrel, posNeg, feedThru, gain)
570
571
572 # Given a COOL channel number extract the subdet name and gain
573 #
574 # return a tuple of { detName, gain }
575 #
576 # Example usage:
577 # (detName, gain) = decoder.decodeSubDetChannelNumber(chan)
578 #
579 # Input arg:
580 # channelNumber - COOL channel number
581 #
582 def decodeSubDetChannelNumber(self, channelNumber):
583 # initial values
584 subDet = "Unknown"
585 gain = -1
586 if channelNumber < self.subDetsOffset:
587 # is a correction
588 subDet = "Corr"
589 gain = channelNumber
590 else:
591 chanSD = channelNumber - self.subDetsOffset
592 gain = chanSD/self.nSubDets
593 chanSD = chanSD - gain*self.nSubDets
594 if chanSD == 0:
595 subDet = "EMB"
596 elif chanSD == 1:
597 subDet = "EMEC"
598 elif chanSD == 2:
599 subDet = "HEC"
600 elif chanSD == 3:
601 subDet = "FCAL"
602
603 return (subDet, gain)
604
605
606
613
614
615if __name__ == '__main__':
616
617 # Test of LArCondContChannels
619
620 print("0 - unknown", decoder.isUnknown(0),"SG", decoder.isSingleGroup(0),"SDG",decoder.isSubDetectorGrouping(0),"FT",decoder.isFeedThroughGrouping(0))
621 print("1 - unknown", decoder.isUnknown(1),"SG", decoder.isSingleGroup(1),"SDG",decoder.isSubDetectorGrouping(1),"FT",decoder.isFeedThroughGrouping(1))
622 print("2 - unknown", decoder.isUnknown(2),"SG", decoder.isSingleGroup(2),"SDG",decoder.isSubDetectorGrouping(2),"FT",decoder.isFeedThroughGrouping(2))
623 print("3 - unknown", decoder.isUnknown(3),"SG", decoder.isSingleGroup(3),"SDG",decoder.isSubDetectorGrouping(3),"FT",decoder.isFeedThroughGrouping(3))
624
625 # Check channels list
626
627 # Barrel:
628 ftList_bp = [1,19,25,31]
629 ftList_bn = [0,18,24,30]
630 # EndCap:
631 ftList_ecp = [1,19,24]
632 ftList_ecn = [0,18,23]
633
634
635 print(" ====== CHECKS FOR FEEDTHROUGHGROUPING ====== ")
636
637 for gain in range(3):
638 chans = []
639 gainList = [ gain ]
640 chans += decoder.feedThruChannelSelection(ftList_bn, gainList, -1)
641 chans += decoder.feedThruChannelSelection(ftList_bp, gainList, 1)
642 chans += decoder.feedThruChannelSelection(ftList_ecn, gainList, -1, False)
643 chans += decoder.feedThruChannelSelection(ftList_ecp, gainList, 1, False)
644
645 print( "ft list b neg: ", ftList_bn)
646 print( "ft list b pos: ", ftList_bp)
647 print( "ft list ec neg: ", ftList_ecn)
648 print( "ft list ec pos: ", ftList_ecp)
649 print( "gain, chans: ", gainList, chans)
650
651 chanSel = decoder.folderFeedThruChannelSelection(ftList_bn,
652 ftList_bp,
653 ftList_ecn,
654 ftList_ecp,
655 gainList)
656 print( chanSel )
657
658 for chan in chans:
659 (isBarrel, posNeg, feedThru, gain) = decoder.decodeFeedThruChannelNumber(chan)
660 print( "chan, isBarrel, posNeg, feedThru, gain",chan, isBarrel, posNeg, feedThru, gain)
661
662
663 # Check subdet channel decoding
664 for chan in range(15):
665 (detName, gain) = decoder.decodeSubDetChannelNumber(chan)
666 chan1 = decoder.subDetChannelSelection(detName, gain)
667 print( "chan, detName, gain, and chan recalc", chan, detName, gain, chan1)
668
669
670 print( " ====== CHECKS FOR EXTENDED FEEDTHROUGHGROUPING ====== ")
671 for gain in range(3):
672 chans = []
673 gainList = [ gain ]
674 chans += decoder.extFeedThruChannelSelection(ftList_bn, gainList, -1)
675 chans += decoder.extFeedThruChannelSelection(ftList_bp, gainList, 1)
676 chans += decoder.extFeedThruChannelSelection(ftList_ecn, gainList, -1, False)
677 chans += decoder.extFeedThruChannelSelection(ftList_ecp, gainList, 1, False)
678
679 print( "ft list b neg: ", ftList_bn)
680 print( "ft list b pos: ", ftList_bp)
681 print( "ft list ec neg: ", ftList_ecn)
682 print( "ft list ec pos: ", ftList_ecp)
683 print( "gain, chans: ", gainList, chans)
684
685 chanSel = decoder.folderExtFeedThruChannelSelection(ftList_bn,
686 ftList_bp,
687 ftList_ecn,
688 ftList_ecp,
689 gainList)
690 print( chanSel)
691
692 for chan in chans:
693 (isBarrel, posNeg, feedThru, gain) = decoder.decodeExtFeedThruChannelNumber(chan)
694 print( "chan, isBarrel, posNeg, feedThru, gain",chan, isBarrel, posNeg, feedThru, gain)
695
696
void print(char *figname, TCanvas *c1)
folderFeedThruGroupChanSel(self, feedThruGroup, gainList=[0, 1, 2])
folderFeedThruChannelSelection(self, negB_FTList, posB_FTList, negEC_FTList, posEC_FTList, gainList, isCorrection=False)
feedThruChannelSelection(self, feedThruList, gainList, posNeg, isBarrel=True, isCorrection=False)
folderExtFeedThruChannelSelection(self, negB_FTList, posB_FTList, negEC_FTList, posEC_FTList, gainList, isCorrection=False)
extFeedThruChannelSelection(self, feedThruList, gainList, posNeg, isBarrel=True, isCorrection=False)