3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 //* for The ALICE HLT Project. *
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 //**************************************************************************
19 /** @file AliHLTTPCEsdWriterComponent.cxx
20 @author Matthias Richter
22 @brief Writer component to store tracks of the HLT TPC conformal
23 mapping tracker in the AliESD format
26 // see header file for class documentation
28 // refer to README to build package
30 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
33 #include "AliHLTTPCEsdWriterComponent.h"
34 #include "AliESDEvent.h"
35 #include "AliESDtrack.h"
36 #include "AliCDBEntry.h"
37 #include "AliCDBManager.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"
48 /** ROOT macro for the implementation of ROOT specific class methods */
49 ClassImp(AliHLTTPCEsdWriterComponent)
51 AliHLTTPCEsdWriterComponent::AliHLTTPCEsdWriterComponent()
53 fSolenoidBz(0),fDoMCLabels(0)
55 // see header file for class documentation
57 // refer to README to build package
59 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
62 AliHLTTPCEsdWriterComponent::~AliHLTTPCEsdWriterComponent()
64 // see header file for class documentation
67 AliHLTTPCEsdWriterComponent::AliWriter::AliWriter()
71 fBase(new AliHLTTPCEsdWriterComponent)
73 // see header file for class documentation
75 // refer to README to build package
77 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
80 AliHLTTPCEsdWriterComponent::AliWriter::~AliWriter()
82 // see header file for class documentation
83 if (fBase) delete fBase;
87 void AliHLTTPCEsdWriterComponent::AliWriter::GetInputDataTypes(AliHLTComponentDataTypeList& list)
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);
95 int AliHLTTPCEsdWriterComponent::AliWriter::InitWriter()
97 // see header file for class documentation
99 fESD = new AliESDEvent;
101 fESD->CreateStdContent();
102 fTree = new TTree("esdTree", "Tree with HLT ESD objects");
104 fTree->SetDirectory(0);
105 fESD->WriteToTree(fTree);
113 iResult=fBase->Reconfigure(NULL, NULL);
119 int AliHLTTPCEsdWriterComponent::AliWriter::CloseWriter()
121 // see header file for class documentation
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();
133 HLTWarning("not initialized");
139 iResult=AliHLTRootFileWriterComponent::CloseWriter();
143 int AliHLTTPCEsdWriterComponent::AliWriter::DumpEvent( const AliHLTComponentEventData& evtData,
144 const AliHLTComponentBlockData* blocks,
145 AliHLTComponentTriggerData& /*trigData*/ )
147 // see header file for class documentation
151 if (pTree && fBase) {
153 AliESDEvent* pESD=fESD;
155 iResult=fBase->ProcessBlocks(pTree, pESD, blocks, (int)evtData.fBlockCnt);
164 int AliHLTTPCEsdWriterComponent::AliWriter::ScanArgument(int argc, const char** argv)
166 // see header file for class documentation
167 int iResult=AliHLTRootFileWriterComponent::ScanArgument(argc, argv);
171 int AliHLTTPCEsdWriterComponent::ProcessBlocks(TTree* pTree, AliESDEvent* pESD,
172 const AliHLTComponentBlockData* blocks,
173 int nBlocks, int* pMinSlice,
176 // see header file for class documentation
179 int iAddedDataBlocks=0;
181 if (pESD && blocks) {
183 pESD->SetMagneticField(fSolenoidBz);
184 const AliHLTComponentBlockData* iter = NULL;
185 AliHLTTPCTrackletData* inPtr=NULL;
188 // first read all the MC information
189 for (int ndx=0; ndx<nBlocks && iResult>=0; ndx++) {
191 if(iter->fDataType == AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo ) {
193 for( int i=0; i<36*6; i++ ){
194 fClusterLabels[i] = 0;
195 fNClusterLabels[i] = 0;
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);
206 // do the conversion of tracks
207 for (int ndx=0; ndx<nBlocks && iResult>=0; 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
217 if (pMinSlice) *pMinSlice=0;
218 if (pMaxSlice) *pMaxSlice=AliHLTTPCTransform::GetNSlice()-1;
220 if (pMinSlice && (*pMinSlice==-1 || *pMinSlice>minslice)) *pMinSlice=minslice;
221 if (pMaxSlice && (*pMaxSlice==-1 || *pMaxSlice<maxslice)) *pMaxSlice=maxslice;
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");
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) {
238 HLTError("invalid sector number");
243 if (iAddedDataBlocks>0 && pTree) {
250 if (iResult>=0) iResult=iAddedDataBlocks;
254 int AliHLTTPCEsdWriterComponent::Tracks2ESD(AliHLTTPCTrackArray* pTracks, AliESDEvent* pESD)
256 // see header file for class documentation
258 if (pTracks && pESD) {
260 for (int i=0; i<pTracks->GetNTracks() && iResult>=0; i++) {
261 AliHLTTPCTrack* pTrack=(*pTracks)[i];
264 if( pTrack->Convert2AliKalmanTrack() ){
265 HLTError("conversion to AliKalmanTrack failed for track %d of %d", i, pTracks->GetNTracks());
269 Float_t points[4] = {pTrack->GetFirstPointX(), pTrack->GetFirstPointY(), pTrack->GetLastPointX(), pTrack->GetLastPointY() };
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;
284 // get MC label for the track
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];
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 );
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] );
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 );
313 std::sort( labels.begin(), labels.end() );
315 labels.push_back( -1 ); // put -1 to the end
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;
324 labelCur = labels[iLab];
330 if( labelMax>=0 && nLabelsMax < 0.9 * nHits ) labelMax = -labelMax;
335 pTrack->SetLabel( mcLabel );
338 iotrack.UpdateTrackParams(pTrack,AliESDtrack::kTPCin);
339 iotrack.SetTPCPoints(points);
341 pESD->AddTrack(&iotrack);
344 HLTError("internal mismatch in array");
355 int AliHLTTPCEsdWriterComponent::Configure(const char* arguments)
357 // see header file for class documentation
359 if (!arguments) return iResult;
361 TString allArgs=arguments;
365 TObjArray* pTokens=allArgs.Tokenize(" ");
367 for (int i=0; i<pTokens->GetEntries() && iResult>=0; i++) {
368 argument=((TObjString*)pTokens->At(i))->GetString();
369 if (argument.IsNull()) continue;
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();
377 HLTError("unknown argument %s", argument.Data());
385 HLTError("missing parameter for argument %s", argument.Data());
392 int AliHLTTPCEsdWriterComponent::Reconfigure(const char* cdbEntry, const char* chainId)
394 // see header file for class documentation
396 const char* path=kAliHLTCDBSolenoidBz;
397 const char* defaultNotify="";
400 defaultNotify=" (default)";
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()*/);
406 TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
408 HLTInfo("received configuration object string: \'%s\'", pString->GetString().Data());
409 iResult=Configure(pString->GetString().Data());
411 HLTError("configuration object \"%s\" has wrong type, required TObjString", path);
414 HLTError("can not fetch object \"%s\" from CDB", path);
421 AliHLTTPCEsdWriterComponent::AliConverter::AliConverter()
424 fBase(new AliHLTTPCEsdWriterComponent),
427 // see header file for class documentation
429 // refer to README to build package
431 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
434 AliHLTTPCEsdWriterComponent::AliConverter::~AliConverter()
436 // see header file for class documentation
437 if (fBase) delete fBase;
440 if (fESD) delete fESD;
444 void AliHLTTPCEsdWriterComponent::AliConverter::GetInputDataTypes(AliHLTComponentDataTypeList& list)
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);
452 AliHLTComponentDataType AliHLTTPCEsdWriterComponent::AliConverter::GetOutputDataType()
454 // see header file for class documentation
455 return kAliHLTDataTypeESDTree;
458 void AliHLTTPCEsdWriterComponent::AliConverter::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
460 // see header file for class documentation
462 inputMultiplier=10.0;
465 int AliHLTTPCEsdWriterComponent::AliConverter::DoInit(int argc, const char** argv)
467 // see header file for class documentation
471 for (int i=0; i<argc && iResult>=0; i++) {
473 if (argument.IsNull()) continue;
476 if (argument.CompareTo("-notree")==0) {
480 } else if (argument.CompareTo("-tree")==0) {
484 } else if (argument.CompareTo("-solenoidBz")==0) {
485 TString tmp="-solenoidBz ";
487 fBase->Configure(tmp.Data());
489 HLTError("unknown argument %s", argument.Data());
494 HLTError("missing parameter for argument %s", argument.Data());
499 iResult=fBase->Reconfigure(NULL, NULL);
505 int AliHLTTPCEsdWriterComponent::AliConverter::DoDeinit()
507 // see header file for class documentation
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*/ )
518 // see header file for class documentation
520 // no direct writing to the output buffer
525 fESD = new AliESDEvent;
527 fESD->CreateStdContent();
533 AliESDEvent* pESD = fESD;
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.
543 pTree = new TTree("esdTree", "Tree with HLT ESD objects");
546 pTree->SetDirectory(0);
549 if ((iResult=fBase->ProcessBlocks(pTree, pESD, blocks, (int)evtData.fBlockCnt))>0) {
550 // TODO: set the specification correctly
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);
558 iResult=PushBack(pESD, kAliHLTDataTypeESDObject|kAliHLTDataOriginTPC, 0);
562 // clear user info list to prevent objects from being deleted
563 pTree->GetUserInfo()->Clear();