Adding output data type of rootifier component to the constants class.
[u/mrichter/AliRoot.git] / HLT / MUON / OfflineInterface / AliHLTMUONESDMaker.cxx
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
48 ClassImp(AliHLTMUONESDMaker);
49
50
51 AliHLTMUONESDMaker::AliHLTMUONESDMaker() :
52         AliHLTMUONProcessor(),
53         fWarnForUnexpecedBlock(false),
54         fMakeMinimalESD(false),
55         fAddCustomData(false)
56 {
57         /// Default constructor.
58 }
59
60
61 AliHLTMUONESDMaker::~AliHLTMUONESDMaker()
62 {
63         /// Default destructor.
64 }
65
66
67 bool AliHLTMUONESDMaker::IgnoreArgument(const char* arg) const
68 {
69         /// Return true if the argument is one of -cdbpath -run or -delaysetup
70         /// to prevent the parent class from parsing these arguments in DoInit.
71         
72         if (strcmp(arg, "-cdbpath") == 0 or strcmp(arg, "-run") == 0 or
73             strcmp(arg, "-delaysetup") == 0)
74         {
75                 return true;
76         }
77         else
78         {
79                 return false;
80         }
81 }
82
83
84 int AliHLTMUONESDMaker::DoInit(int argc, const char** argv)
85 {
86         /// Inherited from AliHLTComponent.
87         /// Parses the command line parameters and initialises the component.
88         
89         HLTInfo("Initialising dHLT ESD maker component.");
90
91         // Inherit the parents functionality.
92         int result = AliHLTMUONProcessor::DoInit(argc, argv);
93         if (result != 0) return result;
94         
95         fWarnForUnexpecedBlock = false;
96         fMakeMinimalESD = false;
97         
98         for (int i = 0; i < argc; i++)
99         {
100                 if (ArgumentAlreadyHandled(i, argv[i])) continue;
101
102                 if (strcmp(argv[i], "-make_minimal_esd") == 0)
103                 {
104                         fMakeMinimalESD = true;
105                         continue;
106                 }
107                 
108                 if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
109                 {
110                         fWarnForUnexpecedBlock = true;
111                         continue;
112                 }
113                 
114                 if (strcmp(argv[i], "-add_rootified_objects") == 0)
115                 {
116                         fAddCustomData = true;
117                         continue;
118                 }
119
120                 HLTError("Unknown option '%s'.", argv[i]);
121                 return -EINVAL;
122         }
123         
124         return 0;
125 }
126
127
128 int AliHLTMUONESDMaker::DoDeinit()
129 {
130         /// Inherited from AliHLTComponent. Performs a cleanup of the component.
131         
132         HLTInfo("Deinitialising dHLT ESD maker component.");
133         return 0;
134 }
135
136
137 const char* AliHLTMUONESDMaker::GetComponentID()
138 {
139         /// Inherited from AliHLTComponent. Returns the component ID.
140         
141         return AliHLTMUONConstants::ESDMakerId();
142 }
143
144
145 AliHLTComponentDataType AliHLTMUONESDMaker::GetOutputDataType()
146 {
147         /// Inherited from AliHLTComponent.
148         /// Returns the ESD object data type with MUON origin.
149         
150         return AliHLTMUONConstants::ESDDataType();
151 }
152
153
154 void AliHLTMUONESDMaker::GetInputDataTypes(AliHLTComponentDataTypeList& list)
155 {
156         /// Inherited from AliHLTProcessor.
157         /// Returns the list of expected input data types.
158         
159         list.push_back(AliHLTMUONConstants::TriggerRecordsBlockDataType());
160         list.push_back(AliHLTMUONConstants::MansoTracksBlockDataType());
161 }
162
163
164 void AliHLTMUONESDMaker::GetOutputDataSize(
165                 unsigned long& constBase, double& inputMultiplier
166         )
167 {
168         /// Inherited from AliHLTComponent.
169         /// Returns an estimate of the expected output data size.
170         
171         constBase = sizeof(AliESDEvent) + 1024*1024;  // The extra 1 MByte is for auxilary objects created in AliESDEvent.
172         inputMultiplier = 10;
173 }
174
175
176 AliHLTComponent* AliHLTMUONESDMaker::Spawn()
177 {
178         /// Inherited from AliHLTComponent. Creates a new object instance.
179         
180         return new AliHLTMUONESDMaker();
181 }
182
183
184 int AliHLTMUONESDMaker::DoEvent(
185                 const AliHLTComponentEventData& evtData,
186                 AliHLTComponentTriggerData& trigData
187         )
188 {
189         /// Inherited from AliHLTProcessor. Processes the new event data.
190         
191         AliESDEvent event;
192         AliHLTUInt32_t clusterIndex = 0;  // for the cluster unique ID.
193         
194         // Create and fill in the standard ESD objects or just create the muon
195         // tracks array if so requested.
196         if (fMakeMinimalESD)
197         {
198                 TClonesArray* muonTracks = new TClonesArray("AliESDMuonTrack",0);
199                 muonTracks->SetName("MuonTracks");
200                 event.AddObject(muonTracks);
201                 event.GetStdContent();
202         }
203         else
204         {
205                 event.CreateStdContent();
206                 event.SetRunNumber(GetRunNo());
207         }
208         
209         const AliHLTComponentBlockData* block = NULL;
210         AliHLTUInt32_t specification = 0;  // Contains the output data block spec bits.
211         std::vector<const AliHLTMUONTriggerRecordStruct*> triggerRecords;
212
213         // First process the blocks of trigger records. We simply mark each trigger
214         // record in the triggerRecords array.
215         for (int i = 0; i < GetNumberOfInputBlocks(); i++)
216         {
217                 block = GetInputBlock(i);
218                 assert( block != NULL );
219                 
220                 HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
221                         i, DataType2Text(block->fDataType).c_str(), block->fPtr, block->fSize
222                 );
223                 
224                 if (block->fDataType == AliHLTMUONConstants::TriggerRecordsBlockDataType())
225                 {
226                         specification |= block->fSpecification;
227                         AliHLTMUONTriggerRecordsBlockReader inblock(block->fPtr, block->fSize);
228                         if (not BlockStructureOk(inblock))
229                         {
230                                 if (DumpDataOnError()) DumpEvent(evtData, trigData);
231                                 continue;
232                         }
233                         
234                         for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
235                         {
236                                 triggerRecords.push_back(&inblock[n]);
237                         }
238                 }
239                 else if (block->fDataType == AliHLTMUONConstants::RootifiedEventDataType() and fAddCustomData)
240                 {
241                         // Do nothing for now, will handle this later.
242                 }
243                 else
244                 {
245                         if (block->fDataType != AliHLTMUONConstants::MansoTracksBlockDataType())
246                         {
247                                 // Log a message indicating that we got a data block that we
248                                 // do not know how to handle.
249                                 if (fWarnForUnexpecedBlock)
250                                         HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
251                                                 DataType2Text(block->fDataType).c_str(), block->fSpecification
252                                         );
253                                 else
254                                         HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
255                                                 DataType2Text(block->fDataType).c_str(), block->fSpecification
256                                         );
257                         }
258                 }
259         }
260         
261         // If we were requested to add all dHLT rootified data objects then do so.
262         if (fAddCustomData)
263         {
264                 const AliHLTComponentDataType& type = AliHLTMUONConstants::RootifiedEventDataType();
265                 const char* classname = AliHLTMUONEvent::Class_Name();
266                 const TObject* obj = NULL;
267                 for (obj = GetFirstInputObject(type, classname); obj != NULL; obj = GetNextInputObject())
268                 {
269                         // Clone the object since the ESD takes ownership of it.
270                         event.AddObject(obj->Clone());
271                 }
272         }
273         
274         // Now we can look for tracks to add. We needed the ROOT trigger records
275         // and reco hits created before we can create track objects.
276         for (block = GetFirstInputBlock(AliHLTMUONConstants::MansoTracksBlockDataType());
277              block != NULL;
278              block = GetNextInputBlock()
279             )
280         {
281                 specification |= block->fSpecification;
282                 AliHLTMUONMansoTracksBlockReader inblock(block->fPtr, block->fSize);
283                 if (not BlockStructureOk(inblock))
284                 {
285                         if (DumpDataOnError()) DumpEvent(evtData, trigData);
286                         continue;
287                 }
288                 
289                 for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
290                 {
291                         const AliHLTMUONMansoTrackStruct& t = inblock[n];
292                         AliESDMuonTrack muTrack;
293                         
294                         AliHLTMUONParticleSign sign;
295                         bool hitset[4];
296                         AliHLTMUONUtils::UnpackMansoTrackFlags(
297                                         t.fFlags, sign, hitset
298                                 );
299                         
300                         double signVal = 0;
301                         switch (sign)
302                         {
303                         case kSignMinus:   signVal = +1.; break;
304                         case kSignUnknown: signVal =  0.; break;
305                         case kSignPlus:    signVal = -1.; break;
306                         default:
307                                 HLTWarning("Got a track with an invalid sign value: %d", int(sign));
308                         }
309                         
310                         TVector3 mom(t.fPx, t.fPy, t.fPz);
311                         if (mom.Mag() != 0)
312                                 muTrack.SetInverseBendingMomentum(signVal/mom.Mag());
313                         else
314                                 muTrack.SetInverseBendingMomentum(0.);
315                         muTrack.SetThetaX(atan2(t.fPx, t.fPz));
316                         muTrack.SetThetaY(atan2(t.fPy, t.fPz));
317                         muTrack.SetZ(0.);
318                         muTrack.SetBendingCoor(0.);
319                         muTrack.SetNonBendingCoor(0.);
320                         
321                         // The Manso algorithm assumes the information at the
322                         // Distance of Closest Approach and chamber 1 is the same
323                         // as the vertex.
324                         if (mom.Mag() != 0)
325                                 muTrack.SetInverseBendingMomentumAtDCA(1./mom.Mag());
326                         else
327                                 muTrack.SetInverseBendingMomentumAtDCA(0.);
328                         muTrack.SetThetaXAtDCA(atan2(t.fPx, t.fPz));
329                         muTrack.SetThetaYAtDCA(atan2(t.fPy, t.fPz));
330                         muTrack.SetBendingCoorAtDCA(0.);
331                         muTrack.SetNonBendingCoorAtDCA(0.);
332                         
333                         if (mom.Mag() != 0)
334                                 muTrack.SetInverseBendingMomentumUncorrected(1./mom.Mag());
335                         else
336                                 muTrack.SetInverseBendingMomentumUncorrected(0.);
337                         muTrack.SetThetaXUncorrected(atan2(t.fPx, t.fPz));
338                         muTrack.SetThetaYUncorrected(atan2(t.fPy, t.fPz));
339                         muTrack.SetZUncorrected(0.);
340                         muTrack.SetBendingCoorUncorrected(0.);
341                         muTrack.SetNonBendingCoorUncorrected(0.);
342                         
343                         muTrack.SetChi2(t.fChi2);
344                         
345                         // Fill in the track hit points.
346                         Int_t nHits = 0;
347                         for (int i = 0; i < 4; i++)
348                         {
349                                 if (not hitset[i]) continue;
350                                 
351                                 AliHLTUInt8_t chamber;
352                                 AliHLTUInt16_t detElemId;
353                                 AliHLTMUONUtils::UnpackRecHitFlags(t.fHit[i].fFlags, chamber, detElemId);
354                                 
355                                 AliESDMuonCluster cluster;
356                                 cluster.SetUniqueID(AliMUONVCluster::BuildUniqueID(chamber, detElemId, clusterIndex++));
357                                 cluster.SetXYZ(t.fHit[i].fX, t.fHit[i].fY, t.fHit[i].fZ);
358                                 cluster.SetErrXY(    // Use nominal values.
359                                                 AliHLTMUONConstants::DefaultNonBendingReso(),
360                                                 AliHLTMUONConstants::DefaultBendingReso()
361                                         );
362                                 cluster.SetCharge(-1.);   // Indicate no total charge calculated.
363                                 cluster.SetChi2(-1.);   // Indicate no fit made.
364                                 muTrack.AddCluster(cluster);
365                                 nHits++;
366                                 muTrack.AddInMuonClusterMap(i+6);
367                         }
368                         
369                         // Find the corresponding trigger record.
370                         const AliHLTMUONTriggerRecordStruct* trigrec = NULL;
371                         for (size_t k = 0; k < triggerRecords.size(); k++)
372                         {
373                                 if (triggerRecords[k]->fId == t.fTrigRec)
374                                 {
375                                         trigrec = triggerRecords[k];
376                                         break;
377                                 }
378                         }
379                         // If the trigger record was found then fill its hit information also.
380                         if (trigrec != NULL)
381                         {
382                                 AliHLTMUONParticleSign trsign;
383                                 bool trhitset[4];
384                                 AliHLTMUONUtils::UnpackTriggerRecordFlags(
385                                                 trigrec->fFlags, trsign, trhitset
386                                         );
387                                 
388                                 for (int i = 0; i < 4; i++)
389                                 {
390                                         if (not trhitset[i]) continue;
391                                         
392                                         AliHLTUInt8_t chamber;
393                                         AliHLTUInt16_t detElemId;
394                                         AliHLTMUONUtils::UnpackRecHitFlags(trigrec->fHit[i].fFlags, chamber, detElemId);
395                                 
396                                         AliESDMuonCluster cluster;
397                                         cluster.SetUniqueID(AliMUONVCluster::BuildUniqueID(chamber, detElemId, clusterIndex++));
398                                         cluster.SetXYZ(
399                                                         trigrec->fHit[i].fX,
400                                                         trigrec->fHit[i].fY,
401                                                         trigrec->fHit[i].fZ
402                                                 );
403                                         cluster.SetErrXY(    // Use nominal values.
404                                                         AliMUONConstants::TriggerNonBendingReso(),
405                                                         AliMUONConstants::TriggerBendingReso()
406                                                 );
407                                         cluster.SetCharge(-1.);   // Indicate no total charge calculated.
408                                         cluster.SetChi2(-1.);   // Indicate no fit made.
409                                         muTrack.AddCluster(cluster);
410                                         nHits++;
411                                         muTrack.AddInMuonClusterMap(i+10);
412                                 }
413                         }
414                         else
415                         {
416                                 HLTWarning("Trigger record (ID = %d) not found for track ID = %d.",
417                                         t.fTrigRec, t.fId
418                                 );
419                         }
420                         
421                         muTrack.SetNHit(nHits);
422                         event.AddMuonTrack(&muTrack);
423                 }
424         }
425         
426         PushBack(&event, AliHLTMUONConstants::ESDDataType(), specification);
427         
428         return 0;
429 }
430