Adding functionality to generate AliESDEvent objects from dHLT raw data during offlin...
[u/mrichter/AliRoot.git] / HLT / MUON / OfflineInterface / AliHLTMUONESDMaker.cxx
CommitLineData
649ab027 1/**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * All rights reserved. *
4 * *
5 * Primary Authors: *
6 * Artur Szostak <artursz@iafrica.com> *
7 * *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
16
17/* $Id: $ */
18
19///
20/// @file AliHLTMUONESDMaker.cxx
21/// @author Artur Szostak <artursz@iafrica.com>
22/// @date 30 June 2008
23/// @brief Implementation of the AliHLTMUONESDMaker component.
24///
25/// The ESD maker component converts dHLT raw internal reconstructed information
26/// into AliESDEvent objects.
27///
28
29#include "AliHLTMUONESDMaker.h"
30#include "AliHLTMUONEvent.h"
31#include "AliHLTMUONConstants.h"
32#include "AliHLTMUONUtils.h"
33#include "AliHLTMUONRecHit.h"
34#include "AliHLTMUONTriggerRecord.h"
35#include "AliHLTMUONMansoTrack.h"
36#include "AliHLTMUONDecision.h"
37#include "AliMUONConstants.h"
38#include "AliMUONVCluster.h"
39#include "AliESDEvent.h"
40#include "AliESDRun.h"
41#include "AliESDMuonTrack.h"
42#include "AliESDMuonCluster.h"
43#include "TClonesArray.h"
44#include <cmath>
45#include <cassert>
46
47
48ClassImp(AliHLTMUONESDMaker);
49
50
51AliHLTMUONESDMaker::AliHLTMUONESDMaker() :
52 AliHLTMUONProcessor(),
53 fWarnForUnexpecedBlock(false),
54 fMakeMinimalESD(false)
55{
56 /// Default constructor.
57}
58
59
60AliHLTMUONESDMaker::~AliHLTMUONESDMaker()
61{
62 /// Default destructor.
63}
64
65
66int AliHLTMUONESDMaker::DoInit(int argc, const char** argv)
67{
68 /// Inherited from AliHLTComponent.
69 /// Parses the command line parameters and initialises the component.
70
71 HLTInfo("Initialising dHLT ESD maker component.");
72
73 fWarnForUnexpecedBlock = false;
74 fMakeMinimalESD = false;
75
76 for (int i = 0; i < argc; i++)
77 {
78 if (strcmp(argv[i], "-make_minimal_esd") == 0)
79 {
80 fMakeMinimalESD = true;
81 continue;
82 }
83
84 if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
85 {
86 fWarnForUnexpecedBlock = true;
87 continue;
88 }
89
90 HLTError("Unknown option '%s'.", argv[i]);
91 return -EINVAL;
92 }
93
94 return 0;
95}
96
97
98int AliHLTMUONESDMaker::DoDeinit()
99{
100 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
101
102 HLTInfo("Deinitialising dHLT ESD maker component.");
103 return 0;
104}
105
106
107const char* AliHLTMUONESDMaker::GetComponentID()
108{
109 /// Inherited from AliHLTComponent. Returns the component ID.
110
111 return AliHLTMUONConstants::ESDMakerId();
112}
113
114
115AliHLTComponentDataType AliHLTMUONESDMaker::GetOutputDataType()
116{
117 /// Inherited from AliHLTComponent.
118 /// Returns the ESD object data type with MUON origin.
119
120 return AliHLTMUONConstants::ESDDataType();
121}
122
123
124void AliHLTMUONESDMaker::GetInputDataTypes(
125 vector<AliHLTComponentDataType>& list
126 )
127{
128 /// Inherited from AliHLTProcessor.
129 /// Returns the list of expected input data types.
130
131 list.push_back(AliHLTMUONConstants::TriggerRecordsBlockDataType());
132 list.push_back(AliHLTMUONConstants::MansoTracksBlockDataType());
133}
134
135
136void AliHLTMUONESDMaker::GetOutputDataSize(
137 unsigned long& constBase, double& inputMultiplier
138 )
139{
140 /// Inherited from AliHLTComponent.
141 /// Returns an estimate of the expected output data size.
142
94135365 143 constBase = sizeof(AliESDEvent) + 1024*1024; // The extra 1 MByte is for auxilary objects created in AliESDEvent.
649ab027 144 inputMultiplier = 10;
145}
146
147
148AliHLTComponent* AliHLTMUONESDMaker::Spawn()
149{
150 /// Inherited from AliHLTComponent. Creates a new object instance.
151
152 return new AliHLTMUONESDMaker();
153}
154
155
156int AliHLTMUONESDMaker::DoEvent(
157 const AliHLTComponentEventData& /*evtData*/,
158 AliHLTComponentTriggerData& /*trigData*/
159 )
160{
161 /// Inherited from AliHLTProcessor. Processes the new event data.
162
163 AliESDEvent event;
164 AliHLTUInt32_t clusterIndex = 0; // for the cluster unique ID.
165
166 // Create and fill in the standard ESD objects or just create the muon
167 // tracks array if so requested.
168 if (fMakeMinimalESD)
169 {
170 TClonesArray* muonTracks = new TClonesArray("AliESDMuonTrack",0);
171 muonTracks->SetName("MuonTracks");
172 event.AddObject(muonTracks);
173 event.GetStdContent();
174 }
175 else
176 {
177 event.CreateStdContent();
178 event.SetRunNumber(GetRunNo());
179 }
180
181 const AliHLTComponentBlockData* block = NULL;
182 AliHLTUInt32_t specification = 0; // Contains the output data block spec bits.
183 std::vector<const AliHLTMUONTriggerRecordStruct*> triggerRecords;
184
185 // First process the blocks of trigger records. We simply mark each trigger
186 // record in the triggerRecords array.
187 for (int i = 0; i < GetNumberOfInputBlocks(); i++)
188 {
189 block = GetInputBlock(i);
190 assert( block != NULL );
191
192 HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
193 i, DataType2Text(block->fDataType).c_str(), block->fPtr, block->fSize
194 );
195
196 if (block->fDataType == AliHLTMUONConstants::TriggerRecordsBlockDataType())
197 {
198 specification |= block->fSpecification;
199 AliHLTUInt8_t* ptr = reinterpret_cast<AliHLTUInt8_t*>(block->fPtr);
200 ptr += block->fOffset;
201 AliHLTMUONTriggerRecordsBlockReader inblock(ptr, block->fSize);
202 if (not BlockStructureOk(inblock)) continue;
203
204 for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
205 {
206 triggerRecords.push_back(&inblock[n]);
207 }
208 }
209 else
210 {
211 if (block->fDataType != AliHLTMUONConstants::MansoTracksBlockDataType())
212 {
213 // Log a message indicating that we got a data block that we
214 // do not know how to handle.
215 if (fWarnForUnexpecedBlock)
216 HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
217 DataType2Text(block->fDataType).c_str(), block->fSpecification
218 );
219 else
220 HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
221 DataType2Text(block->fDataType).c_str(), block->fSpecification
222 );
223 }
224 }
225 }
226
227 // Now we can look for tracks to add. We needed the ROOT trigger records
228 // and reco hits created before we can create track objects.
229 for (block = GetFirstInputBlock(AliHLTMUONConstants::MansoTracksBlockDataType());
230 block != NULL;
231 block = GetNextInputBlock()
232 )
233 {
234 specification |= block->fSpecification;
235 AliHLTUInt8_t* ptr = reinterpret_cast<AliHLTUInt8_t*>(block->fPtr);
236 ptr += block->fOffset;
237 AliHLTMUONMansoTracksBlockReader inblock(ptr, block->fSize);
238 if (not BlockStructureOk(inblock)) continue;
239
240 for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
241 {
242 const AliHLTMUONMansoTrackStruct& t = inblock[n];
243 AliESDMuonTrack muTrack;
244
245 AliHLTMUONParticleSign sign;
246 bool hitset[4];
247 AliHLTMUONUtils::UnpackMansoTrackFlags(
248 t.fFlags, sign, hitset
249 );
250
251 double signVal = 0;
252 switch (sign)
253 {
254 case kSignMinus: signVal = +1.; break;
255 case kSignUnknown: signVal = 0.; break;
256 case kSignPlus: signVal = -1.; break;
257 default:
258 HLTWarning("Got a track with an invalid sign value: %d", int(sign));
259 }
260
261 TVector3 mom(t.fPx, t.fPy, t.fPz);
262 if (mom.Mag() != 0)
263 muTrack.SetInverseBendingMomentum(signVal/mom.Mag());
264 else
265 muTrack.SetInverseBendingMomentum(0.);
266 muTrack.SetThetaX(atan2(t.fPx, t.fPz));
267 muTrack.SetThetaY(atan2(t.fPy, t.fPz));
268 muTrack.SetZ(0.);
269 muTrack.SetBendingCoor(0.);
270 muTrack.SetNonBendingCoor(0.);
271
272 // The Manso algorithm assumes the information at the
273 // Distance of Closest Approach and chamber 1 is the same
274 // as the vertex.
275 if (mom.Mag() != 0)
276 muTrack.SetInverseBendingMomentumAtDCA(1./mom.Mag());
277 else
278 muTrack.SetInverseBendingMomentumAtDCA(0.);
279 muTrack.SetThetaXAtDCA(atan2(t.fPx, t.fPz));
280 muTrack.SetThetaYAtDCA(atan2(t.fPy, t.fPz));
281 muTrack.SetBendingCoorAtDCA(0.);
282 muTrack.SetNonBendingCoorAtDCA(0.);
283
284 if (mom.Mag() != 0)
285 muTrack.SetInverseBendingMomentumUncorrected(1./mom.Mag());
286 else
287 muTrack.SetInverseBendingMomentumUncorrected(0.);
288 muTrack.SetThetaXUncorrected(atan2(t.fPx, t.fPz));
289 muTrack.SetThetaYUncorrected(atan2(t.fPy, t.fPz));
290 muTrack.SetZUncorrected(0.);
291 muTrack.SetBendingCoorUncorrected(0.);
292 muTrack.SetNonBendingCoorUncorrected(0.);
293
294 muTrack.SetChi2(t.fChi2);
295
296 // Fill in the track hit points.
297 Int_t nHits = 0;
298 for (int i = 0; i < 4; i++)
299 {
300 if (not hitset[i]) continue;
301
302 AliHLTUInt8_t chamber;
303 AliHLTUInt16_t detElemId;
304 AliHLTMUONUtils::UnpackRecHitFlags(t.fHit[i].fFlags, chamber, detElemId);
305
306 AliESDMuonCluster cluster;
307 cluster.SetUniqueID(AliMUONVCluster::BuildUniqueID(chamber, detElemId, clusterIndex++));
308 cluster.SetXYZ(t.fHit[i].fX, t.fHit[i].fY, t.fHit[i].fZ);
309 cluster.SetErrXY( // Use nominal values.
310 AliMUONConstants::DefaultNonBendingReso(),
311 AliMUONConstants::DefaultBendingReso()
312 );
313 cluster.SetCharge(-1.); // Indicate no total charge calculated.
314 cluster.SetChi2(-1.); // Indicate no fit made.
315 muTrack.AddCluster(cluster);
316 nHits++;
317 muTrack.AddInMuonClusterMap(i+6);
318 }
319
320 // Find the corresponding trigger record.
321 const AliHLTMUONTriggerRecordStruct* trigrec = NULL;
322 for (size_t k = 0; k < triggerRecords.size(); k++)
323 {
324 if (triggerRecords[k]->fId == t.fTrigRec)
325 {
326 trigrec = triggerRecords[k];
327 break;
328 }
329 }
330 // If the trigger record was found then fill its hit information also.
331 if (trigrec != NULL)
332 {
333 AliHLTMUONParticleSign trsign;
334 bool trhitset[4];
335 AliHLTMUONUtils::UnpackTriggerRecordFlags(
336 trigrec->fFlags, trsign, trhitset
337 );
338
339 for (int i = 0; i < 4; i++)
340 {
341 if (not trhitset[i]) continue;
342
343 AliHLTUInt8_t chamber;
344 AliHLTUInt16_t detElemId;
345 AliHLTMUONUtils::UnpackRecHitFlags(trigrec->fHit[i].fFlags, chamber, detElemId);
346
347 AliESDMuonCluster cluster;
348 cluster.SetUniqueID(AliMUONVCluster::BuildUniqueID(chamber, detElemId, clusterIndex++));
349 cluster.SetXYZ(
350 trigrec->fHit[i].fX,
351 trigrec->fHit[i].fY,
352 trigrec->fHit[i].fZ
353 );
354 cluster.SetErrXY( // Use nominal values.
355 AliMUONConstants::TriggerNonBendingReso(),
356 AliMUONConstants::TriggerBendingReso()
357 );
358 cluster.SetCharge(-1.); // Indicate no total charge calculated.
359 cluster.SetChi2(-1.); // Indicate no fit made.
360 muTrack.AddCluster(cluster);
361 nHits++;
362 muTrack.AddInMuonClusterMap(i+10);
363 }
364 }
365 else
366 {
367 HLTWarning("Trigger record (ID = %d) not found for track ID = %d.",
368 t.fTrigRec, t.fId
369 );
370 }
371
372 muTrack.SetNHit(nHits);
373 event.AddMuonTrack(&muTrack);
374 }
375 }
376
377 PushBack(&event, AliHLTMUONConstants::ESDDataType(), specification);
378
379 return 0;
380}
381