Using common HLT track data format for TRD tracks (Theodor)
[u/mrichter/AliRoot.git] / HLT / TRD / AliHLTTRDTrackerV1Component.cxx
CommitLineData
0e339ac7 1// $Id: AliHLTTRDTrackerV1Component.cxx 23618 2008-01-29 13:07:38Z hristov $
2
3/**************************************************************************
4 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5 * *
6 * Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
7 * Timm Steinbeck <timm@kip.uni-heidelberg.de> *
8 * for The ALICE Off-line 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 AliHLTTRDTrackerV1Component.cxx
20 @author Timm Steinbeck, Matthias Richter
21 @date
22 @brief A TRDTrackerV1 processing component for the HLT. */
23
24#if __GNUC__ >= 3
25using namespace std;
26#endif
27
28#include "AliHLTTRDTrackerV1Component.h"
29#include "AliHLTTRDDefinitions.h"
d679dd6c 30#include "AliHLTTRDCluster.h"
31#include "AliHLTTRDTrack.h"
dc2e6604 32#include "AliHLTTRDUtils.h"
0e339ac7 33
34#include "TFile.h"
35#include "TChain.h"
36
886e8d3d 37#include "AliGeomManager.h"
0e339ac7 38#include "AliCDBManager.h"
39#include "AliESDEvent.h"
f7a1cc68 40#include "AliMagF.h"
0e339ac7 41#include "AliESDfriend.h"
42
9aea5deb 43#include "AliTRDcalibDB.h"
0e339ac7 44#include "AliTRDReconstructor.h"
45#include "AliTRDtrackerV1.h"
0e339ac7 46#include "AliTRDrecoParam.h"
47
48#include <cstdlib>
49#include <cerrno>
50#include <string>
51
d679dd6c 52#ifdef HAVE_VALGRIND_CALLGRIND_H
53#include <valgrind/callgrind.h>
54#else
e3e5ac39 55#define CALLGRIND_START_INSTRUMENTATION do { } while (0)
56#define CALLGRIND_STOP_INSTRUMENTATION do { } while (0)
d679dd6c 57#endif
0e339ac7 58
18ada816 59ClassImp(AliHLTTRDTrackerV1Component)
0e339ac7 60
d679dd6c 61AliHLTTRDTrackerV1Component::AliHLTTRDTrackerV1Component():
62 AliHLTProcessor(),
63 fOutputPercentage(100), // By default we copy to the output exactly what we got as input
162637e4 64 fStrorageDBpath("local://$ALICE_ROOT/OCDB"),
d679dd6c 65 fCDB(NULL),
d679dd6c 66 fGeometryFileName(""),
d679dd6c 67 fTracker(NULL),
68 fRecoParam(NULL),
69 fReconstructor(NULL)
0e339ac7 70{
71 // Default constructor
72
73 fGeometryFileName = getenv("ALICE_ROOT");
74 fGeometryFileName += "/HLT/TRD/geometry.root";
75}
76
77AliHLTTRDTrackerV1Component::~AliHLTTRDTrackerV1Component()
78{
9aea5deb 79 // Destructor
0e339ac7 80}
81
82const char* AliHLTTRDTrackerV1Component::GetComponentID()
83{
84 // Return the component ID const char *
85 return "TRDTrackerV1"; // The ID of this component
86}
87
88void AliHLTTRDTrackerV1Component::GetInputDataTypes( vector<AliHLTComponent_DataType>& list)
89{
90 // Get the list of input data
91 list.clear(); // We do not have any requirements for our input data type(s).
92 list.push_back( AliHLTTRDDefinitions::fgkClusterDataType );
93}
94
95AliHLTComponent_DataType AliHLTTRDTrackerV1Component::GetOutputDataType()
96{
97 // Get the output data type
18ada816 98 //return AliHLTTRDDefinitions::fgkClusterDataType;
99 return kAliHLTDataTypeTrack | kAliHLTDataOriginTRD;
0e339ac7 100}
101
102void AliHLTTRDTrackerV1Component::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
103{
104 // Get the output data size
105 constBase = 0;
106 inputMultiplier = ((double)fOutputPercentage)/100.0;
107}
108
109// Spawn function, return new instance of this class
110AliHLTComponent* AliHLTTRDTrackerV1Component::Spawn()
111{
0e339ac7 112 return new AliHLTTRDTrackerV1Component;
113};
114
d679dd6c 115
0e339ac7 116int AliHLTTRDTrackerV1Component::DoInit( int argc, const char** argv )
117{
118 // perform initialization. We check whether our relative output size is specified in the arguments.
119 fOutputPercentage = 100;
120 int i = 0;
121 char* cpErr;
9aea5deb 122
0e339ac7 123
124 Int_t iRecoParamType = -1; // default will be the low flux
125 Int_t iNtimeBins = -1; // number of time bins for the tracker to use
126 Int_t iMagneticField = -1; // magnetic field: 0==OFF and 1==ON
18ada816 127 Int_t iPIDmethod = 1; // 0=LikelyHood(LH) 1=NeuronalNetwork(NN) 2=TruncatedMean(TM)
0134491a 128 Bool_t bHLTMode = kTRUE, bWriteClusters = kFALSE;
9aea5deb 129
0e339ac7 130 while ( i < argc )
131 {
886e8d3d 132 HLTDebug("argv[%d] == %s", i, argv[i] );
0e339ac7 133 if ( !strcmp( argv[i], "output_percentage" ) )
134 {
135 if ( i+1>=argc )
136 {
886e8d3d 137 HLTError("Missing output_percentage parameter");
0e339ac7 138 return ENOTSUP;
139 }
886e8d3d 140 HLTDebug("argv[%d+1] == %s", i, argv[i+1] );
0e339ac7 141 fOutputPercentage = strtoul( argv[i+1], &cpErr, 0 );
142 if ( *cpErr )
143 {
886e8d3d 144 HLTError("Cannot convert output_percentage parameter '%s'", argv[i+1] );
0e339ac7 145 return EINVAL;
146 }
886e8d3d 147 HLTInfo("Output percentage set to %lu %%", fOutputPercentage );
0e339ac7 148 i += 2;
0e339ac7 149 }
9aea5deb 150 else if ( !strcmp( argv[i], "-NTimeBins" ) )
0e339ac7 151 {
152 if ( i+1>=argc )
153 {
154 HLTError("Missing -NTimeBins parameter");
155 return ENOTSUP;
156 }
157 HLTDebug("Arguments", "argv[%d+1] == %s", i, argv[i+1] );
158 iNtimeBins = strtoul( argv[i+1], &cpErr, 0 );
159 if ( *cpErr )
160 {
161 HLTError("Wrong Argument. Cannot convert -NTimeBins parameter '%s'", argv[i+1] );
162 return EINVAL;
163 }
18ada816 164 i += 2;
0e339ac7 165 }
9aea5deb 166 else if ( strcmp( argv[i], "-cdb" ) == 0)
0e339ac7 167 {
168 if ( i+1 >= argc )
169 {
886e8d3d 170 HLTError( "Missing -cdb argument");
0e339ac7 171 return ENOTSUP;
172 }
173 fStrorageDBpath = argv[i+1];
886e8d3d 174 HLTInfo("DB storage is %s", fStrorageDBpath.c_str() );
0e339ac7 175 i += 2;
18ada816 176 }
9aea5deb 177 else if ( strcmp( argv[i], "-geometry" ) == 0)
0e339ac7 178 {
179 if ( i+1 >= argc )
180 {
886e8d3d 181 HLTError("Missing -geometry argument");
0e339ac7 182 return ENOTSUP;
183 }
184 fGeometryFileName = argv[i+1];
886e8d3d 185 HLTInfo("GeomFile storage is %s",
9aea5deb 186 fGeometryFileName.c_str() );
0e339ac7 187 i += 2;
18ada816 188 }
0e339ac7 189 // the flux parametrizations
9aea5deb 190 else if ( strcmp( argv[i], "-lowflux" ) == 0)
0e339ac7 191 {
192 iRecoParamType = 0;
193 HLTDebug("Low flux reco selected.");
194 i++;
18ada816 195 }
9aea5deb 196 else if ( strcmp( argv[i], "-highflux" ) == 0)
0e339ac7 197 {
198 iRecoParamType = 1;
199 HLTDebug("Low flux reco selected.");
200 i++;
18ada816 201 }
9aea5deb 202 else if ( strcmp( argv[i], "-cosmics" ) == 0)
886e8d3d 203 {
204 iRecoParamType = 2;
205 HLTDebug("Cosmic test reco selected.");
206 i++;
18ada816 207 }
9aea5deb 208 else if ( strcmp( argv[i], "-magnetic_field_ON" ) == 0)
0e339ac7 209 {
210 iMagneticField = 1;
211 i++;
0e339ac7 212 }
9aea5deb 213 else if ( strcmp( argv[i], "-magnetic_field_OFF" ) == 0)
0e339ac7 214 {
215 iMagneticField = 0;
216 i++;
0e339ac7 217 }
0134491a 218 else if ( strcmp( argv[i], "-offlineMode" ) == 0)
219 {
220 bHLTMode=kFALSE;
221 HLTDebug("Using standard offline tracking.");
222 i++;
223 }
18ada816 224 else if ( strcmp( argv[i], "-PIDmethod" ) == 0)
225 {
226 if ( i+1 >= argc )
227 {
228 HLTError("Missing -PIDmethod argument");
229 return ENOTSUP;
230 }
231 if( strcmp(argv[i], "LH") )
232 iPIDmethod=0;
233 else if( strcmp(argv[i], "NN") )
234 iPIDmethod=1;
235 else if( strcmp(argv[i], "TM") )
236 iPIDmethod=2;
237 else {
238 HLTError("Unknown -PIDmethod argument");
239 return ENOTSUP;
240 }
241 i += 2;
242 }
243
9aea5deb 244 else {
245 HLTError("Unknown option '%s'", argv[i] );
246 return EINVAL;
247 }
248
0e339ac7 249 }
250
251 // THE "REAL" INIT COMES HERE
252 // offline condition data base
253 fCDB = AliCDBManager::Instance();
254 if (!fCDB)
255 {
886e8d3d 256 HLTError("Could not get CDB instance", "fCDB 0x%x", fCDB);
0e339ac7 257 return -1;
258 }
259 else
260 {
261 fCDB->SetRun(0); // THIS HAS TO BE RETRIEVED !!!
262 fCDB->SetDefaultStorage(fStrorageDBpath.c_str());
886e8d3d 263 HLTDebug("CDB instance", "fCDB 0x%x", fCDB);
0e339ac7 264 }
265
266 // check if the N of time bins make sense
267 if (iNtimeBins <= 0)
268 {
269 HLTError("Sorry. Tracker needs number of time bins. At the moment you have to provide it with -NTimeBins <value>. The simulation always had 24 and the real data 30. Take your pick. Make sure the information is correct. Ask offline to implement how to propagate this information into clusters/cluster tree.");
270 return -1;
271 }
272
273 if (iNtimeBins < 24 || iNtimeBins > 30)
274 {
275 HLTWarning("The number of time bins seems to be strange = %d. But okay. Let's try it...", iNtimeBins);
276 }
277
278 HLTDebug("The number of time bins = %d.", iNtimeBins);
279 AliTRDtrackerV1::SetNTimeBins(iNtimeBins);
280
281 // !!!! THIS IS IMPORTANT
282 // init alifield map - temporarly via parameter - should come from a DB or DCS ?
283 // !!!!
284 if (iMagneticField < 0)
285 {
286 iMagneticField = 0;
287 HLTWarning("No magnetic field switch stated. Use -magnetic_field_ON or -magnetic_field_OFF flag. Defaulting to OFF = NO MAGNETIC FIELD");
288 }
289
f7a1cc68 290 if (!TGeoGlobalMagField::Instance()->IsLocked()) {
291 if (iMagneticField == 0)
292 {
293 // magnetic field OFF
294 AliMagF* field = new AliMagF("Maps","Maps",2,0.,0., 10.,AliMagF::k5kGUniform);
295 TGeoGlobalMagField::Instance()->SetField(field);
296 HLTDebug("Magnetic field is OFF.");
297 }
298
299 if (iMagneticField == 1)
300 {
301 // magnetic field ON
302 AliMagF* field = new AliMagF("Maps","Maps",2,1.,1., 10.,AliMagF::k5kG);
303 TGeoGlobalMagField::Instance()->SetField(field);
304 HLTDebug("Magnetic field is ON.");
305 }
306 }
307 else {
308 HLTError("Magnetic field is already set and locked, cannot redefine it." );
309 }
0e339ac7 310
311 // reconstruction parameters
886e8d3d 312 if (iRecoParamType < 0 || iRecoParamType > 2)
0e339ac7 313 {
9aea5deb 314 HLTWarning("No reco param selected. Use -lowflux -highflux -cosmics flags. Defaulting to low flux.");
0e339ac7 315 iRecoParamType = 0;
316 }
317
318 if (iRecoParamType == 0)
319 {
320 fRecoParam = AliTRDrecoParam::GetLowFluxParam();
321 HLTDebug("Low flux params init.");
322 }
323
324 if (iRecoParamType == 1)
325 {
326 fRecoParam = AliTRDrecoParam::GetHighFluxParam();
327 HLTDebug("High flux params init.");
328 }
9aea5deb 329
886e8d3d 330 if (iRecoParamType == 2)
331 {
332 fRecoParam = AliTRDrecoParam::GetCosmicTestParam();
333 HLTDebug("Cosmic Test params init.");
334 }
335
0e339ac7 336 if (fRecoParam == 0)
337 {
338 HLTError("No reco params initialized. Sniffing big trouble!");
339 return -1;
340 }
341
0d66dbf5 342 fReconstructor = new AliTRDReconstructor();
d679dd6c 343 // fRecoParam->SetChi2Y(.1);
344 // fRecoParam->SetChi2Z(5.);
9aea5deb 345 fReconstructor->SetRecoParam(fRecoParam);
346 // write clusters [cw] = true
347 // track seeding (stand alone tracking) [sa] = true
348 // PID method in reconstruction (NN) [nn] = true
349 // write online tracklets [tw] = false
350 // drift gas [ar] = false
0134491a 351 // sl_tr_0 = StreamLevel_task_Level
352 // fReconstructor->SetOption("sa,!cw,hlt,sl_tr_0");
d679dd6c 353 TString recoOptions="sa,sl_tr_0";
0134491a 354
355 if (bWriteClusters)
356 {
357 recoOptions += ",cw";
358 }
359 else
360 {
361 recoOptions += ",!cw";
362 }
363 if (bHLTMode)
364 recoOptions += ",hlt";
18ada816 365
366 switch(iPIDmethod){
367 case 0: recoOptions += ",!nn"; break;
368 case 1: recoOptions += ",nn"; break;
369 case 2: recoOptions += ",!nn"; break;
370 }
0134491a 371
372 fReconstructor->SetOption(recoOptions.Data());
373 HLTDebug("Reconstructor options are: %s",recoOptions.Data());
886e8d3d 374
d679dd6c 375 if((AliGeomManager::GetGeometry()) == NULL){
376
377 if ( TFile::Open(fGeometryFileName.c_str())) {
9aea5deb 378 AliGeomManager::LoadGeometry(fGeometryFileName.c_str());
379 }
d679dd6c 380 else {
381 HLTError("Cannot load geometry from file %s",fGeometryFileName.c_str());
382 return EINVAL;
9aea5deb 383 }
d679dd6c 384 }
385 else
386 HLTInfo("Geometry Already Loaded");
0e339ac7 387
388 // create the tracker
9aea5deb 389 fTracker = new AliTRDtrackerV1();
390 fTracker->SetReconstructor(fReconstructor);
0e339ac7 391 HLTDebug("TRDTracker at 0x%x", fTracker);
392
393 if (fTracker == 0)
394 {
395 HLTError("Unable to create the tracker!");
0e339ac7 396 return -1;
397 }
398
0e339ac7 399 return 0;
400}
401
402int AliHLTTRDTrackerV1Component::DoDeinit()
403{
404 // Deinitialization of the component
0e339ac7 405
d679dd6c 406 fTracker->SetClustersOwner(kFALSE);
0e339ac7 407 delete fTracker;
886e8d3d 408 fTracker = 0x0;
9aea5deb 409
410 // We need to set clusters in Reconstructor to null to prevent from
411 // double deleting, since we delete TClonesArray by ourself in DoEvent.
412 fReconstructor->SetClusters(0x0);
0d66dbf5 413 delete fReconstructor;
414 fReconstructor = 0x0;
886e8d3d 415
9aea5deb 416 AliTRDcalibDB::Terminate();
417
0e339ac7 418 return 0;
419}
420
d679dd6c 421int AliHLTTRDTrackerV1Component::DoEvent( const AliHLTComponentEventData& evtData,
422 const AliHLTComponentBlockData* blocks,
423 AliHLTComponent_TriggerData& /*trigData*/,
424 AliHLTUInt8_t* outputPtr,
425 AliHLTUInt32_t& size,
426 vector<AliHLTComponent_BlockData>& outputBlocks )
0e339ac7 427{
428 // Process an event
dc2e6604 429
d679dd6c 430 HLTDebug("NofBlocks %lu", evtData.fBlockCnt );
9aea5deb 431
d679dd6c 432 AliHLTUInt32_t totalSize = 0, offset = 0;
0e339ac7 433 AliHLTUInt32_t dBlockSpecification = 0;
434
d679dd6c 435 vector<AliHLTComponent_DataType> expectedDataTypes;
436 GetInputDataTypes(expectedDataTypes);
18ada816 437 if (evtData.fEventID > 1)
e3e5ac39 438 CALLGRIND_START_INSTRUMENTATION;
d679dd6c 439 for ( unsigned long iBlock = 0; iBlock < evtData.fBlockCnt; iBlock++ )
0e339ac7 440 {
d679dd6c 441 const AliHLTComponentBlockData &block = blocks[iBlock];
d679dd6c 442 AliHLTComponentDataType inputDataType = block.fDataType;
443 Bool_t correctDataType = kFALSE;
18ada816 444
445 for(UInt_t i = 0; i < expectedDataTypes.size(); i++){
d679dd6c 446 if( expectedDataTypes.at(i) == inputDataType)
447 correctDataType = kTRUE;
18ada816 448 }
d679dd6c 449 if (!correctDataType)
450 {
451 HLTDebug( "Block # %i/%i; Event 0x%08LX (%Lu) Wrong received datatype: %s - Skipping",
452 iBlock, evtData.fBlockCnt-1,
453 evtData.fEventID, evtData.fEventID,
454 DataType2Text(inputDataType).c_str());
455 continue;
456 }
c702bc56 457 else {
18ada816 458 HLTDebug("We get the right data type: Block # %i/%i; Event 0x%08LX (%Lu) Received datatype: %s; Block Size: %i",
459 iBlock, evtData.fBlockCnt-1,
460 evtData.fEventID, evtData.fEventID,
461 DataType2Text(inputDataType).c_str(),
462 block.fSize);
c702bc56 463 }
d679dd6c 464
465
dc2e6604 466 TClonesArray* clusterArray = new TClonesArray("AliTRDcluster"); // would be nice to allocate memory for all clusters here.
467 AliHLTTRDUtils::ReadClusters(clusterArray, block.fPtr, block.fSize);
468 HLTDebug("TClonesArray of clusters: nbEntries = %i", clusterArray->GetEntriesFast());
469 fTracker->LoadClusters(clusterArray);
470
d679dd6c 471 // maybe it is not so smart to create it each event? clear is enough ?
472 AliESDEvent *esd = new AliESDEvent();
473 esd->CreateStdContent();
474 fTracker->Clusters2Tracks(esd);
475
d679dd6c 476 Int_t nTracks = esd->GetNumberOfTracks();
dc2e6604 477 HLTInfo("Number of tracks == %d ==", nTracks);
d679dd6c 478
18ada816 479 TClonesArray* trdTracks = 0x0;
480 //trdTracks = fTracker->GetListOfTracks();
481
482 if(nTracks>0){
483 HLTDebug("We have an output ESDEvent: 0x%x with %i tracks", esd, nTracks);
484 AliHLTUInt32_t addedSize = AliHLTTRDUtils::AddESDToOutput(esd, (AliHLTUInt8_t*)(outputPtr+offset));
485 totalSize += addedSize;
486
487 // Fill block
488 AliHLTComponentBlockData bd;
489 FillBlockData( bd );
490 //bd.fPtr = outputPtr;
491 bd.fOffset = offset;
492 bd.fSize = addedSize;
493 bd.fSpecification = dBlockSpecification;
494 bd.fDataType = kAliHLTDataTypeTrack | kAliHLTDataOriginTRD;
495 outputBlocks.push_back( bd );
496 HLTDebug("BD fPtr 0x%x, fOffset %i, fSize %i, fSpec 0x%x", bd.fPtr, bd.fOffset, bd.fSize, bd.fSpecification);
497 offset = totalSize;
498
499 if (trdTracks){
500 //Int_t nbTracks=trdTracks->GetEntriesFast();
501 //if (nbTracks>0){
502 HLTDebug("We have an output array: pointer to trdTracks = 0x%x, nbEntries = %i", trdTracks, trdTracks->GetEntriesFast());
503
504 AliHLTUInt32_t addedSize = AliHLTTRDUtils::AddTracksToOutput(trdTracks, (AliHLTUInt8_t*)(outputPtr+offset));
505 totalSize += addedSize;
506
507 // Fill block
508 AliHLTComponentBlockData bd;
509 FillBlockData( bd );
510 //bd.fPtr = outputPtr;
511 bd.fOffset = offset;
512 bd.fSize = addedSize;
513 bd.fSpecification = dBlockSpecification;
514 bd.fDataType = AliHLTTRDDefinitions::fgkTRDSATracksDataType;
515 outputBlocks.push_back( bd );
516 HLTDebug("BD fPtr 0x%x, fOffset %i, fSize %i, fSpec 0x%x", bd.fPtr, bd.fOffset, bd.fSize, bd.fSpecification);
517 offset = totalSize;
518 }
c702bc56 519 }
520
18ada816 521
522 // if (trdTracks)
523 // totalSize += TransportTracks(trdTracks, outputPtr, outputBlocks, offset, dBlockSpecification);
524 // else {
525 // HLTDebug("Bad array trdTracks = 0x%x", trdTracks);
526 // }
527
d679dd6c 528 HLTDebug("totalSize: %i", totalSize);
529
530// if ( totalSize > allocSize )
531// {
532// HLTError("Too much data; Data written over allowed buffer. Amount written: %lu, allowed amount: %lu.",
533// totalSize, size );
534// return EMSGSIZE;
535// }
536
537 //here we are deleting clusters (but not the TClonesArray itself)
538 fTracker->UnloadClusters();
d679dd6c 539 AliTRDReconstructor::SetClusters(0x0);
540 delete esd;
5a9a2eb5 541 clusterArray->Delete();
542 delete clusterArray;
543
d679dd6c 544 }
545
d679dd6c 546 size = totalSize;
547 HLTDebug("Event is done. size written to the output is %i", size);
d679dd6c 548 return 0;
549}