Project
Loading...
Searching...
No Matches
TRDEventDisplayFeedSpec.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#include "TMath.h"
13
15
20
22#include "Field/MagneticField.h"
24
25using namespace o2::framework;
26using namespace o2::globaltracking;
27
28namespace o2
29{
30namespace trd
31{
32
34{
35 LOG(info) << "Initializing event display feed...";
36}
37
38json TRDEventDisplayFeedSpec::getTracksJson(gsl::span<const TrackTRD> tracks, gsl::span<const Tracklet64> tracklets, gsl::span<const TrackTriggerRecord> trackTrigRecs, int iEvent)
39{
40 json trackArray = json::array();
41
42 const auto& trigRec = trackTrigRecs[iEvent];
43 for (int iTrack = 0; iTrack < trigRec.getNumberOfTracks(); ++iTrack) {
44 TrackTRD track = tracks[iTrack + trigRec.getFirstTrack()];
45 std::string trackId = Form("E%d_T%d", iEvent, iTrack);
46
47 float alpha = track.getAlpha();
48 if (alpha < 0) {
49 alpha += TMath::Pi() * 2;
50 }
51
52 int sector = TMath::Nint(18.0 * alpha / (2 * TMath::Pi()) - 0.5);
53 int stack;
54 for (int iLayer = 0; iLayer < 6; iLayer++) {
55 int trackletIdx = track.getTrackletIndex(iLayer);
56 if (trackletIdx != -1) {
57 int detector = tracklets[trackletIdx].getDetector();
58 stack = detector % 30 / 6;
59 break;
60 }
61 }
62
63 // Tangent of the track momentum dip angle
64 float tanLambda = track.getParam(3);
65 float lambdaDeg = TMath::ATan(tanLambda) * 180 / TMath::Pi();
66
67 // Record stacks with tracks for look-up by writeDigits() later
68 int layerZero = mGeo->getDetector(0, stack, sector);
69 mUsedDetectors.set(layerZero);
70
71 json trackJson = {
72 {"id", trackId},
73 {"stk", stack},
74 {"sec", sector},
75 {"typ", "Trd"},
76 {"i", {{"pT", track.getPt()}, {"alpha", track.getAlpha()}, {"lambda", lambdaDeg}, {"pid", (int)track.getPID().getID()}}},
77 {"path", json::array()},
78 {"tlids", json::array()}};
79
80 bool ok;
81 for (int x = 1; x <= 470; x += 10) {
82 auto xyz = track.getXYZGloAt(x, mBz, ok);
83 json point = {{"x", xyz.X()}, {"y", xyz.Y()}, {"z", xyz.Z()}};
84 trackJson["path"].push_back(point);
85 }
86
87 // Match TRD tracklets to track
88 for (int iLayer = 0; iLayer < 6; iLayer++) {
89 // trackletIdx gives absolute index of tracklet across all events
90 int trackletIdx = track.getTrackletIndex(iLayer);
91 if (trackletIdx != -1) {
92 int trackletCount = 0;
93 // count number of tracklets in all events prior to iEvent
94 for (int i = 0; i < iEvent; i++) {
95 trackletCount += mTrigRecs[i].getNumberOfTracklets();
96 }
97 // trackletId needs relative tracklet index within single event
98 std::string trackletId = Form("E%d_L%d", iEvent, trackletIdx - trackletCount);
99 // record {trackletId, trackId} pair in order to match tracks to tracklets in printTracklets()
100 mTrackletMap.insert(std::pair<std::string, std::string>(trackletId, trackId));
101 trackJson["tlids"].push_back(trackletId);
102 }
103 }
104 trackArray.push_back(trackJson);
105 }
106 return trackArray;
107}
108
109json TRDEventDisplayFeedSpec::getTrackletsJson(gsl::span<const Tracklet64> tracklets, int iEvent)
110{
111 json trackletArray = json::array();
112
113 const auto& trigRec = mTrigRecs[iEvent];
114 for (int iTracklet = 0; iTracklet < trigRec.getNumberOfTracklets(); ++iTracklet) {
115 Tracklet64 tracklet = tracklets[iTracklet + trigRec.getFirstTracklet()];
116 CalibratedTracklet cTracklet = mTransformer.transformTracklet(tracklet);
117
118 std::string trackletId = Form("E%d_L%d", iEvent, iTracklet);
119 // Find matched track if it exists
120 std::string trackId = (mTrackletMap.find(trackletId) != mTrackletMap.end() ? mTrackletMap.at(trackletId) : "null");
121
122 int detector = tracklet.getDetector();
123 int sector = mGeo->getSector(detector);
124 int stack = mGeo->getStack(detector);
125 int layer = mGeo->getLayer(detector);
126
127 // Start position of both raw and calibrated tracklet in event display
128 float localY = cTracklet.getY();
129 // Slope of raw tracklet (key dyDxAN in JSON)
130 float rawDyDx = tracklet.getUncalibratedDy() / mGeo->cdrHght();
131 // Slope of calibrated tracklet
132 float dyDx = cTracklet.getDy() / mGeo->cdrHght();
133
134 json trackletJson = {
135 {"id", trackletId},
136 {"stk", stack},
137 {"sec", sector},
138 {"lyr", layer},
139 {"row", tracklet.getPadRow()},
140 {"trk", trackId},
141 {"lY", localY},
142 {"dyDx", dyDx},
143 {"dyDxAN", rawDyDx}};
144
145 if (trackId == "null") {
146 trackletJson["trk"] = nullptr;
147 }
148
149 trackletArray.push_back(trackletJson);
150 }
151 return trackletArray;
152}
153
154void TRDEventDisplayFeedSpec::writeDigits(gsl::span<const Digit> digits, int iEvent)
155{
156 const auto& trigRec = mTrigRecs[iEvent];
157 for (int det = 0; det < constants::MAXCHAMBER; det += 6) {
158 if (mUsedDetectors[det]) {
159 int sector = mGeo->getSector(det);
160 int stack = mGeo->getStack(det);
161
162 json digitsJson = {
163 {"evid", iEvent},
164 {"lyrs", json::array()}};
165
166 for (int iLayer = 0; iLayer < 6; iLayer++) {
167 json layerJson = {
168 {"lyr", iLayer},
169 {"pads", json::array()}};
170
171 for (int iDigit = trigRec.getFirstDigit(); iDigit < trigRec.getFirstDigit() + trigRec.getNumberOfDigits(); ++iDigit) {
172 Digit digit = digits[iDigit];
173
174 int detector = digit.getDetector();
175
176 if (detector == det + iLayer) {
177 // Digits are in stack with track
178 int row = digit.getPadRow();
179 int col = digit.getPadCol();
180
181 json padJson = {
182 {"row", row},
183 {"col", col},
184 {"tbins", json::array()}};
185
186 for (auto adc : digit.getADC()) {
187 padJson["tbins"].push_back(adc);
188 }
189 layerJson["pads"].push_back(padJson);
190 }
191 }
192 digitsJson["lyrs"].push_back(layerJson);
193 }
194 std::ofstream digitsOut(Form("../alice-trd-event-display/data/o2/E%d.%d.%d.json", iEvent, sector, stack));
195 digitsOut << digitsJson.dump(4);
196 }
197 }
198} // namespace trd
199
201{
202 LOG(info) << "Running event display feed...";
203
204 json jsonData = json::array();
205
206 auto tracks = pc.inputs().get<gsl::span<TrackTRD>>("trdtracks");
207 auto tracklets = pc.inputs().get<gsl::span<Tracklet64>>("trdtracklets");
208 auto digits = pc.inputs().get<gsl::span<Digit>>("trddigits");
209
210 mTrigRecs = pc.inputs().get<gsl::span<TriggerRecord>>("trdtriggerrec");
211 auto trackTrigRecs = pc.inputs().get<gsl::span<TrackTriggerRecord>>("tracktriggerrec");
212
213 int nEvents = std::min((int)mTrigRecs.size(), mNeventsMax);
214
215 for (int iEvent = 0; iEvent < nEvents; ++iEvent) {
216 const auto& trackTrigRec = trackTrigRecs[iEvent];
217
218 if (trackTrigRec.getNumberOfTracks() == 0) {
219 continue;
220 }
221
222 mUsedDetectors.reset();
223
224 // Get run parameters
226 auto prop = o2::base::Propagator::Instance();
227 mBz = prop->getNominalBz();
228
230 double beamEnergy = field->getBeamEnergy();
231 std::string beamType = field->getBeamTypeText();
232
234 auto triggers = grp->getDetsTrigger();
235 auto triggerNames = o2::detectors::DetID::getNames(triggers);
236
237 json eventJson = {
238 {"id", Form("E%d", iEvent)},
239 {"i", {{"be", beamEnergy}, {"bt", beamType}, {"ft", triggerNames}}},
240 {"tracks", json::array()},
241 {"trklts", json::array()}};
242
243 eventJson["tracks"] = getTracksJson(tracks, tracklets, trackTrigRecs, iEvent);
244
245 eventJson["trklts"] = getTrackletsJson(tracklets, iEvent);
246
247 writeDigits(digits, iEvent);
248
249 jsonData.push_back(eventJson);
250 }
251 std::ofstream jsScriptOut(Form("../alice-trd-event-display/data/o2/script.js"));
252 // Path to data file for alicetrd.web: lxplus.cern.ch:/eos/project/a/alice-trd/www/eventdisplay/data/o2/script.js
253
254 jsScriptOut << "function getDigitsLoadUrl(eventNo, sector, stack) { return `"
255 << "data/o2/${eventNo}.${sector}.${stack}.json`; }"
256 << std::endl
257 << std::endl
258 << "function getData() {\n\treturn "
259 << jsonData.dump(4) << "}";
260}
261
263{
264 std::vector<InputSpec> inputs;
265 std::vector<OutputSpec> outputs;
266
267 inputs.emplace_back("trdtracks", "TRD", "MATCH_ITSTPC", 0, Lifetime::Timeframe);
268 inputs.emplace_back("trdtracklets", "TRD", "TRACKLETS", 0, Lifetime::Timeframe);
269 inputs.emplace_back("trddigits", ConcreteDataTypeMatcher{o2::header::gDataOriginTRD, "DIGITS"}, Lifetime::Timeframe);
270 inputs.emplace_back("trdtriggerrec", "TRD", "TRKTRGRD", 0, Lifetime::Timeframe);
271 inputs.emplace_back("tracktriggerrec", "TRD", "TRGREC_ITSTPC", 0, Lifetime::Timeframe);
272
273 return DataProcessorSpec{
274 "TRDEVENTDISPLAYFEED",
275 inputs,
276 outputs,
277 AlgorithmSpec{adaptFromTask<TRDEventDisplayFeedSpec>(nEventsMax)},
278 Options{}};
279}
280
281} // namespace trd
282} //end namespace o2
int32_t i
Header of the General Run Parameters object.
Definition of the MagF class.
uint32_t col
Definition RawData.h:4
uint32_t stack
Definition RawData.h:1
static int initFieldFromGRP(const o2::parameters::GRPMagField *grp, bool verbose=false)
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
Definition Propagator.h:143
static std::string getNames(mask_t mask, char delimiter=',')
Definition DetID.cxx:74
static MagneticField * createNominalField(int fld, bool uniform=false)
create field from rounded value, i.e. +-5 or +-2 kGauss
decltype(auto) get(R binding, int part=0) const
InputRecord & inputs()
The inputs associated with this processing context.
static GRPObject * loadFrom(const std::string &grpFileName="")
int getDetector() const
Definition Digit.h:79
int getPadRow() const
Definition Digit.h:81
ArrayADC const & getADC() const
Definition Digit.h:91
int getPadCol() const
Definition Digit.h:82
json getTrackletsJson(gsl::span< const Tracklet64 > tracklets, int iEvent)
json getTracksJson(gsl::span< const TrackTRD > tracks, gsl::span< const Tracklet64 > tracklets, gsl::span< const TrackTriggerRecord > trackTrigRecs, int iEvent)
void run(o2::framework::ProcessingContext &pc) override
void init(o2::framework::InitContext &ic) override
void writeDigits(gsl::span< const Digit > digits, int iEvent)
CalibratedTracklet transformTracklet(Tracklet64 tracklet, bool trackingFrame=true) const
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
GLint GLenum GLint x
Definition glcorearb.h:403
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
constexpr o2::header::DataOrigin gDataOriginTRD
Definition DataHeader.h:577
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > Options
constexpr int MAXCHAMBER
the maximum number of installed chambers
Definition Constants.h:30
o2::framework::DataProcessorSpec getTRDEventDisplayFeedSpec(int nEventsMax)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
void writeDigits()
const int nEvents
Definition test_Fifo.cxx:27
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Digit > digits
std::vector< int > row
std::vector< Tracklet64 > tracklets
ArrayADC adc