Line data Source code
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 "TList.h"
45 : #include <cmath>
46 : #include <cassert>
47 :
48 :
49 6 : ClassImp(AliHLTMUONESDMaker);
50 :
51 :
52 : AliHLTMUONESDMaker::AliHLTMUONESDMaker() :
53 3 : AliHLTMUONProcessor(),
54 3 : fWarnForUnexpecedBlock(false),
55 3 : fMakeMinimalESD(false),
56 3 : fAddCustomData(false),
57 3 : fMakeClonesArray(false),
58 3 : fMakeESDDataBlock(true),
59 3 : fClusterIndex(0)
60 15 : {
61 : /// Default constructor.
62 6 : }
63 :
64 :
65 : AliHLTMUONESDMaker::~AliHLTMUONESDMaker()
66 12 : {
67 : /// Default destructor.
68 12 : }
69 :
70 :
71 : bool AliHLTMUONESDMaker::IgnoreArgument(const char* arg) const
72 : {
73 : /// Return true if the argument is one of -cdbpath -run or -delaysetup
74 : /// to prevent the parent class from parsing these arguments in DoInit.
75 :
76 0 : if (strcmp(arg, "-cdbpath") == 0 or strcmp(arg, "-run") == 0 or
77 0 : strcmp(arg, "-delaysetup") == 0)
78 : {
79 0 : return true;
80 : }
81 : else
82 : {
83 0 : return false;
84 : }
85 0 : }
86 :
87 :
88 : int AliHLTMUONESDMaker::DoInit(int argc, const char** argv)
89 : {
90 : /// Inherited from AliHLTComponent.
91 : /// Parses the command line parameters and initialises the component.
92 :
93 0 : HLTInfo("Initialising dHLT ESD maker component.");
94 :
95 : // Inherit the parents functionality.
96 0 : int result = AliHLTMUONProcessor::DoInit(argc, argv);
97 0 : if (result != 0) return result;
98 :
99 0 : fWarnForUnexpecedBlock = false;
100 0 : fMakeMinimalESD = false;
101 0 : fMakeClonesArray = false;
102 0 : fMakeESDDataBlock = true;
103 :
104 0 : for (int i = 0; i < argc; i++)
105 : {
106 0 : if (ArgumentAlreadyHandled(i, argv[i])) continue;
107 :
108 0 : if (strcmp(argv[i], "-make_minimal_esd") == 0)
109 : {
110 0 : fMakeMinimalESD = true;
111 0 : continue;
112 : }
113 :
114 0 : if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
115 : {
116 0 : fWarnForUnexpecedBlock = true;
117 0 : continue;
118 : }
119 :
120 0 : if (strcmp(argv[i], "-add_rootified_objects") == 0)
121 : {
122 0 : fAddCustomData = true;
123 0 : continue;
124 : }
125 :
126 0 : if (strcmp(argv[i], "-makeclonesarray") == 0)
127 : {
128 0 : fMakeClonesArray = true;
129 0 : continue;
130 : }
131 :
132 0 : if (strcmp(argv[i], "-makeonlyclonesarray") == 0)
133 : {
134 0 : fMakeMinimalESD = true;
135 0 : fMakeClonesArray = true;
136 0 : fMakeESDDataBlock = false;
137 0 : continue;
138 : }
139 :
140 0 : HLTError("Unknown option '%s'.", argv[i]);
141 0 : return -EINVAL;
142 : }
143 :
144 0 : return 0;
145 0 : }
146 :
147 :
148 : int AliHLTMUONESDMaker::DoDeinit()
149 : {
150 : /// Inherited from AliHLTComponent. Performs a cleanup of the component.
151 :
152 0 : HLTInfo("Deinitialising dHLT ESD maker component.");
153 0 : return 0;
154 : }
155 :
156 :
157 : const char* AliHLTMUONESDMaker::GetComponentID()
158 : {
159 : /// Inherited from AliHLTComponent. Returns the component ID.
160 :
161 198 : return AliHLTMUONConstants::ESDMakerId();
162 : }
163 :
164 :
165 : AliHLTComponentDataType AliHLTMUONESDMaker::GetOutputDataType()
166 : {
167 : /// Inherited from AliHLTComponent. Returns kAliHLTMultipleDataType.
168 : /// Refer to GetOutputDataTypes for all returned data types.
169 :
170 0 : return kAliHLTMultipleDataType;
171 : }
172 :
173 :
174 : int AliHLTMUONESDMaker::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
175 : {
176 : /// Inherited from AliHLTComponent.
177 : /// Returns the ESD object and kAliHLTDataTypeTObject data type with MUON origin.
178 :
179 0 : list.push_back(AliHLTMUONConstants::ESDDataType());
180 0 : list.push_back(kAliHLTDataTypeTObject | kAliHLTDataOriginMUON);
181 0 : return list.size();
182 : }
183 :
184 :
185 : void AliHLTMUONESDMaker::GetInputDataTypes(AliHLTComponentDataTypeList& list)
186 : {
187 : /// Inherited from AliHLTProcessor.
188 : /// Returns the list of expected input data types.
189 :
190 0 : list.push_back(AliHLTMUONConstants::TriggerRecordsBlockDataType());
191 0 : list.push_back(AliHLTMUONConstants::MansoTracksBlockDataType());
192 0 : list.push_back(AliHLTMUONConstants::TracksBlockDataType());
193 0 : }
194 :
195 :
196 : void AliHLTMUONESDMaker::GetOutputDataSize(
197 : unsigned long& constBase, double& inputMultiplier
198 : )
199 : {
200 : /// Inherited from AliHLTComponent.
201 : /// Returns an estimate of the expected output data size.
202 :
203 0 : constBase = sizeof(AliESDEvent) + 1024*1024; // The extra 1 MByte is for auxilary objects created in AliESDEvent.
204 0 : inputMultiplier = 10;
205 0 : }
206 :
207 :
208 : AliHLTComponent* AliHLTMUONESDMaker::Spawn()
209 : {
210 : /// Inherited from AliHLTComponent. Creates a new object instance.
211 :
212 0 : return new AliHLTMUONESDMaker();
213 0 : }
214 :
215 :
216 : int AliHLTMUONESDMaker::DoEvent(
217 : const AliHLTComponentEventData& evtData,
218 : AliHLTComponentTriggerData& trigData
219 : )
220 : {
221 : /// Inherited from AliHLTProcessor. Processes the new event data.
222 :
223 0 : AliESDEvent event;
224 0 : fClusterIndex = 0; // for the cluster unique ID.
225 :
226 : // Create and fill in the standard ESD objects or just create the muon
227 : // tracks array if so requested.
228 0 : if (fMakeMinimalESD)
229 : {
230 0 : TClonesArray* muonTracks = new TClonesArray("AliESDMuonTrack",2);
231 0 : muonTracks->SetName("MuonTracks");
232 0 : event.AddObject(muonTracks);
233 0 : TClonesArray* muonClusters = new TClonesArray("AliESDMuonCluster",0);
234 0 : muonClusters->SetName("MuonClusters");
235 0 : event.AddObject(muonClusters);
236 0 : event.GetStdContent();
237 0 : }
238 : else
239 : {
240 0 : event.CreateStdContent();
241 0 : event.SetRunNumber(GetRunNo());
242 : }
243 :
244 : const AliHLTComponentBlockData* block = NULL;
245 : AliHLTUInt32_t specification = 0; // Contains the output data block spec bits.
246 0 : std::vector<const AliHLTMUONTriggerRecordStruct*> triggerRecords;
247 :
248 : // First process the blocks of trigger records. We simply mark each trigger
249 : // record in the triggerRecords array.
250 0 : for (int i = 0; i < GetNumberOfInputBlocks(); i++)
251 : {
252 0 : block = GetInputBlock(i);
253 0 : assert( block != NULL );
254 :
255 : HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
256 : i, DataType2Text(block->fDataType).c_str(), block->fPtr, block->fSize
257 : );
258 :
259 0 : if (block->fDataType == AliHLTMUONConstants::TriggerRecordsBlockDataType())
260 : {
261 0 : specification |= block->fSpecification;
262 0 : AliHLTMUONTriggerRecordsBlockReader inblock(block->fPtr, block->fSize);
263 0 : if (not BlockStructureOk(inblock))
264 : {
265 0 : if (DumpDataOnError()) DumpEvent(evtData, trigData);
266 0 : continue;
267 : }
268 :
269 0 : for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
270 : {
271 0 : triggerRecords.push_back(&inblock[n]);
272 : }
273 0 : }
274 0 : else if (block->fDataType == AliHLTMUONConstants::RootifiedEventDataType() and fAddCustomData)
275 : {
276 : // Do nothing for now, will handle this later.
277 : }
278 : else
279 : {
280 0 : if (block->fDataType != AliHLTMUONConstants::MansoTracksBlockDataType() and
281 0 : block->fDataType != AliHLTMUONConstants::TracksBlockDataType() )
282 : {
283 : // Log a message indicating that we got a data block that we
284 : // do not know how to handle.
285 0 : if (fWarnForUnexpecedBlock)
286 0 : HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
287 : DataType2Text(block->fDataType).c_str(), block->fSpecification
288 : );
289 : #ifdef __DEBUG
290 : else
291 : HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
292 : DataType2Text(block->fDataType).c_str(), block->fSpecification
293 : );
294 : #endif
295 : }
296 : }
297 : }
298 :
299 : // If we were requested to add all dHLT rootified data objects then do so.
300 0 : if (fAddCustomData)
301 : {
302 0 : const AliHLTComponentDataType& type = AliHLTMUONConstants::RootifiedEventDataType();
303 0 : const char* classname = AliHLTMUONEvent::Class_Name();
304 : const TObject* obj = NULL;
305 0 : for (obj = GetFirstInputObject(type, classname); obj != NULL; obj = GetNextInputObject())
306 : {
307 : // Clone the object since the ESD takes ownership of it.
308 0 : event.AddObject(obj->Clone());
309 : }
310 0 : }
311 :
312 : // Now we can look for tracks to add. We needed the ROOT trigger records
313 : // and reco hits created before we can create track objects.
314 0 : for (block = GetFirstInputBlock(AliHLTMUONConstants::MansoTracksBlockDataType());
315 0 : block != NULL;
316 0 : block = GetNextInputBlock()
317 : )
318 : {
319 0 : specification |= block->fSpecification;
320 0 : AliHLTMUONMansoTracksBlockReader inblock(block->fPtr, block->fSize);
321 0 : if (not BlockStructureOk(inblock))
322 : {
323 0 : if (DumpDataOnError()) DumpEvent(evtData, trigData);
324 0 : continue;
325 : }
326 :
327 0 : for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
328 : {
329 0 : const AliHLTMUONMansoTrackStruct& t = inblock[n];
330 0 : AliESDMuonTrack *muTrack = event.NewMuonTrack();
331 :
332 0 : AliHLTMUONParticleSign sign;
333 0 : bool hitset[4];
334 0 : AliHLTMUONUtils::UnpackMansoTrackFlags(t.fFlags, sign, hitset);
335 :
336 : double signVal = 0;
337 0 : switch (sign)
338 : {
339 0 : case kSignMinus: signVal = +1.; break;
340 0 : case kSignUnknown: signVal = 0.; break;
341 0 : case kSignPlus: signVal = -1.; break;
342 : default:
343 0 : HLTWarning("Got a track with an invalid sign value: %d", int(sign));
344 : }
345 :
346 0 : TVector3 mom(t.fPx, t.fPy, t.fPz);
347 0 : if (mom.Mag() != 0)
348 0 : muTrack->SetInverseBendingMomentum(signVal/mom.Mag());
349 : else
350 0 : muTrack->SetInverseBendingMomentum(0.);
351 0 : muTrack->SetThetaX(atan2(t.fPx, t.fPz));
352 0 : muTrack->SetThetaY(atan2(t.fPy, t.fPz));
353 0 : muTrack->SetZ(0.);
354 0 : muTrack->SetBendingCoor(0.);
355 0 : muTrack->SetNonBendingCoor(0.);
356 :
357 : // The Manso algorithm assumes the information at the
358 : // Distance of Closest Approach and chamber 1 is the same
359 : // as the vertex.
360 0 : if (mom.Mag() != 0)
361 0 : muTrack->SetInverseBendingMomentumAtDCA(1./mom.Mag());
362 : else
363 0 : muTrack->SetInverseBendingMomentumAtDCA(0.);
364 0 : muTrack->SetThetaXAtDCA(atan2(t.fPx, t.fPz));
365 0 : muTrack->SetThetaYAtDCA(atan2(t.fPy, t.fPz));
366 0 : muTrack->SetBendingCoorAtDCA(0.);
367 0 : muTrack->SetNonBendingCoorAtDCA(0.);
368 :
369 0 : if (mom.Mag() != 0)
370 0 : muTrack->SetInverseBendingMomentumUncorrected(1./mom.Mag());
371 : else
372 0 : muTrack->SetInverseBendingMomentumUncorrected(0.);
373 0 : muTrack->SetThetaXUncorrected(atan2(t.fPx, t.fPz));
374 0 : muTrack->SetThetaYUncorrected(atan2(t.fPy, t.fPz));
375 0 : muTrack->SetZUncorrected(0.);
376 0 : muTrack->SetBendingCoorUncorrected(0.);
377 0 : muTrack->SetNonBendingCoorUncorrected(0.);
378 :
379 0 : muTrack->SetChi2(t.fChi2);
380 :
381 : // Fill in the track hit points.
382 0 : for (int i = 0; i < 4; i++)
383 : {
384 0 : if (not hitset[i]) continue;
385 :
386 0 : AliHLTUInt8_t chamber;
387 0 : AliHLTUInt16_t detElemId;
388 0 : AliHLTMUONUtils::UnpackRecHitFlags(t.fHit[i].fFlags, chamber, detElemId);
389 :
390 0 : AliESDMuonCluster *cluster = event.NewMuonCluster();
391 0 : cluster->SetUniqueID(AliMUONVCluster::BuildUniqueID(chamber, detElemId, fClusterIndex++));
392 0 : cluster->SetXYZ(t.fHit[i].fX, t.fHit[i].fY, t.fHit[i].fZ);
393 0 : cluster->SetErrXY( // Use nominal values.
394 0 : AliHLTMUONConstants::DefaultNonBendingReso(),
395 0 : AliHLTMUONConstants::DefaultBendingReso()
396 : );
397 0 : cluster->SetCharge(-1.); // Indicate no total charge calculated.
398 0 : cluster->SetChi2(-1.); // Indicate no fit made.
399 0 : muTrack->AddClusterId(cluster->GetUniqueID());
400 0 : muTrack->AddInMuonClusterMap(i+6);
401 0 : }
402 :
403 0 : FillTriggerInfo(triggerRecords, t.fTrigRec, t.fId, *muTrack, event);
404 0 : }
405 0 : }
406 :
407 0 : for (block = GetFirstInputBlock(AliHLTMUONConstants::TracksBlockDataType());
408 0 : block != NULL;
409 0 : block = GetNextInputBlock()
410 : )
411 : {
412 0 : specification |= block->fSpecification;
413 0 : AliHLTMUONTracksBlockReader inblock(block->fPtr, block->fSize);
414 0 : if (not BlockStructureOk(inblock))
415 : {
416 0 : if (DumpDataOnError()) DumpEvent(evtData, trigData);
417 0 : continue;
418 : }
419 :
420 0 : for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
421 : {
422 0 : const AliHLTMUONTrackStruct& t = inblock[n];
423 0 : AliESDMuonTrack *muTrack = event.NewMuonTrack();
424 :
425 0 : AliHLTMUONParticleSign sign;
426 0 : bool hitset[16];
427 0 : AliHLTMUONUtils::UnpackTrackFlags(t.fFlags, sign, hitset);
428 :
429 0 : muTrack->SetInverseBendingMomentum(t.fInverseBendingMomentum);
430 0 : muTrack->SetThetaX(t.fThetaX);
431 0 : muTrack->SetThetaY(t.fThetaY);
432 0 : muTrack->SetZ(t.fZ);
433 0 : muTrack->SetBendingCoor(t.fY);
434 0 : muTrack->SetNonBendingCoor(t.fX);
435 :
436 : // The full tracker assumes the information at the
437 : // Distance of Closest Approach and chamber 1 is the same
438 : // as the vertex.
439 0 : muTrack->SetInverseBendingMomentumAtDCA(t.fInverseBendingMomentum);
440 0 : muTrack->SetThetaXAtDCA(t.fThetaX);
441 0 : muTrack->SetThetaYAtDCA(t.fThetaY);
442 0 : muTrack->SetBendingCoorAtDCA(t.fY);
443 0 : muTrack->SetNonBendingCoorAtDCA(t.fX);
444 :
445 0 : muTrack->SetInverseBendingMomentumUncorrected(t.fInverseBendingMomentum);
446 0 : muTrack->SetThetaXUncorrected(t.fThetaX);
447 0 : muTrack->SetThetaYUncorrected(t.fThetaY);
448 0 : muTrack->SetZUncorrected(t.fZ);
449 0 : muTrack->SetBendingCoorUncorrected(t.fY);
450 0 : muTrack->SetNonBendingCoorUncorrected(t.fX);
451 :
452 0 : muTrack->SetChi2(t.fChi2);
453 :
454 : // Fill in the track hit points.
455 0 : for (int i = 0; i < 16; i++)
456 : {
457 0 : if (not hitset[i]) continue;
458 :
459 0 : AliHLTUInt8_t chamber;
460 0 : AliHLTUInt16_t detElemId;
461 0 : AliHLTMUONUtils::UnpackRecHitFlags(t.fHit[i].fFlags, chamber, detElemId);
462 :
463 0 : AliESDMuonCluster *cluster = event.NewMuonCluster();
464 0 : cluster->SetUniqueID(AliMUONVCluster::BuildUniqueID(chamber, detElemId, fClusterIndex++));
465 0 : cluster->SetXYZ(t.fHit[i].fX, t.fHit[i].fY, t.fHit[i].fZ);
466 0 : cluster->SetErrXY( // Use nominal values.
467 0 : AliHLTMUONConstants::DefaultNonBendingReso(),
468 0 : AliHLTMUONConstants::DefaultBendingReso()
469 : );
470 0 : cluster->SetCharge(-1.); // Indicate no total charge calculated.
471 0 : cluster->SetChi2(-1.); // Indicate no fit made.
472 0 : muTrack->AddClusterId(cluster->GetUniqueID());
473 0 : muTrack->AddInMuonClusterMap(chamber);
474 0 : }
475 :
476 0 : FillTriggerInfo(triggerRecords, t.fTrigRec, t.fId, *muTrack, event);
477 0 : }
478 0 : }
479 :
480 0 : if (fMakeClonesArray and event.GetList() != NULL)
481 : {
482 0 : PushBack(
483 0 : event.GetList()->FindObject("MuonTracks"),
484 0 : kAliHLTDataTypeTObject | kAliHLTDataOriginMUON,
485 : specification
486 : );
487 0 : PushBack(
488 0 : event.GetList()->FindObject("MuonClusters"),
489 0 : kAliHLTDataTypeTObject | kAliHLTDataOriginMUON,
490 : specification
491 : );
492 : }
493 0 : if (fMakeESDDataBlock)
494 : {
495 0 : PushBack(&event, AliHLTMUONConstants::ESDDataType(), specification);
496 : }
497 : return 0;
498 0 : }
499 :
500 :
501 : void AliHLTMUONESDMaker::FillTriggerInfo(
502 : const AliTriggerRecordList& triggerRecords,
503 : AliHLTInt32_t trigRecId, AliHLTInt32_t trackId,
504 : AliESDMuonTrack& muTrack, AliESDEvent& event
505 : )
506 : {
507 : /// Finds the trigger record with ID = 'id' and fills the output ESD track structure.
508 :
509 : // Find the corresponding trigger record.
510 : const AliHLTMUONTriggerRecordStruct* trigrec = NULL;
511 0 : for (size_t k = 0; k < triggerRecords.size(); k++)
512 : {
513 0 : if (triggerRecords[k]->fId == trigRecId)
514 : {
515 0 : trigrec = triggerRecords[k];
516 0 : break;
517 : }
518 : }
519 : // If the trigger record was found then fill its hit information also.
520 0 : if (trigrec != NULL)
521 : {
522 0 : AliHLTMUONParticleSign trsign;
523 0 : bool trhitset[4];
524 0 : AliHLTMUONUtils::UnpackTriggerRecordFlags(
525 0 : trigrec->fFlags, trsign, trhitset
526 : );
527 :
528 0 : for (int i = 0; i < 4; i++)
529 : {
530 0 : if (not trhitset[i]) continue;
531 :
532 0 : AliHLTUInt8_t chamber;
533 0 : AliHLTUInt16_t detElemId;
534 0 : AliHLTMUONUtils::UnpackRecHitFlags(trigrec->fHit[i].fFlags, chamber, detElemId);
535 :
536 0 : AliESDMuonCluster *cluster = event.NewMuonCluster();
537 0 : cluster->SetUniqueID(AliMUONVCluster::BuildUniqueID(chamber, detElemId, fClusterIndex++));
538 0 : cluster->SetXYZ(
539 0 : trigrec->fHit[i].fX,
540 0 : trigrec->fHit[i].fY,
541 0 : trigrec->fHit[i].fZ
542 : );
543 0 : cluster->SetErrXY( // Use nominal values.
544 0 : AliMUONConstants::TriggerNonBendingReso(),
545 0 : AliMUONConstants::TriggerBendingReso()
546 : );
547 0 : cluster->SetCharge(-1.); // Indicate no total charge calculated.
548 0 : cluster->SetChi2(-1.); // Indicate no fit made.
549 0 : muTrack.AddClusterId(cluster->GetUniqueID());
550 0 : muTrack.AddInMuonClusterMap(i+10);
551 0 : }
552 0 : }
553 : else
554 : {
555 0 : HLTWarning("Trigger record (ID = %d) not found for track ID = %d.",
556 : trigRecId, trackId
557 : );
558 : }
559 0 : }
|