]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCGlobalMergerComponent.cxx
correcting memory leaks on error conditions
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCGlobalMergerComponent.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 //*                  Timm Steinbeck <timm@kip.uni-heidelberg.de>           *
9 //*                  for The ALICE HLT Project.                            *
10 //*                                                                        *
11 //* Permission to use, copy, modify and distribute this software and its   *
12 //* documentation strictly for non-commercial purposes is hereby granted   *
13 //* without fee, provided that the above copyright notice appears in all   *
14 //* copies and that both the copyright notice and this permission notice   *
15 //* appear in the supporting documentation. The authors make no claims     *
16 //* about the suitability of this software for any purpose. It is          *
17 //* provided "as is" without express or implied warranty.                  *
18 //**************************************************************************
19
20 /** @file   AliHLTTPCGlobalMergerComponent.cxx
21     @author Timm Steinbeck, Matthias Richter
22     @date   
23     @brief  HLT TPC global merger component.
24 */
25
26 #if __GNUC__>= 3
27 using namespace std;
28 #endif
29
30 #include <climits>
31 #include "AliHLTTPCGlobalMergerComponent.h"
32 #include "AliHLTTPCTransform.h"
33 #include "AliHLTTPCGlobalMerger.h"
34 #include "AliHLTTPCVertex.h"
35 #include "AliHLTTPCVertexData.h"
36 #include "AliHLTTPCTrackSegmentData.h"
37 #include "AliHLTTPCTrackArray.h"
38 #include "AliHLTTPCTrackletDataFormat.h"
39 //#include "AliHLTTPCSpacePointData.h"
40 //#include "AliHLTTPCClusterDataFormat.h"
41 #include "AliHLTTPCDefinitions.h"
42 #include <cstdlib>
43 #include <cerrno>
44
45 /** ROOT macro for the implementation of ROOT specific class methods */
46 ClassImp(AliHLTTPCGlobalMergerComponent);
47
48 AliHLTTPCGlobalMergerComponent::AliHLTTPCGlobalMergerComponent()
49   :
50   fGlobalMerger(NULL),
51   fVertex(NULL)
52 {
53   // see header file for class documentation
54   // or
55   // refer to README to build package
56   // or
57   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
58 }
59
60 AliHLTTPCGlobalMergerComponent::~AliHLTTPCGlobalMergerComponent()
61 {
62   // see header file for class documentation
63 }
64
65 // Public functions to implement AliHLTComponent's interface.
66 // These functions are required for the registration process
67
68 const char* AliHLTTPCGlobalMergerComponent::GetComponentID()
69 {
70   // see header file for class documentation
71   return "TPCGlobalMerger";
72 }
73
74 void AliHLTTPCGlobalMergerComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
75 {
76   // see header file for class documentation
77   list.clear();
78   list.push_back( AliHLTTPCDefinitions::fgkTrackSegmentsDataType );
79   list.push_back( AliHLTTPCDefinitions::fgkVertexDataType );
80 }
81
82 AliHLTComponentDataType AliHLTTPCGlobalMergerComponent::GetOutputDataType()
83 {
84   // see header file for class documentation
85   return AliHLTTPCDefinitions::fgkTracksDataType;
86 }
87
88 void AliHLTTPCGlobalMergerComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
89 {
90   // see header file for class documentation
91   // XXX TODO: Find more realistic values.
92   constBase = 0;
93   inputMultiplier = 1.0;
94 }
95
96 AliHLTComponent* AliHLTTPCGlobalMergerComponent::Spawn()
97 {
98   // see header file for class documentation
99   return new AliHLTTPCGlobalMergerComponent;
100 }
101
102 void AliHLTTPCGlobalMergerComponent::SetMergerParameters(Double_t maxy,Double_t maxz,Double_t maxkappa,Double_t maxpsi,Double_t maxtgl)
103 {
104   // see header file for class documentation
105   fGlobalMerger->SetParameter( maxy, maxz, maxkappa, maxpsi, maxtgl );
106 }
107
108 int AliHLTTPCGlobalMergerComponent::DoInit( int /*argc*/, const char** /*argv*/ )
109 {
110   // see header file for class documentation
111   if ( fGlobalMerger || fVertex )
112     return EINPROGRESS;
113   fGlobalMerger = new AliHLTTPCGlobalMerger();
114   fVertex = new AliHLTTPCVertex();
115   SetMergerParameters();
116   return 0;
117 }
118
119 int AliHLTTPCGlobalMergerComponent::DoDeinit()
120 {
121   // see header file for class documentation
122   if ( fGlobalMerger )
123     delete fGlobalMerger;
124   fGlobalMerger = NULL;
125   if ( fVertex )
126     delete fVertex;
127   fVertex = NULL;
128   return 0;
129 }
130
131 int AliHLTTPCGlobalMergerComponent::DoEvent( const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, 
132                                               AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, 
133                                               AliHLTUInt32_t& size, AliHLTComponentBlockDataList& outputBlocks )
134 {
135   // see header file for class documentation
136   int iResult=0;
137   AliHLTUInt32_t capacity=size;
138   size=0;
139
140   if (!IsDataEvent()) return 0;
141
142   const AliHLTComponentBlockData* iter = NULL;
143   const AliHLTComponentBlockData* lastVertexBlock = NULL;
144   unsigned long ndx;
145
146   std::vector<SliceData> slices;
147   std::vector<SliceData>::iterator sdIter, sdEnd;
148   int minSlice = INT_MAX, maxSlice = 0;
149   bool found;
150   AliHLTTPCTrackletData* inPtr;
151   AliHLTTPCTrackletData* outPtr;
152   UInt_t tSize = 0;
153   Int_t slice=0;
154
155   // Create sorted (by slice number) list of data (tracks and vertex) for each slice present.
156   // also note the min and max slice numbers
157   for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
158     {
159       iter = blocks+ndx;
160       bool bIsTrackSegDataBlock=false;
161       bool bIsVertexDataBlock=false;
162       if(!(bIsTrackSegDataBlock=(iter->fDataType==AliHLTTPCDefinitions::fgkTrackSegmentsDataType)) &&
163          !(bIsVertexDataBlock=(iter->fDataType==AliHLTTPCDefinitions::fgkVertexDataType))){
164         continue;
165       }
166
167       slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
168       if (slice<0 || slice>=AliHLTTPCTransform::GetNSlice()) {
169         HLTError("invalid slice number %d extracted from specification 0x%08lx,  skipping block of type %s",
170                  slice, iter->fSpecification, DataType2Text(iter->fDataType).c_str());
171         // just remember the error, if there are other valid blocks ignore the
172         // error, return code otherwise
173         iResult=-EBADF;
174         continue;
175       }
176       if (slice!=AliHLTTPCDefinitions::GetMaxSliceNr( *iter )) {
177         // the code was not written for/ never used with multiple slices
178         // in one data block/ specification
179         HLTWarning("specification 0x%08lx indicates multiple slices in data block %s: never used before, please audit the code",
180                    iter->fSpecification, DataType2Text(iter->fDataType).c_str());
181       }
182       found=false;
183       sdIter = slices.begin();
184       sdEnd = slices.end();
185       while ( sdIter != sdEnd )
186         {
187           if ( sdIter->fSlice > slice || sdIter->fSlice == slice )
188             break;
189           sdIter++;
190         }
191       if ( sdIter==sdEnd || sdIter->fSlice>slice )
192         {
193           if ( sdIter == sdEnd )
194             maxSlice = slice;
195           if ( sdIter==slices.begin() )
196             minSlice = slice;
197           SliceData sd;
198           sd.fSlice = slice;
199           sd.fVertexBlock = NULL;
200           sd.fVertexBlockIndex = 0;
201           sd.fTrackletBlock = NULL;
202           sd.fTrackletBlockIndex = 0;
203           sdIter = slices.insert( sdIter, sd );
204         }
205       if ( sdIter->fSlice == slice )
206         {
207           if (bIsTrackSegDataBlock)
208             {
209               if ( !sdIter->fTrackletBlock )
210                 {
211                   sdIter->fTrackletBlock = iter;
212                   sdIter->fTrackletBlockIndex = ndx;
213                 }
214               else
215                 {
216                   Logging( kHLTLogError, "HLT::GlobalMerger::DoEvent", "Duplicate track data block",
217                            "Duplicate track data block for slice %lu in event 0x%08lX (%lu) - previous block: %lu - new block: %lu.",
218                            slice, evtData.fEventID, evtData.fEventID, sdIter->fTrackletBlockIndex, ndx );
219                 }
220             }
221           if (bIsVertexDataBlock)
222             {
223               lastVertexBlock = iter;
224               if ( !sdIter->fVertexBlock )
225                 {
226                   sdIter->fVertexBlock = iter;
227                   sdIter->fVertexBlockIndex = ndx;
228                 }
229               else
230                 {
231                   Logging( kHLTLogError, "HLT::GlobalMerger::DoEvent", "Duplicate vertex data block",
232                            "Duplicate vertex data block for slice %lu in event 0x%08lX (%lu) - previous block: %lu - new block: %lu.",
233                            slice, evtData.fEventID, evtData.fEventID, sdIter->fVertexBlockIndex, ndx );
234                 }
235             }
236         }
237     }
238
239   // skip the processing if there was no track segment data
240   if (slices.size()==0) {
241     return iResult;
242   }
243   iResult=0;
244
245   //fGlobalMerger->Setup( minSlice, maxSlice );
246   fGlobalMerger->Setup( 0, 35 );
247
248   if ( !lastVertexBlock )
249     {
250       Logging( kHLTLogInfo, "HLT::GlobalMerger::DoEvent", "No vertex data block",
251                "No vertex data block found  for event  0x%08lX (%lu).", evtData.fEventID, evtData.fEventID );
252       fVertex->SetZero();
253     }
254   else
255     fVertex->Read( (AliHLTTPCVertexData*)( lastVertexBlock->fPtr ) );
256
257   // Add all tracks into the merger
258   sdIter = slices.begin();
259   sdEnd = slices.end();
260   int lastSlice = -1;
261   while ( sdIter != sdEnd )
262     {
263       if ( sdIter->fVertexBlock )
264         {
265           fVertex->Read( (AliHLTTPCVertexData*)( sdIter->fVertexBlock->fPtr ) );
266           fGlobalMerger->SetVertex( fVertex );
267         }
268       for ( int slNr=lastSlice+1; slNr<=sdIter->fSlice; slNr++ )
269         fGlobalMerger->InitSlice( slNr );
270       if ( sdIter->fTrackletBlock )
271         {
272           inPtr = (AliHLTTPCTrackletData*)( sdIter->fTrackletBlock->fPtr );
273           if ( !inPtr )
274             {
275               Logging( kHLTLogError, "HLT::GlobalMerger::DoEvent", "No track data block",
276                        "No track data block found  for event  0x%08lX (%lu).", evtData.fEventID, evtData.fEventID );
277             }
278           else
279             {
280               //fGlobalMerger->InitSlice( sdIter->fSlice );
281               fGlobalMerger->FillTracks( inPtr->fTrackletCnt, inPtr->fTracklets );
282             } 
283         }
284       lastSlice = sdIter->fSlice;
285       sdIter++;
286     }
287   for ( int slNr=lastSlice+1; slNr<=35; slNr++ )
288     fGlobalMerger->InitSlice( slNr );
289     
290
291   // Now we can really merge
292   fGlobalMerger->Merge();
293   fGlobalMerger->AddAllTracks();
294
295   // check if there was enough space in the output buffer
296   UInt_t ntracks0=fGlobalMerger->GetOutTracks()->GetNTracks();
297   if (outputPtr==NULL || (sizeof(AliHLTTPCTrackletData)+ntracks0*sizeof(AliHLTTPCTrackSegmentData)>capacity)) {
298     iResult=-ENOSPC;
299   } else {
300   outPtr = (AliHLTTPCTrackletData*)(outputPtr);
301
302   tSize = fGlobalMerger->GetOutTracks()->WriteTracks( ntracks0, outPtr->fTracklets );
303   outPtr->fTrackletCnt = ntracks0;
304
305   tSize += sizeof(AliHLTTPCTrackletData);
306
307   AliHLTComponentBlockData bd;
308   FillBlockData( bd );
309   bd.fOffset = 0;
310   bd.fSize = tSize;
311   bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification( minSlice, maxSlice, 0, 5 );
312   outputBlocks.push_back( bd );
313   }
314
315   size = tSize;
316   return iResult;
317 }
318
319