]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCEsdWriterComponent.cxx
update
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCEsdWriterComponent.cxx
1 // @(#) $Id$
2
3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project        * 
5 //* ALICE Experiment at CERN, All rights reserved.                         *
6 //*                                                                        *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8 //*                  for The ALICE HLT Project.                            *
9 //*                                                                        *
10 //* Permission to use, copy, modify and distribute this software and its   *
11 //* documentation strictly for non-commercial purposes is hereby granted   *
12 //* without fee, provided that the above copyright notice appears in all   *
13 //* copies and that both the copyright notice and this permission notice   *
14 //* appear in the supporting documentation. The authors make no claims     *
15 //* about the suitability of this software for any purpose. It is          *
16 //* provided "as is" without express or implied warranty.                  *
17 //**************************************************************************
18
19 /** @file   AliHLTTPCEsdWriterComponent.cxx
20     @author Matthias Richter
21     @date   
22     @brief  Writer component to store tracks of the HLT TPC conformal
23             mapping tracker in the AliESD format
24 */
25
26 // see header file for class documentation
27 // or
28 // refer to README to build package
29 // or
30 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
31
32 #include <cassert>
33 #include "AliHLTTPCEsdWriterComponent.h"
34 #include "AliESDEvent.h"
35 #include "AliESDtrack.h"
36 #include "AliCDBEntry.h"
37 #include "AliCDBManager.h"
38 #include "TTree.h"
39 #include "TList.h"
40 #include "AliHLTTPCTrack.h"
41 #include "AliHLTTPCTrackArray.h"
42 #include "AliHLTTPCTrackletDataFormat.h"
43 #include "AliHLTTPCDefinitions.h"
44 #include "AliHLTTPCTransform.h"
45 #include "AliHLTTPCClusterFinder.h"
46 #include <vector>
47
48 /** ROOT macro for the implementation of ROOT specific class methods */
49 ClassImp(AliHLTTPCEsdWriterComponent)
50
51 AliHLTTPCEsdWriterComponent::AliHLTTPCEsdWriterComponent()
52   :
53   fSolenoidBz(0),fDoMCLabels(0)
54 {
55   // see header file for class documentation
56   // or
57   // refer to README to build package
58   // or
59   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
60 }
61
62 AliHLTTPCEsdWriterComponent::~AliHLTTPCEsdWriterComponent()
63 {
64   // see header file for class documentation
65 }
66
67 AliHLTTPCEsdWriterComponent::AliWriter::AliWriter()
68   :
69   fTree(NULL),
70   fESD(NULL),
71   fBase(new AliHLTTPCEsdWriterComponent)
72 {
73   // see header file for class documentation
74   // or
75   // refer to README to build package
76   // or
77   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
78 }
79
80 AliHLTTPCEsdWriterComponent::AliWriter::~AliWriter()
81 {
82   // see header file for class documentation
83   if (fBase) delete fBase;
84   fBase=NULL;
85 }
86
87 void AliHLTTPCEsdWriterComponent::AliWriter::GetInputDataTypes(AliHLTComponentDataTypeList& list)
88 {
89   // see header file for class documentation
90   list.push_back(AliHLTTPCDefinitions::fgkTrackSegmentsDataType);
91   list.push_back(AliHLTTPCDefinitions::fgkTracksDataType);
92   list.push_back(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo);
93 }
94
95 int AliHLTTPCEsdWriterComponent::AliWriter::InitWriter()
96 {
97   // see header file for class documentation
98   int iResult=0;
99   fESD = new AliESDEvent;
100   if (fESD) {
101     fESD->CreateStdContent();
102     fTree = new TTree("esdTree", "Tree with HLT ESD objects");
103     if (fTree) {
104       fTree->SetDirectory(0);
105       fESD->WriteToTree(fTree);
106     }
107   }
108   if (fTree==NULL) {
109     iResult=-ENOMEM;
110   }
111
112   if (iResult>=0) {
113     iResult=fBase->Reconfigure(NULL, NULL);
114   }
115
116   return iResult;
117 }
118
119 int AliHLTTPCEsdWriterComponent::AliWriter::CloseWriter()
120 {
121   // see header file for class documentation
122   int iResult=0;
123   if (fTree) {
124     // the esd structure is written to the user info and is
125     // needed in te ReadFromTree method to read all objects correctly
126     if (fESD) fTree->GetUserInfo()->Add(fESD);
127     WriteObject(kAliHLTVoidEventID, fTree);
128     fTree->GetUserInfo()->Clear();
129     TTree* pTree=fTree;
130     fTree=NULL;
131     delete pTree;
132   } else {
133     HLTWarning("not initialized");
134   }
135
136   if (fESD) {
137     delete fESD;
138   }
139   iResult=AliHLTRootFileWriterComponent::CloseWriter();
140   return iResult;
141 }
142
143 int AliHLTTPCEsdWriterComponent::AliWriter::DumpEvent( const AliHLTComponentEventData& evtData,
144                                             const AliHLTComponentBlockData* blocks, 
145                                             AliHLTComponentTriggerData& /*trigData*/ )
146 {
147   // see header file for class documentation
148   int iResult=0;
149   TTree* pTree=fTree;
150   assert(fBase);
151   if (pTree && fBase) {
152     if (fESD) {
153       AliESDEvent* pESD=fESD;
154
155       iResult=fBase->ProcessBlocks(pTree, pESD, blocks, (int)evtData.fBlockCnt);
156
157     } else {
158       iResult=-ENOMEM;
159     }
160   }
161   return iResult;
162 }
163
164 int AliHLTTPCEsdWriterComponent::AliWriter::ScanArgument(int argc, const char** argv)
165 {
166   // see header file for class documentation
167   int iResult=AliHLTRootFileWriterComponent::ScanArgument(argc, argv);
168   return iResult;
169 }
170
171 int AliHLTTPCEsdWriterComponent::ProcessBlocks(TTree* pTree, AliESDEvent* pESD,
172                                                const AliHLTComponentBlockData* blocks,
173                                                int nBlocks, int* pMinSlice,
174                                                int* pMaxSlice)
175 {
176   // see header file for class documentation
177
178   int iResult=0;
179   int iAddedDataBlocks=0;
180   fDoMCLabels = 0;
181   if (pESD && blocks) {
182       pESD->Reset(); 
183       pESD->SetMagneticField(fSolenoidBz);
184       const AliHLTComponentBlockData* iter = NULL;
185       AliHLTTPCTrackletData* inPtr=NULL;
186       int bIsTrackSegs=0;
187
188       // first read all the MC information
189       for (int ndx=0; ndx<nBlocks && iResult>=0; ndx++) {
190         iter = blocks+ndx;
191         if(iter->fDataType == AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo ) {
192           if( !fDoMCLabels ){
193             for( int i=0; i<36*6; i++ ){
194               fClusterLabels[i] = 0;
195               fNClusterLabels[i] = 0;
196             }
197           }
198           Int_t slice=AliHLTTPCDefinitions::GetMinSliceNr(iter->fSpecification);
199           Int_t patch=AliHLTTPCDefinitions::GetMinPatchNr(iter->fSpecification);
200           fClusterLabels[ slice*6 + patch] = (AliHLTTPCClusterFinder::ClusterMCInfo *)iter->fPtr;
201           fNClusterLabels[ slice*6 + patch] = iter->fSize/sizeof(AliHLTTPCClusterFinder::ClusterMCInfo);
202           fDoMCLabels = 1;
203         }
204       }
205
206       // do the conversion of tracks
207       for (int ndx=0; ndx<nBlocks && iResult>=0; ndx++) {
208         iter = blocks+ndx;
209         if ( (bIsTrackSegs=(iter->fDataType == AliHLTTPCDefinitions::fgkTrackSegmentsDataType))==1 ||
210              iter->fDataType == AliHLTTPCDefinitions::fgkTracksDataType ) {
211           Int_t minslice=AliHLTTPCDefinitions::GetMinSliceNr(iter->fSpecification);
212           Int_t maxslice=AliHLTTPCDefinitions::GetMaxSliceNr(iter->fSpecification);
213           if (bIsTrackSegs==0) {
214             // slice parameter and data specification ignored, tracks already in global coordinates
215             minslice=-1;
216             maxslice=-1;
217             if (pMinSlice) *pMinSlice=0;
218             if (pMaxSlice) *pMaxSlice=AliHLTTPCTransform::GetNSlice()-1;
219           } else {
220             if (pMinSlice && (*pMinSlice==-1 || *pMinSlice>minslice)) *pMinSlice=minslice;
221             if (pMaxSlice && (*pMaxSlice==-1 || *pMaxSlice<maxslice)) *pMaxSlice=maxslice;
222           }
223           //HLTDebug("dataspec %#x minslice %d", iter->fSpecification, minslice);
224           if (minslice >=-1 && minslice<AliHLTTPCTransform::GetNSlice()) {
225             if (minslice!=maxslice) {
226               HLTWarning("data from multiple sectors in one block: "
227                          "possible mismatch in treatment of local coordinate system");
228             }
229             AliHLTTPCTrackArray tracks;
230             inPtr=(AliHLTTPCTrackletData*)iter->fPtr;
231             HLTDebug("reading block %d (slice %d): %d tracklets", ndx, minslice, inPtr->fTrackletCnt);
232             if ((iResult=tracks.FillTracksChecked(inPtr->fTracklets, inPtr->fTrackletCnt, iter->fSize, minslice, 0/*don't rotate*/))>=0) {
233               if ((iResult=Tracks2ESD(&tracks, pESD))>=0) {
234                 iAddedDataBlocks++;
235               }
236             }
237           } else {
238             HLTError("invalid sector number");
239             iResult=-EBADF;
240           }
241         }
242       }
243       if (iAddedDataBlocks>0 && pTree) {
244         pTree->Fill();
245       }
246
247   } else {
248     iResult=-EINVAL;
249   }
250   if (iResult>=0) iResult=iAddedDataBlocks;
251   return iResult;
252 }
253
254 int AliHLTTPCEsdWriterComponent::Tracks2ESD(AliHLTTPCTrackArray* pTracks, AliESDEvent* pESD)
255 {
256   // see header file for class documentation
257   int iResult=0;
258   if (pTracks && pESD) {    
259  
260     for (int i=0; i<pTracks->GetNTracks() && iResult>=0; i++) {
261       AliHLTTPCTrack* pTrack=(*pTracks)[i];
262       if (pTrack) {
263         
264         if( pTrack->Convert2AliKalmanTrack() ){   
265           HLTError("conversion to AliKalmanTrack failed for track %d of %d", i, pTracks->GetNTracks()); 
266           continue;
267         }
268
269         Float_t points[4] = {pTrack->GetFirstPointX(), pTrack->GetFirstPointY(), pTrack->GetLastPointX(), pTrack->GetLastPointY() };
270
271         if(pTrack->GetSector() == -1){ // Set first and last points for global tracks
272           Double_t s = TMath::Sin( pTrack->GetAlpha() );
273           Double_t c = TMath::Cos( pTrack->GetAlpha() );
274           points[0] =  pTrack->GetFirstPointX()*c + pTrack->GetFirstPointY()*s;
275           points[1] = -pTrack->GetFirstPointX()*s + pTrack->GetFirstPointY()*c;   
276           points[2] =  pTrack->GetLastPointX() *c + pTrack->GetLastPointY() *s;
277           points[3] = -pTrack->GetLastPointX() *s + pTrack->GetLastPointY() *c;   
278         }
279
280         Int_t mcLabel = -1;
281
282         if( fDoMCLabels ){
283             
284           // get MC label for the track
285           
286           vector<int> labels;
287           
288           UInt_t *hits = pTrack->GetHitNumbers();
289           Int_t nHits = pTrack->GetNHits();
290           for( Int_t ih=0; ih<nHits; ih++){
291             UInt_t id = hits[ih];
292             int iSlice = id>>25;
293             int iPatch = (id>>22)&0x7; 
294             int iCluster = id&0x3fffff;
295             if( iSlice<0 || iSlice>36 || iPatch<0 || iPatch>5 ){
296               HLTError("Corrupted TPC cluster Id: slice %d, patch %d, cluster %d",
297                        iSlice, iPatch,iCluster );
298               continue;
299             }
300             AliHLTTPCClusterFinder::ClusterMCInfo *patchLabels = fClusterLabels[iSlice*6 + iPatch];
301             if( !patchLabels ) continue;
302             if( iCluster >= fNClusterLabels[iSlice*6 + iPatch] ){
303               HLTError("TPC slice %d, patch %d: ClusterID==%d >= N MC labels==%d ",
304                        iSlice, iPatch,iCluster, fNClusterLabels[iSlice*6 + iPatch] );
305               continue;
306             }
307             AliHLTTPCClusterFinder::ClusterMCInfo &lab = patchLabels[iCluster];     
308             if ( lab.fClusterID[0].fMCID >= 0 ) labels.push_back( lab.fClusterID[0].fMCID );
309             if ( lab.fClusterID[1].fMCID >= 0 ) labels.push_back( lab.fClusterID[1].fMCID );
310             if ( lab.fClusterID[2].fMCID >= 0 ) labels.push_back( lab.fClusterID[2].fMCID );
311           }
312           
313           std::sort( labels.begin(), labels.end() );
314           
315           labels.push_back( -1 ); // put -1 to the end
316           
317           int labelMax = -1, labelCur = -1, nLabelsMax = 0, nLabelsCurr = 0;
318           for ( unsigned int iLab = 0; iLab < labels.size(); iLab++ ) {
319             if ( labels[iLab] != labelCur ) {         
320               if ( labelCur >= 0 && nLabelsMax< nLabelsCurr ) {
321                 nLabelsMax = nLabelsCurr;
322                 labelMax = labelCur;
323               }
324               labelCur = labels[iLab];
325               nLabelsCurr = 0;
326             }
327             nLabelsCurr++;
328           }
329           
330           if( labelMax>=0 && nLabelsMax < 0.9 * nHits ) labelMax = -labelMax;
331
332           mcLabel = labelMax;
333         }
334         
335         pTrack->SetLabel( mcLabel );
336         
337         AliESDtrack iotrack;
338         iotrack.UpdateTrackParams(pTrack,AliESDtrack::kTPCin);
339         iotrack.SetTPCPoints(points);
340
341         pESD->AddTrack(&iotrack);
342         
343       } else {
344         HLTError("internal mismatch in array");
345         iResult=-EFAULT;
346       }
347     }
348     
349   } else {
350     iResult=-EINVAL;
351   }
352   return iResult;
353 }
354
355 int AliHLTTPCEsdWriterComponent::Configure(const char* arguments)
356 {
357   // see header file for class documentation
358   int iResult=0;
359   if (!arguments) return iResult;
360
361   TString allArgs=arguments;
362   TString argument;
363   int bMissingParam=0;
364
365   TObjArray* pTokens=allArgs.Tokenize(" ");
366   if (pTokens) {
367     for (int i=0; i<pTokens->GetEntries() && iResult>=0; i++) {
368       argument=((TObjString*)pTokens->At(i))->GetString();
369       if (argument.IsNull()) continue;
370       
371       if (argument.CompareTo("-solenoidBz")==0) {
372         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
373         HLTInfo("Magnetic Field set to: %s", ((TObjString*)pTokens->At(i))->GetString().Data());
374         fSolenoidBz=((TObjString*)pTokens->At(i))->GetString().Atof();
375         continue;
376       } else {
377         HLTError("unknown argument %s", argument.Data());
378         iResult=-EINVAL;
379         break;
380       }
381     }
382     delete pTokens;
383   }
384   if (bMissingParam) {
385     HLTError("missing parameter for argument %s", argument.Data());
386     iResult=-EINVAL;
387   }
388
389   return iResult;
390 }
391
392 int AliHLTTPCEsdWriterComponent::Reconfigure(const char* cdbEntry, const char* chainId)
393 {
394   // see header file for class documentation
395   int iResult=0;
396   const char* path=kAliHLTCDBSolenoidBz;
397   const char* defaultNotify="";
398   if (cdbEntry) {
399     path=cdbEntry;
400     defaultNotify=" (default)";
401   }
402   if (path) {
403     HLTInfo("reconfigure from entry %s%s, chain id %s", path, defaultNotify,(chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
404     AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
405     if (pEntry) {
406       TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
407       if (pString) {
408         HLTInfo("received configuration object string: \'%s\'", pString->GetString().Data());
409         iResult=Configure(pString->GetString().Data());
410       } else {
411         HLTError("configuration object \"%s\" has wrong type, required TObjString", path);
412       }
413     } else {
414       HLTError("can not fetch object \"%s\" from CDB", path);
415     }
416   }
417   
418   return iResult;
419 }
420
421 AliHLTTPCEsdWriterComponent::AliConverter::AliConverter()
422   :
423   fESD(NULL),
424   fBase(new AliHLTTPCEsdWriterComponent),
425   fWriteTree(0)
426 {
427   // see header file for class documentation
428   // or
429   // refer to README to build package
430   // or
431   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
432 }
433
434 AliHLTTPCEsdWriterComponent::AliConverter::~AliConverter()
435 {
436   // see header file for class documentation
437   if (fBase) delete fBase;
438   fBase=NULL;
439
440   if (fESD) delete fESD;
441   fESD=NULL;
442 }
443
444 void AliHLTTPCEsdWriterComponent::AliConverter::GetInputDataTypes(AliHLTComponentDataTypeList& list)
445 {
446   // see header file for class documentation
447   list.push_back(AliHLTTPCDefinitions::fgkTrackSegmentsDataType);
448   list.push_back(AliHLTTPCDefinitions::fgkTracksDataType);
449   list.push_back(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo);
450 }
451
452 AliHLTComponentDataType AliHLTTPCEsdWriterComponent::AliConverter::GetOutputDataType()
453 {
454   // see header file for class documentation
455   return kAliHLTDataTypeESDTree;
456 }
457
458 void AliHLTTPCEsdWriterComponent::AliConverter::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
459 {
460   // see header file for class documentation
461   constBase=2000000;
462   inputMultiplier=10.0;
463 }
464
465 int AliHLTTPCEsdWriterComponent::AliConverter::DoInit(int argc, const char** argv)
466 {
467   // see header file for class documentation
468   int iResult=0;
469   TString argument="";
470   int bMissingParam=0;
471   for (int i=0; i<argc && iResult>=0; i++) {
472     argument=argv[i];
473     if (argument.IsNull()) continue;
474
475     // -notree
476     if (argument.CompareTo("-notree")==0) {
477       fWriteTree=0;
478
479       // -tree
480     } else if (argument.CompareTo("-tree")==0) {
481       fWriteTree=1;
482
483       // -solenoidBz
484     } else if (argument.CompareTo("-solenoidBz")==0) {
485       TString tmp="-solenoidBz ";
486       tmp+=argv[++i];
487       fBase->Configure(tmp.Data());
488     } else {
489       HLTError("unknown argument %s", argument.Data());
490       break;
491     }
492   }
493   if (bMissingParam) {
494     HLTError("missing parameter for argument %s", argument.Data());
495     iResult=-EINVAL;
496   }
497
498   if (iResult>=0) {
499     iResult=fBase->Reconfigure(NULL, NULL);
500   }
501
502   return iResult;
503 }
504
505 int AliHLTTPCEsdWriterComponent::AliConverter::DoDeinit()
506 {
507   // see header file for class documentation
508   return 0;
509 }
510
511 int AliHLTTPCEsdWriterComponent::AliConverter::DoEvent(const AliHLTComponentEventData& evtData, 
512                                                        const AliHLTComponentBlockData* blocks, 
513                                                        AliHLTComponentTriggerData& /*trigData*/,
514                                                        AliHLTUInt8_t* /*outputPtr*/, 
515                                                        AliHLTUInt32_t& size,
516                                                        AliHLTComponentBlockDataList& /*outputBlocks*/ )
517 {
518   // see header file for class documentation
519   int iResult=0;
520   // no direct writing to the output buffer
521   size=0;
522
523   assert(fBase);
524   if (!fESD) {
525     fESD = new AliESDEvent;
526     if (fESD) {
527       fESD->CreateStdContent();
528     } else {
529       iResult=-ENOMEM;
530     }
531   }
532
533   AliESDEvent* pESD = fESD;
534
535   if (pESD && fBase) {
536   
537     TTree* pTree = NULL;
538     // TODO: Matthias 06.12.2007
539     // Tried to write the ESD directly instead to a tree, but this did not work
540     // out. Information in the ESD is different, needs investigation.
541     
542     if (fWriteTree)
543       pTree = new TTree("esdTree", "Tree with HLT ESD objects");
544  
545     if (pTree) {
546       pTree->SetDirectory(0);
547     }
548
549     if ((iResult=fBase->ProcessBlocks(pTree, pESD, blocks, (int)evtData.fBlockCnt))>0) {
550       // TODO: set the specification correctly
551       if (pTree) {
552         // the esd structure is written to the user info and is
553         // needed in te ReadFromTree method to read all objects correctly
554         pTree->GetUserInfo()->Add(pESD);
555         pESD->WriteToTree(pTree);
556         iResult=PushBack(pTree, kAliHLTDataTypeESDTree|kAliHLTDataOriginTPC, 0);
557       } else {
558         iResult=PushBack(pESD, kAliHLTDataTypeESDObject|kAliHLTDataOriginTPC, 0);
559       }
560     }
561     if (pTree) {
562       // clear user info list to prevent objects from being deleted
563       pTree->GetUserInfo()->Clear();
564       delete pTree;
565     }
566   }
567   return iResult;
568 }
569