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