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