4c3adbafb11749696794c66a072b9376a11c312b
[u/mrichter/AliRoot.git] / HLT / TPCLib / offline / AliHLTTPCOfflineTrackerComponent.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 //*                                                                        *
9 //* Permission to use, copy, modify and distribute this software and its   *
10 //* documentation strictly for non-commercial purposes is hereby granted   *
11 //* without fee, provided that the above copyright notice appears in all   *
12 //* copies and that both the copyright notice and this permission notice   *
13 //* appear in the supporting documentation. The authors make no claims     *
14 //* about the suitability of this software for any purpose. It is          *
15 //* provided "as is" without express or implied warranty.                  *
16 //**************************************************************************
17
18 /** @file   AliHLTTPCOfflineTrackerComponent.cxx
19     @author Jacek Otwinowski & Matthias Richter
20     @date   
21     @brief  Wrapper component to the TPC offline tracker
22 */
23
24 #include "AliHLTTPCOfflineTrackerComponent.h"
25 #include "TString.h"
26 #include "TClonesArray.h"
27 #include "TObjArray.h"
28 #include "TObjString.h"
29 #include "AliVParticle.h"
30 #include "AliCDBManager.h"
31 #include "AliCDBEntry.h"
32 #include "AliGeomManager.h"
33 #include "AliMagFMaps.h"
34 #include "AliTPCReconstructor.h"
35 #include "AliTPCParam.h"
36 #include "AliTPCRecoParam.h"
37 #include "AliTPCParamSR.h"
38 #include "AliTPCtrackerMI.h"
39 #include "AliTPCClustersRow.h"
40 #include "AliTPCseed.h"
41 #include "AliESDEvent.h"
42 #include "AliESDfriend.h"
43 #include "AliHLTTPCDefinitions.h"
44
45 /** ROOT macro for the implementation of ROOT specific class methods */
46 ClassImp(AliHLTTPCOfflineTrackerComponent)
47
48 AliHLTTPCOfflineTrackerComponent::AliHLTTPCOfflineTrackerComponent() : AliHLTProcessor(),
49 fGeometryFileName(""),
50 fTPCGeomParam(0),
51 fTracker(0),
52 fESD(0),
53 fESDfriend(0)
54 {
55   // Default constructor
56   fGeometryFileName = getenv("ALICE_ROOT");
57   fGeometryFileName += "/HLT/TPCLib/offline/geometry.root";
58 }
59
60 AliHLTTPCOfflineTrackerComponent::~AliHLTTPCOfflineTrackerComponent()
61 {
62   // see header file for class documentation
63 }
64
65 const char* AliHLTTPCOfflineTrackerComponent::GetComponentID()
66 {
67   // see header file for class documentation
68   return "TPCOfflineTracker";
69 }
70
71 void AliHLTTPCOfflineTrackerComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
72 {
73   // get input data type
74   list.push_back(kAliHLTDataTypeTObjArray|kAliHLTDataOriginTPC/*AliHLTTPCDefinitions::fgkOfflineClustersDataType*/);
75 }
76
77 AliHLTComponentDataType AliHLTTPCOfflineTrackerComponent::GetOutputDataType()
78 {
79   // create output data type
80   return kAliHLTDataTypeESDObject|kAliHLTDataOriginTPC/*AliHLTTPCDefinitions::fgkOfflineTrackSegmentsDataType*/;
81 }
82
83 void AliHLTTPCOfflineTrackerComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
84 {
85   // get output data size
86   constBase = 2000000;
87   inputMultiplier = 1;
88 }
89
90 AliHLTComponent* AliHLTTPCOfflineTrackerComponent::Spawn()
91 {
92   // create instance of the component
93   return new AliHLTTPCOfflineTrackerComponent;
94 }
95
96 int AliHLTTPCOfflineTrackerComponent::DoInit( int argc, const char** argv )
97 {
98   // init configuration 
99   //
100   int iResult=0;
101 #ifdef HAVE_NOT_TPCOFFLINE_REC
102   HLTFatal("AliRoot version > v4-13-Release required");
103   return -ENOSYS;
104 #endif
105
106   TString argument="";
107   TString configuration=""; 
108   int bMissingParam=0;
109
110   // loop over input parameters
111   for (int i=0; i<argc && iResult>=0; i++) {
112     argument=argv[i];
113     if (argument.IsNull()) continue;
114
115     if (argument.CompareTo("-geometry")==0) {
116       if ((bMissingParam=(++i>=argc))) break;
117
118       HLTInfo("got \'-geometry\' argument: %s", argv[i]);
119       fGeometryFileName = argv[i];
120       HLTInfo("Geometry file is: %s", fGeometryFileName.c_str());
121
122       // the remaining arguments are treated as configuration
123     } else {
124       if (!configuration.IsNull()) configuration+=" ";
125       configuration+=argument;
126     }
127   } // end loop
128
129   if (bMissingParam) {
130     HLTError("missing parameter for argument %s", argument.Data());
131     iResult=-EINVAL;
132   }
133
134   if (iResult>=0 && !configuration.IsNull()) {
135     iResult=Configure(configuration.Data());
136   } else {
137     iResult=Reconfigure(NULL, NULL);
138   }
139
140   //
141   // initialisation
142   //
143    
144   // Load geometry
145   HLTInfo("Geometry file %s",fGeometryFileName.c_str());
146   AliGeomManager::LoadGeometry(fGeometryFileName.c_str());
147   if((AliGeomManager::GetGeometry()) == 0) {
148     HLTError("Cannot load geometry from file %s",fGeometryFileName.c_str());
149     iResult=-EINVAL;
150   }
151
152   // TPC reconstruction parameters
153   //AliTPCRecoParam * tpcRecoParam = AliTPCRecoParam::GetLowFluxParam();
154   AliTPCRecoParam * tpcRecoParam = AliTPCRecoParam::GetHLTParam();
155   if(tpcRecoParam) {
156     AliTPCReconstructor::SetRecoParam(tpcRecoParam);
157   }
158  
159   // TPC geometry parameters
160   fTPCGeomParam = new AliTPCParamSR;
161   if (fTPCGeomParam) {
162     fTPCGeomParam->ReadGeoMatrices();
163   }
164
165   // Init tracker
166   fTracker = new AliTPCtrackerMI(fTPCGeomParam);
167
168   // AliESDEvent event needed by AliTPCtrackerMI
169   // output of the component
170   fESD = new AliESDEvent();
171   if (fESD) {
172     fESD->CreateStdContent();
173
174     // add ESD friend
175     fESDfriend = new AliESDfriend();
176     if(fESDfriend) fESD->AddObject(fESDfriend);
177   }
178
179   if (!fTracker || !fESD || !fTPCGeomParam) {
180     HLTError("failed creating internal objects");
181     iResult=-ENOMEM;
182   }
183
184   if (iResult>=0) {
185     // read the default CDB entries
186     iResult=Reconfigure(NULL, NULL);
187   }
188
189   return iResult;
190 }
191
192 int AliHLTTPCOfflineTrackerComponent::DoDeinit()
193 {
194   // deinit configuration
195
196   if(fTPCGeomParam) delete fTPCGeomParam; fTPCGeomParam = 0; 
197   if(fTracker) delete fTracker; fTracker = 0; 
198   if(fESD) delete fESD; fESD = 0;
199   //Note: fESD is owner of fESDfriends
200
201   return 0;
202 }
203
204 int AliHLTTPCOfflineTrackerComponent::DoEvent( const AliHLTComponentEventData& /*evtData*/, AliHLTComponentTriggerData& /*trigData*/)
205 {
206   // tracker function
207   HLTInfo("DoEvent processing data");
208
209   int iResult=0;
210   TClonesArray *clusterArray=0;
211   TObjArray *seedArray=0;
212   int slice, patch;
213
214   const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeTObjArray|kAliHLTDataOriginTPC); 
215   if(!pBlock) {
216      HLTError("Cannot get first data block 0x%08x ",pBlock);
217      iResult=-ENOMEM; return iResult;
218   }
219   int minSlice=AliHLTTPCDefinitions::GetMinSliceNr(pBlock->fSpecification);
220   int maxSlice=AliHLTTPCDefinitions::GetMaxSliceNr(pBlock->fSpecification);
221   int minPatch=AliHLTTPCDefinitions::GetMinPatchNr(pBlock->fSpecification);
222   int maxPatch=AliHLTTPCDefinitions::GetMaxPatchNr(pBlock->fSpecification);  
223
224   if (fTracker && fESD) {
225       // loop over input data blocks: TClonesArrays of clusters
226       for (TObject *pObj = (TObject *)GetFirstInputObject(kAliHLTDataTypeTObjArray|kAliHLTDataOriginTPC/*AliHLTTPCDefinitions::fgkOfflineClustersDataType*/,"TClonesArray",0);
227          pObj !=0 && iResult>=0;
228          pObj = (TObject *)GetNextInputObject(0)) {
229       clusterArray = dynamic_cast<TClonesArray*>(pObj);
230       if (!clusterArray) continue;
231
232       HLTInfo("load %d clusters from block %s 0x%08x", clusterArray->GetEntries(), DataType2Text(GetDataType(pObj)).c_str(), GetSpecification(pObj));
233       slice=AliHLTTPCDefinitions::GetMinSliceNr(GetSpecification(pObj));
234       patch=AliHLTTPCDefinitions::GetMinPatchNr(GetSpecification(pObj));
235
236       if(slice < minSlice) minSlice=slice;
237       if(slice > maxSlice) maxSlice=slice;
238       if(patch < minPatch) minPatch=patch;
239       if(patch > maxPatch) maxPatch=patch;
240 #ifndef HAVE_NOT_TPCOFFLINE_REC
241       fTracker->LoadClusters(clusterArray);
242 #endif //HAVE_NOT_TPCOFFLINE_REC
243  
244     clusterArray->Delete();
245     }// end loop over input objects
246
247 #ifndef HAVE_NOT_TPCOFFLINE_REC
248     // Load outer sectors
249       fTracker->LoadOuterSectors();
250     // Load inner sectors
251       fTracker->LoadInnerSectors();
252 #endif
253
254     // set magnetic field for the ESD, assumes correct initialization of
255     // the field map
256     fESD->SetMagneticField(AliTracker::GetBz());
257   
258     // run tracker
259     fTracker->Clusters2Tracks(fESD);
260
261     // add TPC seed to the AliESDtrack
262     seedArray = fTracker->GetSeeds();
263     if(seedArray) {
264        Int_t nseed = seedArray->GetEntriesFast();
265        HLTInfo("Number TPC seeds %d",nseed);
266
267        for(Int_t i=0; i<nseed; ++i) {
268           AliTPCseed *seed = (AliTPCseed*)seedArray->UncheckedAt(i);
269           if(!seed) continue; 
270
271           //HLTInfo("TPC seed:  sec %d, row %d",seed->GetSector(), seed->GetRow());
272
273           AliESDtrack *esdtrack=fESD->GetTrack(i);
274           if(esdtrack) esdtrack->AddCalibObject((TObject*)seed);
275           else 
276              HLTInfo("Cannot add TPC seed to AliESDtrack %d", i);
277        }
278     seedArray->Clear();
279     }
280
281     // reset ESDs friends (no Reset function!)
282     fESDfriend->~AliESDfriend();
283     new (fESDfriend) AliESDfriend(); // Reset ...
284
285     // add ESDfriend to AliESDEvent
286     fESD->GetESDfriend(fESDfriend);
287
288     // unload clusters
289     fTracker->UnloadClusters();
290
291     Int_t nTracks = fESD->GetNumberOfTracks();
292     HLTInfo("Number of tracks %d", nTracks);
293
294     // calculate specification from the specification of input data blocks
295     AliHLTUInt32_t iSpecification = AliHLTTPCDefinitions::EncodeDataSpecification( minSlice, maxSlice, minPatch, maxPatch );
296     HLTInfo("minSlice %d, maxSlice %d, minPatch %d, maxPatch %d", minSlice, maxSlice, minPatch, maxPatch);
297
298     // send data
299     PushBack(fESD, kAliHLTDataTypeESDObject|kAliHLTDataOriginTPC, iSpecification);
300
301     // reset ESDs and ESDs friends
302     fESD->Reset();
303
304   } else {
305     HLTError("component not initialized");
306     iResult=-ENOMEM;
307   }
308
309   return iResult;
310 }
311
312 int AliHLTTPCOfflineTrackerComponent::Configure(const char* arguments)
313 {
314   // see header file for class documentation
315   int iResult=0;
316   if (!arguments) return iResult;
317
318   TString allArgs=arguments;
319   TString argument;
320   int bMissingParam=0;
321
322   TObjArray* pTokens=allArgs.Tokenize(" ");
323   if (pTokens) {
324     for (int i=0; i<pTokens->GetEntries() && iResult>=0; i++) {
325       argument=((TObjString*)pTokens->At(i))->GetString();
326       if (argument.IsNull()) continue;
327
328       if (argument.CompareTo("-solenoidBz")==0) {
329         if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
330         // TODO: check if there is common functionality in the AliMagF* classes
331         float SolenoidBz=((TObjString*)pTokens->At(i))->GetString().Atof();
332         if (SolenoidBz<kAlmost0Field) SolenoidBz=kAlmost0Field;
333         float factor=1.;
334         int map=AliMagFMaps::k2kG;
335         if (SolenoidBz<3.) {
336           map=AliMagFMaps::k2kG;
337           factor=SolenoidBz/2;
338         } else if (SolenoidBz>=3. && SolenoidBz<4.5) {
339           map=AliMagFMaps::k4kG;
340           factor=SolenoidBz/4;
341         } else {
342           map=AliMagFMaps::k5kG;
343           factor=SolenoidBz/5;
344         }
345         // the magnetic field map is not supposed to change
346         // field initialization should be done once in the beginning
347         // TODO: does the factor need adjustment?
348         const AliMagF* currentMap=AliTracker::GetFieldMap();
349         if (!currentMap) {
350           AliMagFMaps* field = new AliMagFMaps("Maps","Maps", 2, 1., 10., map);
351           AliTracker::SetFieldMap(field,kTRUE);
352           HLTInfo("Solenoid Field set to: %f map %d", SolenoidBz, map);
353         } else if (currentMap->Map()!=map) {
354           HLTWarning("omitting request to override field map %s with %s", currentMap->Map(), map);
355         }
356         continue;
357       } else {
358         HLTError("unknown argument %s", argument.Data());
359         iResult=-EINVAL;
360         break;
361       }
362     }
363     delete pTokens;
364   }
365   if (bMissingParam) {
366     HLTError("missing parameter for argument %s", argument.Data());
367     iResult=-EINVAL;
368   }
369   return iResult;
370 }
371
372 int AliHLTTPCOfflineTrackerComponent::Reconfigure(const char* cdbEntry, const char* chainId)
373 {
374   // see header file for class documentation
375   int iResult=0;
376   const char* path=kAliHLTCDBSolenoidBz;
377   const char* defaultNotify="";
378   if (cdbEntry) {
379     path=cdbEntry;
380     defaultNotify=" (default)";
381   }
382   if (path) {
383     if (chainId) {} // just to get rid of warning, can not comment argument due to debug message
384     HLTDebug("reconfigure from entry %s%s, chain id %s", path, defaultNotify,(chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
385     AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
386     if (pEntry) {
387       TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
388       if (pString) {
389         HLTDebug("received configuration object string: \'%s\'", pString->GetString().Data());
390         iResult=Configure(pString->GetString().Data());
391       } else {
392         HLTError("configuration object \"%s\" has wrong type, required TObjString", path);
393       }
394     } else {
395       HLTError("can not fetch object \"%s\" from CDB", path);
396     }
397   }
398   
399   return iResult;
400 }