2 //****************************************************************************
3 //* This file is property of and copyright by the ALICE HLT Project *
4 //* ALICE Experiment at CERN, All rights reserved. *
6 //* Primary Authors: Sergey Gorbunov, Torsten Alt *
7 //* Developers: Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de> *
8 //* Torsten Alt <talt@cern.ch> *
9 //* for The ALICE HLT Project. *
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 //****************************************************************************
20 // @file AliHLTTPCHWCFEmulator.cxx
21 // @author Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de>
22 // @author Torsten Alt <talt@cern.ch>
23 // @brief FPGA ClusterFinder Emulator for TPC
27 #include "AliHLTTPCHWCFDataTypes.h"
28 #include "AliHLTTPCHWCFEmulator.h"
29 #include "AliHLTTPCClusterMCData.h"
30 #include "AliHLTTPCHWCFData.h"
39 AliHLTTPCHWCFEmulator::AliHLTTPCHWCFEmulator()
51 AliHLTTPCHWCFEmulator::~AliHLTTPCHWCFEmulator()
56 AliHLTTPCHWCFEmulator::AliHLTTPCHWCFEmulator(const AliHLTTPCHWCFEmulator&)
68 AliHLTTPCHWCFEmulator& AliHLTTPCHWCFEmulator::operator=(const AliHLTTPCHWCFEmulator&)
74 void AliHLTTPCHWCFEmulator::Init( const AliHLTUInt32_t *mapping, AliHLTUInt32_t config )
79 fChannelProcessor.SetDeconvolution( config & 0x1 );
80 fChannelMerger.SetDeconvolution( (config>>1) & 0x1 );
81 fDivisionUnit.SetSinglePadSuppression( (config>>3) & 0x1 );
82 fChannelMerger.SetByPassMerger( (config>>4) & 0x1 );
83 fDivisionUnit.SetClusterLowerLimit( (config>>8) & 0xFF );
84 fChannelProcessor.SetSingleSeqLimit( (config>>16) & 0xFF );
86 fChannelProcessor.SetDebugLevel(fDebug);
87 fChannelMerger.SetDebugLevel(fDebug);
88 fDivisionUnit.SetDebugLevel(fDebug);
92 int AliHLTTPCHWCFEmulator::FindClusters( const AliHLTUInt32_t *rawEvent,
93 AliHLTUInt32_t rawEventSize32,
94 AliHLTUInt32_t *output,
95 AliHLTUInt32_t &outputSize32,
96 const AliHLTTPCClusterMCLabel *mcLabels,
97 AliHLTUInt32_t nMCLabels,
98 AliHLTTPCClusterMCData *outputMC
101 // Loops over all rows finding the clusters
103 AliHLTUInt32_t maxOutputSize32 = outputSize32;
105 if( outputMC ) outputMC->fCount = 0;
106 AliHLTUInt32_t maxNMCLabels = nMCLabels;
107 if( !rawEvent ) return -1;
113 fChannelExtractor.Init( fkMapping, mcLabels, 3*rawEventSize32 );
114 fChannelProcessor.Init();
115 fChannelMerger.Init();
116 fDivisionUnit.Init();
118 // Read the data, word by word
120 for( AliHLTUInt32_t iWord=0; iWord<=rawEventSize32; iWord++ ){
122 const AliHLTTPCHWCFBunch *bunch=0;
123 const AliHLTTPCHWCFClusterFragment *fragment=0;
124 const AliHLTTPCHWCFClusterFragment *candidate=0;
125 const AliHLTTPCHWCFCluster *cluster = 0;
127 if( iWord<rawEventSize32 ) fChannelExtractor.InputStream(ReadBigEndian(rawEvent[iWord]));
128 else fChannelExtractor.InputEndOfData();
130 while( (bunch = fChannelExtractor.OutputStream()) ){
131 fChannelProcessor.InputStream(bunch);
132 while( (fragment = fChannelProcessor.OutputStream() )){
133 fChannelMerger.InputStream( fragment );
134 while( (candidate = fChannelMerger.OutputStream()) ){
135 fDivisionUnit.InputStream(candidate);
136 while( (cluster = fDivisionUnit.OutputStream()) ){
137 if( cluster->fFlag==1 ){
138 if( outputSize32+AliHLTTPCHWCFData::fgkAliHLTTPCHWClusterSize > maxOutputSize32 ){ // No space in the output buffer
142 AliHLTUInt32_t *co = &output[outputSize32];
144 co[i++] = WriteBigEndian(cluster->fRowQ);
145 co[i++] = WriteBigEndian(cluster->fQ);
146 co[i++] = cluster->fP;
147 co[i++] = cluster->fT;
148 co[i++] = cluster->fP2;
149 co[i++] = cluster->fT2;
150 outputSize32+=AliHLTTPCHWCFData::fgkAliHLTTPCHWClusterSize;
151 if( mcLabels && outputMC && outputMC->fCount < maxNMCLabels){
152 outputMC->fLabels[outputMC->fCount++] = cluster->fMC;
155 else if( cluster->fFlag==2 ){
156 if( outputSize32+1 > maxOutputSize32 ){ // No space in the output buffer
160 output[outputSize32++] = cluster->fRowQ;
170 AliHLTUInt32_t AliHLTTPCHWCFEmulator::ReadBigEndian ( AliHLTUInt32_t word )
172 // read the word written in big endian format (lowest byte first)
174 const AliHLTUInt8_t *bytes = reinterpret_cast<const AliHLTUInt8_t *>( &word );
175 AliHLTUInt32_t i[4] = {bytes[0],bytes[1],bytes[2],bytes[3]};
177 return (i[3]<<24) | (i[2]<<16) | (i[1]<<8) | i[0];
180 AliHLTUInt32_t AliHLTTPCHWCFEmulator::WriteBigEndian ( AliHLTUInt32_t word )
182 // write the word in big endian format (least byte first)
184 AliHLTUInt32_t ret = 0;
185 AliHLTUInt8_t *bytes = reinterpret_cast<AliHLTUInt8_t *>( &ret );
186 bytes[0] = (word ) & 0xFF;
187 bytes[1] = (word >> 8) & 0xFF;
188 bytes[2] = (word >> 16) & 0xFF;
189 bytes[3] = (word >> 24) & 0xFF;
193 AliHLTUInt32_t AliHLTTPCHWCFEmulator::CreateConfiguration
195 bool doDeconvTime, bool doDeconvPad, bool doFlowControl,
196 bool doSinglePadSuppression, bool bypassMerger,
197 AliHLTUInt32_t clusterLowerLimit,AliHLTUInt32_t singleSeqLimit
200 // static method to create configuration word
202 AliHLTUInt32_t config = 0;
204 config |= ( (AliHLTUInt32_t)doDeconvTime & 0x1 );
205 config |= ( (AliHLTUInt32_t)doDeconvPad & 0x1 ) << 1;
206 config |= ( (AliHLTUInt32_t)doFlowControl & 0x1 ) << 2;
207 config |= ( (AliHLTUInt32_t)doSinglePadSuppression & 0x1 ) << 3;
208 config |= ( (AliHLTUInt32_t)bypassMerger & 0x1 ) << 4;
209 config |= ( (AliHLTUInt32_t)clusterLowerLimit & 0xFF )<<8;
210 config |= ( (AliHLTUInt32_t)singleSeqLimit & 0xFF )<<16;