ATLAS Offline Software
addL1.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 # Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
4 """
5 Module for creating the rob fragments normally send through the RoIB
6 using the information readout from the ROSs.
7 It can be used either standalone or as a "-Z" plugin to athenaMT/PT.
8 
9 Note that a bunch of information is hardcoded and could change if
10 the data format of the CTP/MUCTPI/L1Calo ROIB fragments change.
11 
12 The payload of the CTP DAQ ROB (0x770000) is as follows:
13  1 x NumberTimeWords
14  N x CTPdataformat.DAQwordsPerBunch
15  1 x numberExtraPayloadWords
16 This differs from the CTP ROB (0x770001) where only one bunch crossing is saved (N=1).
17 """
18 
19 import os
20 import sys
21 
22 import logging
23 import eformat
24 import libpyevent_storage as EventStorage
25 from TrigByteStreamTools import CTPfragment
26 from TrigByteStreamTools.CTPfragment import CTPdataformat
27 
28 def modify(event):
29  """Fills in the L1R from the most appropriate source (L1/ROS or Dummy)."""
30 
31  map=[[eformat.helper.SubDetector.TDAQ_CTP,0,1],
32  [eformat.helper.SubDetector.TDAQ_MUON_CTP_INTERFACE,0,1],
33  [eformat.helper.SubDetector.TDAQ_CALO_CLUSTER_PROC_ROI,136,168],
34  [eformat.helper.SubDetector.TDAQ_CALO_CLUSTER_PROC_ROI,137,169],
35  [eformat.helper.SubDetector.TDAQ_CALO_CLUSTER_PROC_ROI,138,170],
36  [eformat.helper.SubDetector.TDAQ_CALO_CLUSTER_PROC_ROI,139,171],
37  [eformat.helper.SubDetector.TDAQ_CALO_JET_PROC_ROI,140,172],
38  [eformat.helper.SubDetector.TDAQ_CALO_JET_PROC_ROI,141,173]]
39 
40  DaqRobs=[None]*len(map)
41  L2Robs=[None]*len(map)
42 
43 
44  for rob in event:
45  cnt=0
46  for match in map:
47  if rob.source_id()==eformat.helper.SourceIdentifier(match[0],match[1]):
48  DaqRobs[cnt]=rob
49  elif rob.source_id()==eformat.helper.SourceIdentifier(match[0],match[2]):
50  L2Robs[cnt]=rob
51  cnt+=1
52 
53  # There are no CTP ROBs, event can not be recovered and should be skipped
54  if (not DaqRobs[0]) and (not L2Robs[0]):
55  logging.warning(' Plugin "addL1": No DAQ CTP fragment. Event can not be recovered. Event will be skipped. L1 id = %d, Global id = %d ', event.lvl1_id(), event.global_id())
56  return False
57 
58  # Workaround for corrupted events
59  new_event=eformat.write.FullEventFragment()
60  new_event.copy_header(event)
61  for rob in event:
62  new_event.append_unchecked(rob)
63 
64  for idx in range(len(map)):
65  if L2Robs[idx]:
66  pass
67  elif DaqRobs[idx]:
68 
69  rob=eformat.write.ROBFragment(DaqRobs[idx])
70  rob.source_id(eformat.helper.SourceIdentifier(map[idx][0],map[idx][2]))
71 
72  daq_data = [r for r in rob.rod_data()]
73 
74  if idx==0: #CTP DAQ ROD
75  # offset to triggered bunch trigger words
76  offset = CTPdataformat.NumberTimeWords + CTPfragment.lvl1AcceptBunch(rob)*CTPdataformat.DAQwordsPerBunch
77  # Copy leading words (once per fragment)
78  data = daq_data[:CTPdataformat.NumberTimeWords]
79  # Copy per bunch words
80  data += daq_data[offset : offset+CTPdataformat.DAQwordsPerBunch]
81  # Copy extra payload
82  data += daq_data[-CTPfragment.numberExtraPayloadWords(rob):]
83  rob.rod_data(data)
84 
85  elif idx==1: #MuCTPi DAQ ROB
86  data=[]
87  if len(DaqRobs[idx].rod_data()) > 0:
88  muctpBC=(DaqRobs[idx].rod_data()[0]>>18)&7
89  for word in DaqRobs[idx].rod_data()[1:]:
90  if (word>>14)&7==muctpBC and (word>>26)&1:
91  data+=[(word&0x3fff)|(((word>>17)&0x1ff)<<14)]
92 
93  if len(data)==0:
94  rob=eformat.write.ROBFragment()
95  rob.copy_header(DaqRobs[idx])
96  rob.source_id(eformat.helper.SourceIdentifier(map[idx][0],map[idx][2]))
97  else:
98  rob.rod_data(data)
99 
100  new_event.append(rob)
101  else:
102  rob=eformat.write.ROBFragment()
103  rob.source_id(eformat.helper.SourceIdentifier(map[idx][0],map[idx][2]))
104  new_event.append(rob)
105 
106  return new_event.readonly()
107 
108 def CTPreco(input_file,output_file):
109  input = eformat.istream([input_file])
110  dr=EventStorage.pickDataReader(input_file)
111  output = eformat.ostream(core_name="subset",
112  run_number=dr.runNumber(),
113  trigger_type=dr.triggerType(),
114  detector_mask=dr.detectorMask(),
115  beam_type=dr.beamType(),
116  beam_energy=dr.beamEnergy())
117  for event in input:
118  new_event = modify(event)
119  if not new_event:
120  continue
121  else:
122  output.write(new_event)
123  tmp_file_name = output.last_filename()
124  del output
125  os.rename(tmp_file_name,output_file)
126 
127 
128 
129 if __name__ == "__main__":
130  if len(sys.argv)!=3:
131  print('usage: %s <infile> <outfile>' % sys.argv[0])
132  sys.exit(1)
133 
134  CTPreco(sys.argv[1],sys.argv[2])
python.addL1.CTPreco
def CTPreco(input_file, output_file)
Definition: addL1.py:108
python.addL1.modify
def modify(event)
Definition: addL1.py:28
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
Muon::print
std::string print(const MuPatSegment &)
Definition: MuonTrackSteering.cxx:28