bugfix: handling of multiple output blocks introduced fake blocks
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTAltroChannelSelectorComponent.cxx
CommitLineData
3e6ec852 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 * for The ALICE HLT Project. *
9 * *
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 **************************************************************************/
18
19/** @file AliHLTAltroChannelSelectorComponent.cxx
20 @author Matthias Richter
21 @date
22 @brief A filter/selective readout component for TPC Altro data. */
23
24// see header file for class documentation
25// or
26// refer to README to build package
27// or
28// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
29
e1440dab 30#include <cassert>
3e6ec852 31#include "AliHLTAltroChannelSelectorComponent.h"
e1440dab 32#include "AliHLTTPCTransform.h"
33#include "AliHLTTPCDigitReaderRaw.h"
34#include "AliHLTTPCDefinitions.h"
35#include "AliHLTTPCPadArray.h"
3e6ec852 36
37/** ROOT macro for the implementation of ROOT specific class methods */
38ClassImp(AliHLTAltroChannelSelectorComponent)
39
40AliHLTAltroChannelSelectorComponent::AliHLTAltroChannelSelectorComponent()
41 :
e1440dab 42 AliHLTProcessor(),
43 fRawreaderMode(0)
3e6ec852 44{
45 // see header file for class documentation
46 // or
47 // refer to README to build package
48 // or
49 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
50}
51
52AliHLTAltroChannelSelectorComponent::~AliHLTAltroChannelSelectorComponent()
53{
54 // see header file for class documentation
55}
56
57const char* AliHLTAltroChannelSelectorComponent::GetComponentID()
58{
59 // see header file for class documentation
60 return "AltroChannelSelector";
61}
62
63void AliHLTAltroChannelSelectorComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
64{
65 // see header file for class documentation
66 list.clear();
67 list.push_back(kAliHLTDataTypeDDLRaw|kAliHLTDataOriginTPC);
68 //list.push_back(channel list);
69}
70
71AliHLTComponentDataType AliHLTAltroChannelSelectorComponent::GetOutputDataType()
72{
73 // see header file for class documentation
74 return kAliHLTDataTypeDDLRaw|kAliHLTDataOriginTPC;
75}
76
77void AliHLTAltroChannelSelectorComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
78{
79 // see header file for class documentation
80 constBase=0;
81 inputMultiplier=1.0;
82}
83
84AliHLTComponent* AliHLTAltroChannelSelectorComponent::Spawn()
85{
86 // see header file for class documentation
87 return new AliHLTAltroChannelSelectorComponent;
88}
89
90int AliHLTAltroChannelSelectorComponent::DoInit(int argc, const char** argv)
91{
92 // see header file for class documentation
93 int iResult=0;
94 TString argument="";
e1440dab 95 bool bMissingParam=0;
3e6ec852 96 for (int i=0; i<argc && iResult>=0; i++) {
97 argument=argv[i];
98 if (argument.IsNull()) continue;
99
e1440dab 100 // -rawreadermode
101 if (argument.CompareTo("-rawreadermode")==0) {
102 if ((bMissingParam=(++i>=argc))) break;
103 int mode=AliHLTTPCDigitReaderRaw::DecodeMode(argv[i]);
104 if (mode<0) {
105 HLTError("invalid rawreadermode specifier '%s'", argv[i]);
106 iResult=-EINVAL;
107 } else {
108 fRawreaderMode=static_cast<unsigned>(mode);
109 }
3e6ec852 110 } else {
111 iResult=-EINVAL;
112 }
113 }
114
e1440dab 115 if (bMissingParam) {
116 HLTError("missing parameter for argument %s", argument.Data());
117 iResult=-EINVAL;
118 }
119
3e6ec852 120 return iResult;
121}
122
123int AliHLTAltroChannelSelectorComponent::DoDeinit()
124{
125 // see header file for class documentation
126 return 0;
127}
128
129int AliHLTAltroChannelSelectorComponent::DoEvent(const AliHLTComponentEventData& evtData,
130 const AliHLTComponentBlockData* blocks,
131 AliHLTComponentTriggerData& /*trigData*/,
132 AliHLTUInt8_t* outputPtr,
133 AliHLTUInt32_t& size,
134 AliHLTComponentBlockDataList& outputBlocks )
135{
136 // see header file for class documentation
137 int iResult=0;
138
e1440dab 139 // process the DLL input
140 int blockno=0;
141 for (; blockno<(int)evtData.fBlockCnt; blockno++ ) {
142 if (blocks[blockno].fDataType != (kAliHLTDataTypeDDLRaw|kAliHLTDataOriginTPC)) continue;
143
144 // search for the active pad information
145 AliHLTTPCPadArray::AliHLTTPCActivePads* pActivePadsArray=NULL;
146 int iNofActivePads=0;
147 for (int i=0; i<(int)evtData.fBlockCnt; i++ ) {
148 if (blocks[i].fDataType == AliHLTTPCDefinitions::fgkActivePadsDataType &&
149 blocks[i].fSpecification==blocks[blockno].fSpecification) {
150 pActivePadsArray=reinterpret_cast<AliHLTTPCPadArray::AliHLTTPCActivePads*>(blocks[i].fPtr);
151 iNofActivePads=blocks[i].fSize/sizeof(AliHLTTPCPadArray::AliHLTTPCActivePads);
152 }
153 }
154 if (pActivePadsArray==NULL) {
155 HLTWarning("no block of type %s for specification 0x%08x available, data block unchanged",
156 DataType2Text(AliHLTTPCDefinitions::fgkActivePadsDataType).c_str(),
157 blocks[blockno].fSpecification);
158 // forward the whole block
159 outputBlocks.push_back(blocks[blockno]);
160 continue;
161 }
162
163 int part=AliHLTTPCDefinitions::GetMinPatchNr(blocks[blockno]);
164 assert(part==AliHLTTPCDefinitions::GetMaxPatchNr(blocks[blockno]));
165 int slice=AliHLTTPCDefinitions::GetMinSliceNr(blocks[blockno]);
166 assert(slice==AliHLTTPCDefinitions::GetMaxSliceNr(blocks[blockno]));
167 int firstRow=AliHLTTPCTransform::GetFirstRow(part);
168 int lastRow=AliHLTTPCTransform::GetLastRow(part);
169 AliHLTTPCDigitReaderRaw reader(fRawreaderMode);
170 reader.InitBlock(blocks[blockno].fPtr,blocks[blockno].fSize,firstRow,lastRow,part,slice);
171 AliHLTUInt32_t iOutputSize=0;
172 AliHLTUInt32_t iCapacity=size;
173 while (reader.NextAltroBlock()) {
174 int active=0;
175 for (; active<iNofActivePads; active++) {
854ef340 176 if ((int)pActivePadsArray[active].fRow==reader.GetRow() &&
177 (int)pActivePadsArray[active].fPad==reader.GetPad()) {
e1440dab 178 break;
179 }
180 }
181 if (active>=iNofActivePads) {
182 HLTDebug("ALTRO block Row %d, Pad %d discarded (inactive)", reader.GetRow(), reader.GetPad());
183 continue;
184 }
185
186 void* pChannel=NULL;
187 AliHLTUInt16_t hwAddress=~(AliHLTUInt16_t)0;
188 int channelSize=reader.GetAltroChannelRawData(pChannel, hwAddress);
189 HLTDebug("ALTRO block Row/Pad %d/%d selected (active)", reader.GetRow(), reader.GetPad());
190 if (channelSize>0 && pChannel!=NULL) {
191 if (iOutputSize==0) {
192 // first add the RCU trailer
193 unsigned rcuTrailerLength=reader.GetRCUDataBlockLength();
194 AliHLTUInt8_t* pSrc=reinterpret_cast<AliHLTUInt8_t*>(blocks[blockno].fPtr);
195 pSrc+=blocks[blockno].fSize;
196 if ((iResult=CopyBlockToEnd(outputPtr, iCapacity, iOutputSize, pSrc, rcuTrailerLength))>=0) {
197 assert(iResult==rcuTrailerLength);
198 iOutputSize+=rcuTrailerLength;
199 } else {
200 HLTError("failed to writer RCU trailer of length %d for block %d", rcuTrailerLength, blockno);
201 break;
202 }
203 }
204 }
205 if ((iResult=CopyBlockToEnd(outputPtr, iCapacity, iOutputSize, pChannel, channelSize))>=0) {
206 assert(iResult==channelSize);
207 iOutputSize+=channelSize;
208 } else {
209 HLTError("failed to writer ALTRO channel of length %d for block %d", channelSize, blockno);
210 break;
211 }
212 }
213 if (iResult>=0) {
214 // write the common data header
215 int cdhSize=reader.GetCommonDataHeaderSize();
216 if ((iResult=CopyBlockToEnd(outputPtr, iCapacity, iOutputSize, blocks[blockno].fPtr, cdhSize))>=0) {
217 assert(iResult==cdhSize);
218 iOutputSize+=cdhSize;
219
220 // set new length of the data block
221 AliHLTUInt32_t* pCdhSize=reinterpret_cast<AliHLTUInt32_t*>(outputPtr+iCapacity-iOutputSize+1);
222 *pCdhSize=iOutputSize;
223
224 // insert block descriptor
225 AliHLTComponentBlockData bd;
226 FillBlockData(bd);
227 bd.fOffset=iCapacity-iOutputSize;
228 bd.fSize=iOutputSize;
229 bd.fDataType=blocks[blockno].fDataType;
230 bd.fSpecification=blocks[blockno].fSpecification;
231 outputBlocks.push_back(bd);
232 iCapacity-=iOutputSize;
233 } else {
234 HLTError("failed to write CDH of length %d for block %d", cdhSize, blockno);
235 break;
236 }
237 }
3e6ec852 238 }
239
e1440dab 240 if (iResult<0) {
241 outputBlocks.clear();
3e6ec852 242 }
243
e1440dab 244 // !!! do not change the size since the output buffer is filled from the end !!!
245
246 return iResult;
247}
248
249int AliHLTAltroChannelSelectorComponent::CopyBlockToEnd(AliHLTUInt8_t* pTgt, unsigned capacity, unsigned position, void* pSrc, unsigned size)
250{
251 int iResult=0;
252 if (pTgt==NULL || pSrc==NULL) return -EINVAL;
253 if (capacity-position<size) return -ENOSPC;
254
255 memcpy(pTgt+(capacity-position-size), pSrc, size);
256 iResult=size;
257
3e6ec852 258 return iResult;
259}