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: Timm Steinbeck <timm@kip.uni-heidelberg.de> *
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 AliHLTTPCCompModelConverter.cxx
20 @author Timm Steinbeck
21 @author changed by J. Wagner
23 @brief A copy processing component for the HLT. */
29 #include "AliHLTTPCCompModelConverter.h"
30 #include "AliHLTTPCTransform.h"
31 #include "AliHLTTPCTrack.h"
32 #include "AliHLTTPCModelTrack.h"
33 #include "AliHLTTPCCompDataCompressorHelper.h"
34 #include "AliHLTTPCSpacePointContainer.h"
37 AliHLTTPCCompModelConverter::AliHLTTPCCompModelConverter()
40 , fOutputTrackArray("AliHLTTPCModelTrack")
41 , fModelAnalysisInstance(NULL)
44 // see header file for class documentation
45 for ( UInt_t slice=0; slice<36; slice++ )
46 for ( UInt_t patch=0; patch<6; patch++ )
48 fClusterUsedSizes[slice][patch] = 0;
49 fClusterUsed[slice][patch] = NULL;
55 AliHLTTPCCompModelConverter::AliHLTTPCCompModelConverter(AliHLTTPCCompModelAnalysis* modelanalysis)
58 , fOutputTrackArray("AliHLTTPCModelTrack")
59 , fModelAnalysisInstance(modelanalysis)
62 // see header file for class documentation
63 for ( UInt_t slice=0; slice<36; slice++ )
64 for ( UInt_t patch=0; patch<6; patch++ )
66 fClusterUsedSizes[slice][patch] = 0;
67 fClusterUsed[slice][patch] = NULL;
73 AliHLTTPCCompModelConverter::~AliHLTTPCCompModelConverter()
75 // see header file for class documentation
76 for ( UInt_t slice=0; slice<36; slice++ )
77 for ( UInt_t patch=0; patch<6; patch++ )
79 if ( fClusterUsed[slice][patch] )
81 delete [] fClusterUsed[slice][patch];
82 fClusterUsed[slice][patch] = NULL;
88 int AliHLTTPCCompModelConverter::Init()
90 // see header file for class documentation
91 fInputTrackArray.clear();
92 fOutputTrackArray.Reset();
93 for ( UInt_t slice=0; slice<36; slice++ )
94 for ( UInt_t patch=0; patch<6; patch++ )
95 fClusters[slice][patch] = NULL;
100 int AliHLTTPCCompModelConverter::SetInputTracks( const AliHLTTracksData* pTracks, unsigned sizeInByte )
102 // see header file for class documentation
103 HLTDebug( "Filling %u tracks", (unsigned)pTracks->fCount );
104 return AliHLTGlobalBarrelTrack::ConvertTrackDataArray(pTracks, sizeInByte, fInputTrackArray);
107 int AliHLTTPCCompModelConverter::SetInputClusters( AliHLTTPCClusterData* clusters, UInt_t slice, UInt_t patch )
109 // set input clusters for a partition
110 if ( slice>=36 || patch>=6 )
112 if ( fClusters[slice][patch] )
114 fClusters[slice][patch] = clusters;
115 if ( fClusterUsedSizes[slice][patch]<clusters->fSpacePointCnt ||
116 fClusterUsedSizes[slice][patch]>clusters->fSpacePointCnt*8 )
118 delete [] fClusterUsed[slice][patch];
119 fClusterUsed[slice][patch] = NULL;
121 if ( !fClusterUsed[slice][patch] )
123 fClusterUsed[slice][patch] = new bool[clusters->fSpacePointCnt];
124 if ( !fClusterUsed[slice][patch] )
129 for ( unsigned long nn=0; nn<clusters->fSpacePointCnt; nn++ )
130 fClusterUsed[slice][patch][nn]=false;
135 void AliHLTTPCCompModelConverter::Convert()
137 // convert tracks to the track model
139 // FIXME: the tracks have supposedly been sorted according to momentum to
140 // process the high momentum tracks first, QSort however builds upon
141 // AliTPCtrack::Compare, it's implementation has been changed
142 //fInputTrackArray.QSort();
144 for(unsigned i=0; i<fInputTrackArray.size(); i++)
146 AliHLTGlobalBarrelTrack *intrack = &(fInputTrackArray[i]);
147 if(!intrack) continue;
149 if(intrack->GetNumberOfPoints()<fMinHits)
151 HLTDebug("Track %d with %d clusters is below minimum of %d clusters",i,intrack->GetNHits(),fMinHits);
155 // LOSS OF TRACKS due to following statement possible!
156 // FIXME: make this configurable
157 if(intrack->Pt()<0.1)
159 HLTDebug("Discarding track with low pt.");
160 if(fModelAnalysisInstance)
162 if(fModelAnalysisInstance->GetfModelAnalysis()) // analysis of model
164 HLTError("FIXME: correct parameter");
165 //fModelAnalysisInstance->MarkTrashTrack(intrack);
172 // check if this is necessary
173 //intrack->CalculateHelix();
175 AliHLTTPCModelTrack *outtrack = (AliHLTTPCModelTrack*)fOutputTrackArray.NextTrack();
176 outtrack->SetNHits(intrack->GetNumberOfPoints());
177 //outtrack->SetRowRange(intrack->GetFirstRow(),intrack->GetLastRow());
178 //outtrack->SetFirstPoint(intrack->GetFirstPointX(),intrack->GetFirstPointY(),intrack->GetFirstPointZ());
179 //outtrack->SetLastPoint(intrack->GetLastPointX(),intrack->GetLastPointY(),intrack->GetLastPointZ());
180 outtrack->SetPt(intrack->Pt());
181 outtrack->SetPsi(intrack->GetSnp());
182 outtrack->SetTgl(intrack->GetTgl());
183 // FIXME: charge is not propagated with AliHLTExternalTrackParam, check if it is needed
184 //outtrack->SetCharge(intrack->GetCharge());
185 outtrack->CalculateHelix();
186 Int_t nhits = intrack->GetNumberOfPoints();
187 const UInt_t *hitids = intrack->GetPoints();
188 Int_t origslice = AliHLTTPCSpacePointData::GetSlice(hitids[nhits-1]);
189 outtrack->Init(origslice,-1);
191 for(Int_t j=nhits-1; j>=0; j--)
194 Int_t slice = AliHLTTPCSpacePointData::GetSlice(id);
195 Int_t patch = AliHLTTPCSpacePointData::GetPatch(id);
196 UInt_t pos = AliHLTTPCSpacePointData::GetNumber(id);
199 if ( !fClusters[slice][patch] )
201 //HLTWarning( "No clusters for slice %d, patch %d", slice, patch );
204 if ( !fClusterUsed[slice][patch] )
206 HLTWarning( "No cluster used data for slice %d, patch %d", slice, patch );
209 if ( fClusters[slice][patch]->fSpacePointCnt<=pos )
211 HLTWarning( "Clusters position %d too large in slice %d, patch %d (%u max.)", pos,
212 slice, patch, fClusters[slice][patch]->fSpacePointCnt );
216 AliHLTTPCSpacePointData *points = fClusters[slice][patch]->fSpacePoints;
217 bool* clustersUsed = fClusterUsed[slice][patch];
218 Float_t xyz[3] = {points[pos].fX,points[pos].fY,points[pos].fZ};
219 Int_t padrow = points[pos].fPadRow;
220 //HLTInfo("track %d cluster %d: slice %d part %d nr %d:\n\t x=%f y=%f z=%f padrow=%d", i, j, slice, patch, pos, xyz[0], xyz[1], xyz[2], padrow);
222 //Calculate the crossing point between track and padrow
223 Float_t angle = 0; //Perpendicular to padrow in local coordinates
224 AliHLTTPCTransform::Local2GlobalAngle(&angle,slice);
225 // FIXME: CalculateReferencePoint not available
226 // if(!intrack->CalculateReferencePoint(angle,AliHLTTPCTransform::Row2X(padrow)))
228 // HLTError( "AliHLTDataCompressor::FillData : Error in crossing point calc on slice %d, padrow %d", slice, padrow );
230 // //outtrack->Print(kFALSE);
234 Float_t xyzCross[3] = {intrack->GetX(),intrack->GetY(),intrack->GetZ()};
237 AliHLTTPCTransform::Slice2Sector(slice,padrow,sector,row);
238 AliHLTTPCTransform::Global2Raw(xyzCross,sector,row);
240 AliHLTTPCTransform::Local2Raw(xyz,sector,row);
242 AliHLTTPCTransform::Global2Raw(xyz,sector,row);
245 outtrack->SetPadHit(padrow,xyzCross[1]);
246 outtrack->SetTimeHit(padrow,xyzCross[2]);
247 //HLTInfo("track %d cluster %d: xyzCross={%f,%f,%f}", i, j, xyzCross[0], xyzCross[1], xyzCross[2]);
248 //HLTInfo("track %d cluster %d: xyz={%f,%f,%f}", i, j, xyz[0], xyz[1], xyz[2]);
250 //outtrack->SetCrossingAngleLUT(padrow,intrack->GetCrossingAngle(padrow,slice));
251 outtrack->CalculateClusterWidths(padrow,kTRUE); // calculates parSigmas (with parametrisation) in raw coordinates
252 //HLTInfo("angle %f", outtrack->GetCrossingAngleLUT(padrow));
253 //HLTInfo("parsigma %f",outtrack->GetParSigmaY2(padrow));
254 patch = AliHLTTPCTransform::GetPatch(padrow);
255 // sigmay in units of pads (quantisation!)
256 Float_t sigmaY2 = points[pos].fSigmaY2 / pow(AliHLTTPCTransform::GetPadPitchWidth(patch),2);
257 //HLTInfo("sigmaY conv.: %f", points[pos].fSigmaY2);
259 //HLTInfo("parSigmaY2 = %f",AliHLTTPCTransform::GetParSigmaY2(padrow, xyzCross[2],angle));
260 //Float_t testsigma = 0.0;
261 //outtrack->GetSigmaY2(padrow, testsigma);
262 //HLTInfo("DSigmaY2 = %f",testsigma);
264 //HLTInfo("sigmaY2 float: %f",sigmaY2);
265 Float_t sigmaZ2 = points[pos].fSigmaZ2 / pow(AliHLTTPCTransform::GetZWidth(),2);
266 outtrack->SetCluster(padrow,xyz[1],xyz[2],points[pos].fCharge,sigmaY2,sigmaZ2,3);
267 //AliHLTTPCClusterModel* test1 = outtrack->GetClusterModel(padrow);
268 //HLTInfo("Dsigma %f",test1->fDSigmaY);
270 //IMPORTANT: Set the slice in which cluster is, you need it in AliHLTTPCModelTrack::FillTrack!
271 outtrack->GetClusterModel(padrow)->fSlice=slice;
273 outtrack->GetClusterModel(padrow)->fID=points[pos].fID;
274 HLTDebug( "Track %d cluster for padrow %d ID: %u (0x%08X) - fSlice: %u", i, padrow,
275 outtrack->GetClusterModel(padrow)->fID, outtrack->GetClusterModel(padrow)->fID,
276 (unsigned)outtrack->GetClusterModel(padrow)->fSlice );
278 //points[pos].fCharge = 0;//Mark this cluster as used.
279 clustersUsed[pos] = true;//Mark this cluster as used.
281 } //end of clusters for each track
283 //outtrack->SetNClusters(AliHLTTPCTransform::GetNRows(-1)); // Equivalent call in ExpandTrackData
284 } // end of track-loop
287 // validation test for clusternumbers of tracks:
288 //for(unsigned long jj = 0; jj < (unsigned long) fOutputTrackArray.GetNTracks(); jj++)
290 // AliHLTTPCModelTrack *track = (AliHLTTPCModelTrack*)fOutputTrackArray.GetCheckedTrack(jj);
291 // Int_t nhits = track->GetNHits();
292 // HLTInfo("Number of clusters for track %lu is %d",jj, nhits);
295 //comp->WriteFile(fOutputTrackArray);
299 void AliHLTTPCCompModelConverter::ExpandTrackData()
301 // see header file for class documentation
302 //Loop over tracks and try to assign unused clusters.
303 //Only clusters which are closer than the max. residual are taken.
305 HLTDebug( "Expanding %lu tracks", (unsigned long)fOutputTrackArray.GetNTracks() );
306 for(Int_t i=0; i<fOutputTrackArray.GetNTracks(); i++)
308 AliHLTTPCModelTrack *track = (AliHLTTPCModelTrack*)fOutputTrackArray.GetCheckedTrack(i);
312 // tracks that hit every row already cannot be expanded in the current model!
313 if(track->GetNHits() == AliHLTTPCTransform::GetNRows()) continue;
315 Int_t nhits = track->GetNHits();
318 //HLTInfo("Before expansion: track %u with number of clusters %d", i, nhits);
321 for(Int_t padrow=AliHLTTPCTransform::GetNRows()-1; padrow>=0; padrow--)
323 if(track->IsPresent(padrow))
325 lastSlice = track->GetClusterModel(padrow)->fSlice;
329 if(lastSlice < 0) //the outer cluster is missing, so skip it - it will be written anyhow.
332 //Check the slice of the next padrow:
333 Int_t nextPadrow = padrow-1;
334 Int_t nextSlice = -1;
335 while(nextPadrow >=0)
337 if(track->IsPresent(nextPadrow))
339 nextSlice = track->GetClusterModel(nextPadrow)->fSlice;
345 if(nextSlice != lastSlice)//The track crosses a slice boundary here
349 if ( !fClusters[lastSlice][0] )
351 HLTWarning( "No clusters for slice %d, patch %d", lastSlice, 0 );
354 if ( !fClusterUsed[lastSlice][0] )
356 HLTWarning( "No cluster used data for slice %d, patch %d", lastSlice, 0 );
359 AliHLTTPCSpacePointData *points = fClusters[lastSlice][0]->fSpacePoints;//->GetDataPointer(size);
360 bool* clustersUsed = fClusterUsed[lastSlice][0];
362 Float_t globalangle = 0;
363 AliHLTTPCTransform::Local2GlobalAngle(&globalangle,lastSlice);
364 if(!track->CalculateReferencePoint(globalangle,AliHLTTPCTransform::Row2X(padrow)))
366 Float_t xyzCross[3] = {track->GetPointX(),track->GetPointY(),track->GetPointZ()};
367 AliHLTTPCTransform::Global2LocHLT(xyzCross,lastSlice);
368 Float_t mindist = 123456789;
369 AliHLTTPCSpacePointData *closest=0;
371 for(UInt_t j=0; j<fClusters[lastSlice][0]->fSpacePointCnt; j++)
373 //if(points[j].fCharge == 0) continue;// || points[j].fPadRow != padrow) continue;
374 if (clustersUsed[j]) continue; // Cluster already used
375 if(points[j].fPadRow < padrow) continue;
376 if(points[j].fPadRow > padrow) break;
377 Float_t xyz[3] = {points[j].fX,points[j].fY,points[j].fZ};
380 AliHLTTPCTransform::Global2LocHLT(xyz,lastSlice);
383 //Check for overflow:
384 Int_t temp = (Int_t)rint((xyzCross[1]-xyz[1])/AliHLTTPCCompDataCompressorHelper::GetXYResidualStep(padrow));
385 if( abs(temp) > 1<<(AliHLTTPCCompDataCompressorHelper::GetNPadBits()-1))
388 temp = (Int_t)rint((xyzCross[2]-xyz[2])/AliHLTTPCCompDataCompressorHelper::GetZResidualStep(padrow));
389 if( abs(temp) > 1<<(AliHLTTPCCompDataCompressorHelper::GetNTimeBits()-1))
392 Float_t dist = sqrt( pow(xyzCross[1]-xyz[1],2) + pow(xyzCross[2]-xyz[2],2) );
395 closest = &points[j];
400 if(closest) //there was a cluster assigned
403 Float_t xyz[3] = {closest->fX,closest->fY,closest->fZ};
404 AliHLTTPCTransform::Slice2Sector(lastSlice,padrow,sector,row);
405 AliHLTTPCTransform::Local2Raw(xyzCross,sector,row);
407 AliHLTTPCTransform::Local2Raw(xyz,sector,row);
409 AliHLTTPCTransform::Global2Raw(xyz,sector,row);
412 track->SetPadHit(padrow,xyzCross[1]);
413 track->SetTimeHit(padrow,xyzCross[2]);
415 Float_t angle = track->GetCrossingAngle(padrow,lastSlice);
416 track->SetCrossingAngleLUT(padrow,angle);
417 track->CalculateClusterWidths(padrow,kTRUE);
418 Int_t patch = AliHLTTPCTransform::GetPatch(padrow);
419 Float_t sigmaY2 = closest->fSigmaY2 / pow(AliHLTTPCTransform::GetPadPitchWidth(patch),2);
420 Float_t sigmaZ2 = closest->fSigmaZ2 / pow(AliHLTTPCTransform::GetZWidth(),2);
421 track->SetCluster(padrow,xyz[1],xyz[2],closest->fCharge,sigmaY2,sigmaZ2,3);
422 //AliHLTTPCClusterModel* test1 = track->GetClusterModel(padrow);
423 //HLTInfo("Dsigma %f",test1->fDSigmaY);
427 //IMPORTANT: Set the slice in which cluster is, you need it in AliHLTTPCModelTrack::FillTrack!
428 track->GetClusterModel(padrow)->fSlice=lastSlice;
430 track->GetClusterModel(padrow)->fID=closest->fID;
431 HLTDebug( "Track %d cluster for padrow %d ID: %u (0x%08X) - fSlice: %u", i, padrow,
432 track->GetClusterModel(padrow)->fID, track->GetClusterModel(padrow)->fID,
433 track->GetClusterModel(padrow)->fSlice );
435 //closest->fCharge = 0;//Mark this cluster as used.
436 clustersUsed[closestJ] = true;//Mark this cluster as used.
439 track->SetNClusters(AliHLTTPCTransform::GetNRows());
440 //cout<<"Track was assigned "<<nhits<<" clusters"<<endl;
443 //HLTInfo( "After expansion: track %d with clusters %u", i, nhits);
448 unsigned long AliHLTTPCCompModelConverter::GetOutputModelDataSize() const
450 // see header file for class documentation
451 unsigned long dataSize=0;
452 Short_t ntracks = fOutputTrackArray.GetNTracks();
454 dataSize += sizeof(AliHLTUInt32_t);
456 for(Int_t i=0; i<ntracks; i++)
458 AliHLTTPCModelTrack *track = (AliHLTTPCModelTrack*)fOutputTrackArray.GetCheckedTrack(i);
462 dataSize += sizeof(AliHLTTPCTrackModel)+track->GetNClusters()*sizeof(AliHLTTPCClusterModel);
467 int AliHLTTPCCompModelConverter::OutputModelData( AliHLTUInt8_t* data, unsigned long& /*dataSize*/ ) const
469 // see header file for class documentation
470 unsigned long dataOffset=0;
471 Short_t ntracks = fOutputTrackArray.GetNTracks();
473 AliHLTTPCClusterModel *clusters=0;
474 AliHLTTPCTrackModel *model=0;
476 *(AliHLTUInt32_t*)data = 0; // Write format version number
477 dataOffset += sizeof(AliHLTUInt32_t);
479 for(Int_t i=0; i<ntracks; i++)
481 AliHLTTPCModelTrack *track = (AliHLTTPCModelTrack*)fOutputTrackArray.GetCheckedTrack(i);
486 model = track->GetModel();
488 clusters = track->GetClusters();
491 //HLTInfo( "Track %d clusters: %u", i, (unsigned)track->GetNPresentClusters() );
493 for ( Int_t jj=0; jj<track->GetNClusters(); jj++ )
495 //HLTDebug( " Cluster %d fPresent: %u", jj, (unsigned)clusters[jj].fPresent );
498 memcpy( data+dataOffset, model, sizeof(AliHLTTPCTrackModel) );
499 dataOffset += sizeof(AliHLTTPCTrackModel);
501 memcpy( data+dataOffset, clusters, track->GetNClusters()*sizeof(AliHLTTPCClusterModel) );
502 dataOffset += track->GetNClusters()*sizeof(AliHLTTPCClusterModel);
507 void AliHLTTPCCompModelConverter::SelectRemainingClusters()
509 // see header file for class documentation
510 //Select which remaining clusters to write in addition to the compressed data.
511 //In particular one can here make sure that "important" clusters are not missed:
512 //The offline track finder perform seed finding in the outer padrows;
513 //the first seeding is using pair of points on outermost padrow and
514 //0.125*nrows more rows towards the vertex. The second seeding uses pair
515 //of points on the outermost padrow-0.5*0.125*nrows and 0.125*nrows + 0.5*0.125*nrows
516 //more rows towards the vertex. In order to evaluate the seeds, the track offline
517 //track finder checks whether a certain amount of possible clusters (padrows) is
518 //attached to the track, and then the kalman filtering starts.
519 //To ensure a minimal loss off efficiency, all clusters in this region should be
522 Int_t nrows = AliHLTTPCTransform::GetNRows();
523 Int_t gap=(Int_t)(0.125*nrows), shift=(Int_t)(0.5*gap);
525 for(Int_t slice=0; slice<36; slice++)
527 for(Int_t patch=0; patch<6; patch++)
529 if ( !fClusters[slice][patch] )
531 AliHLTTPCSpacePointData *points = fClusters[slice][patch]->fSpacePoints;
532 bool* clustersUsed = fClusterUsed[slice][patch];
533 for(UInt_t i=0; i<fClusters[slice][patch]->fSpacePointCnt; i++)
535 //if(points[i].fCharge == 0) continue; //Already removed
536 if (clustersUsed[i]) continue; //Already removed
537 Int_t padrow = (Int_t)points[i].fPadRow;
539 //Check the widths (errors) of the cluster, and remove big bastards:
540 Float_t padw = sqrt(points[i].fSigmaY2) / AliHLTTPCTransform::GetPadPitchWidth(AliHLTTPCTransform::GetPatch(padrow));
541 Float_t timew = sqrt(points[i].fSigmaZ2) / AliHLTTPCTransform::GetZWidth();
542 if(padw >= 2.55 || timew >= 2.55)//Because we use 1 byte to store
544 //points[i].fCharge = 0;
545 clustersUsed[i] = true;
549 Float_t xyz[3] = {points[i].fX,points[i].fY,points[i].fZ};
551 AliHLTTPCTransform::Slice2Sector(slice,padrow,sector,row);
552 AliHLTTPCTransform::Global2Raw(xyz,sector,row);
554 if(padrow >= nrows-1-gap-shift) continue;//save all the clusters in this region
556 //if(padrow >= nrows-1-shift) continue;
558 //Save the clusters at the borders:
559 //if(xyz[1] < 3 || xyz[1] >= AliHLTTPCTransform::GetNPads(padrow)-4)
562 //Save clusters on padrows used for offline seeding:
563 if(padrow == nrows - 1 || padrow == nrows - 1 - gap || //First seeding
564 padrow == nrows - 1 - shift || padrow == nrows - 1 - gap - shift) //Second seeding
567 //Cluster did not meet any of the above criteria, so disregard it:
568 //points[i].fCharge = 0;
569 clustersUsed[i] = true;
576 unsigned long AliHLTTPCCompModelConverter::GetRemainingClustersOutputDataSize() const
578 // see header file for class documentation
581 for ( UInt_t slice=0; slice<36; slice++ )
582 for ( UInt_t patch=0; patch<6; patch++ )
584 bool* clustersUsed = fClusterUsed[slice][patch];
585 if ( !clustersUsed || !fClusters[slice][patch] )
587 for ( UInt_t pos=0; pos<fClusters[slice][patch]->fSpacePointCnt; pos++ )
589 if ( !clustersUsed[pos] )
593 return clusterCnt*sizeof(AliHLTTPCClusterModel);
595 const Int_t nrows = AliHLTTPCTransform::GetNRows();
596 Int_t * npoints = new Int_t[nrows];
597 unsigned long dataWritten = 0;
599 dataWritten += sizeof(AliHLTUInt32_t);
601 // FIXME: get rid of hardcoded numbers
602 for(Int_t slice=0; slice<35 && iResult>=0; slice++)
604 for(Int_t patch=0; patch < 6 && iResult>=0; patch++)
606 if ( !fClusters[slice][patch] )
611 AliHLTTPCSpacePointData *points = fClusters[slice][patch]->fSpacePoints;
612 bool* clustersUsed = fClusterUsed[slice][patch];
615 memset(npoints,0,nrows*sizeof(Int_t));
618 for(UInt_t j=0; j<fClusters[slice][patch]->fSpacePointCnt; j++)
620 //if(points[j].fCharge == 0) continue; //has been used
621 if ( clustersUsed[j] ) continue; //has been used
622 if ( !npoints[points[j].fPadRow] )
624 npoints[points[j].fPadRow]++;
631 AliHLTTPCRemainingRow *tempPt=0;
634 Int_t localcounter=0;
636 for(UInt_t j=0; j<fClusters[slice][patch]->fSpacePointCnt; j++)
638 //if(points[j].fCharge == 0) continue; //has been used
639 if ( clustersUsed[j] ) continue; //has been used
641 Int_t padrow = points[j].fPadRow;
642 if(padrow != lastRow)
648 HLTError( "Zero row pointer " );
652 if(localcounter != tempPt->fNClusters)
654 HLTError( "Mismatching clustercounter %lu - %d ",
655 (unsigned long)localcounter, (Int_t)tempPt->fNClusters );
663 size = sizeof(AliHLTTPCRemainingRow) + npoints[padrow]*sizeof(AliHLTTPCRemainingCluster);
664 data = new Byte_t[size];
665 tempPt = reinterpret_cast<AliHLTTPCRemainingRow*>(data);
668 tempPt->fPadRow = padrow;
669 tempPt->fNClusters = npoints[padrow];
672 if(localcounter >= npoints[padrow])
674 HLTError( "Cluster counter out of range: %lu - %lu",
675 (unsigned long)localcounter, (unsigned long)npoints[padrow] );
683 //Write the last row:
693 // FIXME check the caller and propagate an error condition
694 if (iResult<0) return 0;
699 int AliHLTTPCCompModelConverter::GetRemainingClusters( AliHLTUInt8_t* const pTgt, unsigned long& dataSize ) const
701 // see header file for class documentation
704 // FIXME: almost identical code to GetRemainingClustersOutputDataSize
706 const Int_t nrows = AliHLTTPCTransform::GetNRows();
707 Int_t * npoints = new Int_t[nrows];
708 unsigned long dataWritten = 0;
709 AliHLTUInt8_t* writePtr = pTgt;
711 *(AliHLTUInt32_t*)writePtr = 0; // Write format version
712 dataWritten += sizeof(AliHLTUInt32_t);
713 writePtr += sizeof(AliHLTUInt32_t);
715 for(Int_t slice=0; slice<=35 && iResult>=0; slice++)
717 for(Int_t patch=0; patch < 6 && iResult>=0; patch++)
719 if ( !fClusters[slice][patch] )
721 *writePtr = (AliHLTUInt8_t)0;
726 AliHLTTPCSpacePointData *points = fClusters[slice][patch]->fSpacePoints;
727 bool* clustersUsed = fClusterUsed[slice][patch];
730 memset(npoints,0,nrows*sizeof(Int_t));
733 for(UInt_t j=0; j<fClusters[slice][patch]->fSpacePointCnt; j++)
735 //if(points[j].fCharge == 0) continue; //has been used
736 if ( clustersUsed[j] ) continue; //has been used
737 if ( !npoints[points[j].fPadRow] )
739 npoints[points[j].fPadRow]++;
742 *writePtr = (AliHLTUInt8_t)nonZeroRows;
748 AliHLTTPCRemainingRow *tempPt=0;
751 Int_t localcounter=0;
753 for(UInt_t j=0; j<fClusters[slice][patch]->fSpacePointCnt; j++)
755 //if(points[j].fCharge == 0) continue; //has been used
756 if ( clustersUsed[j] ) continue; //has been used
758 Int_t padrow = points[j].fPadRow;
759 if(padrow != lastRow)
765 HLTError( "Zero row pointer " );
769 if(localcounter != tempPt->fNClusters)
771 HLTError( "Mismatching clustercounter %lu - %d ",
772 (unsigned long)localcounter, (Int_t)tempPt->fNClusters );
776 //cout<<"Writing row "<<(int)tempPt->fPadRow<<" with "<<(int)tempPt->fNClusters<<" clusters"<<endl;
777 //fwrite(tempPt,size,1,outfile);
778 if ( dataWritten+size > dataSize )
780 HLTWarning( "Cannot write remaining clusters to output. Data size too large (exceeding %lu bytes)", (unsigned long)dataSize );
784 memcpy( writePtr, tempPt, size );
790 size = sizeof(AliHLTTPCRemainingRow) + npoints[padrow]*sizeof(AliHLTTPCRemainingCluster);
791 data = new Byte_t[size];
792 tempPt = (AliHLTTPCRemainingRow*)data;
795 tempPt->fPadRow = padrow;
796 tempPt->fNClusters = npoints[padrow];
799 if(localcounter >= npoints[padrow])
801 HLTError( "Cluster counter out of range: %lu - %lu",
802 (unsigned long)localcounter, (unsigned long)npoints[padrow] );
807 Float_t xyz[3] = {points[j].fX,points[j].fY,points[j].fZ};
809 AliHLTTPCTransform::Slice2Sector(slice,padrow,sector,row);
811 AliHLTTPCTransform::Local2Raw(xyz,sector,row);
813 AliHLTTPCTransform::Global2Raw(xyz,sector,row);
816 Float_t padw = points[j].fSigmaY2 / pow(AliHLTTPCTransform::GetPadPitchWidth(AliHLTTPCTransform::GetPatch(padrow)),2);
817 Float_t timew = points[j].fSigmaZ2 / pow(AliHLTTPCTransform::GetZWidth(),2);
818 tempPt->fClusters[localcounter].fPad = xyz[1];
819 tempPt->fClusters[localcounter].fTime = xyz[2];
820 tempPt->fClusters[localcounter].fCharge = points[j].fCharge;
821 tempPt->fClusters[localcounter].fSigmaY2 = padw;
822 tempPt->fClusters[localcounter].fSigmaZ2 = timew;
824 tempPt->fClusters[localcounter].fID = points[j].fID;
827 if(fModelAnalysisInstance)
829 if(fModelAnalysisInstance->GetfModelAnalysis())
831 fModelAnalysisInstance->MarkTrashCluster(fClusters[slice][patch], slice, patch);
837 //Write the last row:
838 if ( dataWritten+size > dataSize )
840 HLTWarning( "Cannot write remaining clusters to output. Data size too large (exceeding %lu bytes)", (unsigned long)dataSize );
848 memcpy( writePtr, tempPt, size );
856 dataSize = dataWritten;