bugfix: check for output buffer size
[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 // see header file for class documentation                                   //
27 // or                                                                        //
28 // refer to README to build package                                          //
29 // or                                                                        //
30 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt                          //
31
32 #if __GNUC__>= 3
33 using namespace std;
34 #endif
35
36 #include <climits>
37 #include "AliHLTTPCGlobalMergerComponent.h"
38 //#include "AliHLTTPCTransform.h"
39 #include "AliHLTTPCGlobalMerger.h"
40 #include "AliHLTTPCVertex.h"
41 #include "AliHLTTPCVertexData.h"
42 #include "AliHLTTPCTrackSegmentData.h"
43 #include "AliHLTTPCTrackArray.h"
44 #include "AliHLTTPCTrackletDataFormat.h"
45 //#include "AliHLTTPCSpacePointData.h"
46 //#include "AliHLTTPCClusterDataFormat.h"
47 #include "AliHLTTPCDefinitions.h"
48 #include <cstdlib>
49 #include <cerrno>
50
51 /** ROOT macro for the implementation of ROOT specific class methods */
52 ClassImp(AliHLTTPCGlobalMergerComponent);
53
54 AliHLTTPCGlobalMergerComponent::AliHLTTPCGlobalMergerComponent()
55   :
56   fGlobalMerger(NULL),
57   fVertex(NULL)
58 {
59   // see header file for class documentation
60   // or
61   // refer to README to build package
62   // or
63   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
64 }
65
66 AliHLTTPCGlobalMergerComponent::~AliHLTTPCGlobalMergerComponent()
67 {
68   // see header file for class documentation
69 }
70
71 // Public functions to implement AliHLTComponent's interface.
72 // These functions are required for the registration process
73
74 const char* AliHLTTPCGlobalMergerComponent::GetComponentID()
75 {
76   // see header file for class documentation
77   return "TPCGlobalMerger";
78 }
79
80 void AliHLTTPCGlobalMergerComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
81 {
82   // see header file for class documentation
83   list.clear();
84   list.push_back( AliHLTTPCDefinitions::fgkTrackSegmentsDataType );
85   list.push_back( AliHLTTPCDefinitions::fgkVertexDataType );
86 }
87
88 AliHLTComponentDataType AliHLTTPCGlobalMergerComponent::GetOutputDataType()
89 {
90   // see header file for class documentation
91   return AliHLTTPCDefinitions::fgkTracksDataType;
92 }
93
94 void AliHLTTPCGlobalMergerComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
95 {
96   // see header file for class documentation
97   // XXX TODO: Find more realistic values.
98   constBase = 0;
99   inputMultiplier = 1.0;
100 }
101
102 AliHLTComponent* AliHLTTPCGlobalMergerComponent::Spawn()
103 {
104   // see header file for class documentation
105   return new AliHLTTPCGlobalMergerComponent;
106 }
107
108 void AliHLTTPCGlobalMergerComponent::SetMergerParameters(Double_t maxy,Double_t maxz,Double_t maxkappa,Double_t maxpsi,Double_t maxtgl)
109 {
110   // see header file for class documentation
111   fGlobalMerger->SetParameter( maxy, maxz, maxkappa, maxpsi, maxtgl );
112 }
113
114 int AliHLTTPCGlobalMergerComponent::DoInit( int /*argc*/, const char** /*argv*/ )
115 {
116   // see header file for class documentation
117   if ( fGlobalMerger || fVertex )
118     return EINPROGRESS;
119   fGlobalMerger = new AliHLTTPCGlobalMerger();
120   fVertex = new AliHLTTPCVertex();
121   SetMergerParameters();
122   return 0;
123 }
124
125 int AliHLTTPCGlobalMergerComponent::DoDeinit()
126 {
127   // see header file for class documentation
128   if ( fGlobalMerger )
129     delete fGlobalMerger;
130   fGlobalMerger = NULL;
131   if ( fVertex )
132     delete fVertex;
133   fVertex = NULL;
134   return 0;
135 }
136
137 int AliHLTTPCGlobalMergerComponent::DoEvent( const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, 
138                                               AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, 
139                                               AliHLTUInt32_t& size, AliHLTComponentBlockDataList& outputBlocks )
140 {
141   // see header file for class documentation
142   int iResult=0;
143   const AliHLTComponentBlockData* iter = NULL;
144   const AliHLTComponentBlockData* lastVertexBlock = NULL;
145   unsigned long ndx;
146
147   std::vector<SliceData> slices;
148   std::vector<SliceData>::iterator sdIter, sdEnd;
149   int minSlice = INT_MAX, maxSlice = 0;
150   bool found;
151   AliHLTTPCTrackletData* inPtr;
152   AliHLTTPCTrackletData* outPtr;
153   UInt_t tSize = 0;
154   Int_t slice=0;
155
156   // Create sorted (by slice number) list of data (tracks and vertex) for each slice present.
157   // also note the min and max slice numbers
158   for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
159     {
160       iter = blocks+ndx;
161       slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
162       found=false;
163       sdIter = slices.begin();
164       sdEnd = slices.end();
165       while ( sdIter != sdEnd )
166         {
167           if ( sdIter->fSlice > slice || sdIter->fSlice == slice )
168             break;
169           sdIter++;
170         }
171       if ( sdIter==sdEnd || sdIter->fSlice>slice )
172         {
173           if ( sdIter == sdEnd )
174             maxSlice = slice;
175           if ( sdIter==slices.begin() )
176             minSlice = slice;
177           SliceData sd;
178           sd.fSlice = slice;
179           sd.fVertexBlock = NULL;
180           sd.fVertexBlockIndex = 0;
181           sd.fTrackletBlock = NULL;
182           sd.fTrackletBlockIndex = 0;
183           sdIter = slices.insert( sdIter, sd );
184         }
185       if ( sdIter->fSlice == slice )
186         {
187           if ( iter->fDataType == AliHLTTPCDefinitions::fgkTrackSegmentsDataType )
188             {
189               if ( !sdIter->fTrackletBlock )
190                 {
191                   sdIter->fTrackletBlock = iter;
192                   sdIter->fTrackletBlockIndex = ndx;
193                 }
194               else
195                 {
196                   Logging( kHLTLogError, "HLT::GlobalMerger::DoEvent", "Duplicate track data block",
197                            "Duplicate track data block for slice %lu in event 0x%08lX (%lu) - previous block: %lu - new block: %lu.",
198                            slice, evtData.fEventID, evtData.fEventID, sdIter->fTrackletBlockIndex, ndx );
199                 }
200             }
201           if ( iter->fDataType == AliHLTTPCDefinitions::fgkVertexDataType )
202             {
203               lastVertexBlock = iter;
204               if ( !sdIter->fVertexBlock )
205                 {
206                   sdIter->fVertexBlock = iter;
207                   sdIter->fVertexBlockIndex = ndx;
208                 }
209               else
210                 {
211                   Logging( kHLTLogError, "HLT::GlobalMerger::DoEvent", "Duplicate vertex data block",
212                            "Duplicate vertex data block for slice %lu in event 0x%08lX (%lu) - previous block: %lu - new block: %lu.",
213                            slice, evtData.fEventID, evtData.fEventID, sdIter->fVertexBlockIndex, ndx );
214                 }
215             }
216         }
217     }
218
219   //fGlobalMerger->Setup( minSlice, maxSlice );
220   fGlobalMerger->Setup( 0, 35 );
221
222   if ( !lastVertexBlock )
223     {
224       Logging( kHLTLogInfo, "HLT::GlobalMerger::DoEvent", "No vertex data block",
225                "No vertex data block found  for event  0x%08lX (%lu).", evtData.fEventID, evtData.fEventID );
226       fVertex->SetZero();
227     }
228   else
229     fVertex->Read( (AliHLTTPCVertexData*)( lastVertexBlock->fPtr ) );
230
231   // Add all tracks into the merger
232   sdIter = slices.begin();
233   sdEnd = slices.end();
234   int lastSlice = -1;
235   while ( sdIter != sdEnd )
236     {
237       if ( sdIter->fVertexBlock )
238         {
239           fVertex->Read( (AliHLTTPCVertexData*)( sdIter->fVertexBlock->fPtr ) );
240           fGlobalMerger->SetVertex( fVertex );
241         }
242       for ( int slNr=lastSlice+1; slNr<=sdIter->fSlice; slNr++ )
243         fGlobalMerger->InitSlice( slNr );
244       if ( sdIter->fTrackletBlock )
245         {
246           inPtr = (AliHLTTPCTrackletData*)( sdIter->fTrackletBlock->fPtr );
247           if ( !inPtr )
248             {
249               Logging( kHLTLogError, "HLT::GlobalMerger::DoEvent", "No track data block",
250                        "No track data block found  for event  0x%08lX (%lu).", evtData.fEventID, evtData.fEventID );
251             }
252           else
253             {
254               //fGlobalMerger->InitSlice( sdIter->fSlice );
255               fGlobalMerger->FillTracks( inPtr->fTrackletCnt, inPtr->fTracklets );
256             } 
257         }
258       lastSlice = sdIter->fSlice;
259       sdIter++;
260     }
261   for ( int slNr=lastSlice+1; slNr<=35; slNr++ )
262     fGlobalMerger->InitSlice( slNr );
263     
264
265   // Now we can really merge
266   fGlobalMerger->Merge();
267   fGlobalMerger->AddAllTracks();
268
269   // check if there was enough space in the output buffer
270   UInt_t ntracks0=fGlobalMerger->GetOutTracks()->GetNTracks();
271   if (outputPtr==NULL || (sizeof(AliHLTTPCTrackletData)+ntracks0*sizeof(AliHLTTPCTrackSegmentData)>size)) {
272     iResult=-ENOSPC;
273   } else {
274   outPtr = (AliHLTTPCTrackletData*)(outputPtr);
275
276   tSize = fGlobalMerger->GetOutTracks()->WriteTracks( ntracks0, outPtr->fTracklets );
277   outPtr->fTrackletCnt = ntracks0;
278
279   tSize += sizeof(AliHLTTPCTrackletData);
280
281   AliHLTComponentBlockData bd;
282   FillBlockData( bd );
283   bd.fOffset = 0;
284   bd.fSize = tSize;
285   bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification( minSlice, maxSlice, 0, 5 );
286   outputBlocks.push_back( bd );
287   }
288
289   size = tSize;
290   return iResult;
291 }
292
293