Adding functionality to generate AliESDEvent objects from dHLT raw data during offlin...
[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 {
56         /// Default constructor.
57 }
58
59
60 AliHLTMUONESDMaker::~AliHLTMUONESDMaker()
61 {
62         /// Default destructor.
63 }
64
65
66 int 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
98 int 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
107 const char* AliHLTMUONESDMaker::GetComponentID()
108 {
109         /// Inherited from AliHLTComponent. Returns the component ID.
110         
111         return AliHLTMUONConstants::ESDMakerId();
112 }
113
114
115 AliHLTComponentDataType 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
124 void 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
136 void 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         
143         constBase = sizeof(AliESDEvent) + 1024*1024;  // The extra 1 MByte is for auxilary objects created in AliESDEvent.
144         inputMultiplier = 10;
145 }
146
147
148 AliHLTComponent* AliHLTMUONESDMaker::Spawn()
149 {
150         /// Inherited from AliHLTComponent. Creates a new object instance.
151         
152         return new AliHLTMUONESDMaker();
153 }
154
155
156 int 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