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: Matthias Richter <Matthias.Richter@ift.uib.no> *
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 AliHLTAltroChannelSelectorComponent.cxx
20 @author Matthias Richter
22 @brief A filter/selective readout component for TPC Altro data. */
24 // see header file for class documentation
26 // refer to README to build package
28 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
31 #include "AliHLTAltroChannelSelectorComponent.h"
32 #include "AliHLTTPCTransform.h"
33 #include "AliHLTTPCDigitReaderRaw.h"
34 #include "AliHLTTPCDefinitions.h"
35 #include "AliHLTTPCPadArray.h"
37 /** ROOT macro for the implementation of ROOT specific class methods */
38 ClassImp(AliHLTAltroChannelSelectorComponent)
40 AliHLTAltroChannelSelectorComponent::AliHLTAltroChannelSelectorComponent()
45 // see header file for class documentation
47 // refer to README to build package
49 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
52 AliHLTAltroChannelSelectorComponent::~AliHLTAltroChannelSelectorComponent()
54 // see header file for class documentation
57 const char* AliHLTAltroChannelSelectorComponent::GetComponentID()
59 // see header file for class documentation
60 return "AltroChannelSelector";
63 void AliHLTAltroChannelSelectorComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
65 // see header file for class documentation
67 list.push_back(kAliHLTDataTypeDDLRaw|kAliHLTDataOriginTPC);
68 list.push_back(AliHLTTPCDefinitions::fgkActivePadsDataType);
69 list.push_back(kAliHLTDataTypeHwAddr16);
72 AliHLTComponentDataType AliHLTAltroChannelSelectorComponent::GetOutputDataType()
74 // see header file for class documentation
75 return kAliHLTDataTypeDDLRaw|kAliHLTDataOriginTPC;
78 void AliHLTAltroChannelSelectorComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
80 // see header file for class documentation
85 AliHLTComponent* AliHLTAltroChannelSelectorComponent::Spawn()
87 // see header file for class documentation
88 return new AliHLTAltroChannelSelectorComponent;
91 int AliHLTAltroChannelSelectorComponent::DoInit(int argc, const char** argv)
93 // see header file for class documentation
97 for (int i=0; i<argc && iResult>=0; i++) {
99 if (argument.IsNull()) continue;
102 if (argument.CompareTo("-rawreadermode")==0) {
103 if ((bMissingParam=(++i>=argc))) break;
104 int mode=AliHLTTPCDigitReaderRaw::DecodeMode(argv[i]);
106 HLTError("invalid rawreadermode specifier '%s'", argv[i]);
109 fRawreaderMode=static_cast<unsigned>(mode);
110 // always use the reader in unsorted mode regardless of the
112 if (fRawreaderMode%2==0) fRawreaderMode++;
120 HLTError("missing parameter for argument %s", argument.Data());
127 int AliHLTAltroChannelSelectorComponent::DoDeinit()
129 // see header file for class documentation
133 int AliHLTAltroChannelSelectorComponent::DoEvent(const AliHLTComponentEventData& evtData,
134 const AliHLTComponentBlockData* blocks,
135 AliHLTComponentTriggerData& /*trigData*/,
136 AliHLTUInt8_t* outputPtr,
137 AliHLTUInt32_t& size,
138 AliHLTComponentBlockDataList& outputBlocks )
140 // see header file for class documentation
143 // process the DLL input
145 const AliHLTComponentBlockData* pDesc=NULL;
147 for (pDesc=GetFirstInputBlock(kAliHLTDataTypeDDLRaw|kAliHLTDataOriginTPC); pDesc!=NULL; pDesc=GetNextInputBlock(), blockno++) {
149 // search for the active pad information
150 AliHLTTPCPadArray::AliHLTTPCActivePads* pActivePadsArray=NULL;
151 AliHLTUInt16_t* pActiveHwAddressArray=NULL;
153 for (int i=0; i<(int)evtData.fBlockCnt; i++ ) {
154 const AliHLTComponentBlockData* iter=NULL;
155 // search for selection data of row/pad type
156 for (iter=GetFirstInputBlock(AliHLTTPCDefinitions::fgkActivePadsDataType); iter!=NULL; iter=GetNextInputBlock()) {
157 if (iter->fSpecification==pDesc->fSpecification) {
158 pActivePadsArray=reinterpret_cast<AliHLTTPCPadArray::AliHLTTPCActivePads*>(iter->fPtr);
159 iArraySize=iter->fSize/sizeof(AliHLTTPCPadArray::AliHLTTPCActivePads);
164 // search for selection data of hw address type
165 for (iter=GetFirstInputBlock(kAliHLTDataTypeHwAddr16); iter!=NULL; iter=GetNextInputBlock()) {
166 if (iter->fSpecification==pDesc->fSpecification) {
167 pActiveHwAddressArray=reinterpret_cast<AliHLTUInt16_t*>(iter->fPtr);
168 iArraySize=iter->fSize/sizeof(AliHLTUInt16_t);
173 if (pActivePadsArray==NULL && pActiveHwAddressArray==NULL) {
174 HLTWarning("no block of type %s or %s for specification 0x%08x available, data block unchanged",
175 DataType2Text(AliHLTTPCDefinitions::fgkActivePadsDataType).c_str(),
176 DataType2Text(kAliHLTDataTypeHwAddr16).c_str(),
177 pDesc->fSpecification);
178 // forward the whole block
179 outputBlocks.push_back(*pDesc);
183 int part=AliHLTTPCDefinitions::GetMinPatchNr(*pDesc);
184 assert(part==AliHLTTPCDefinitions::GetMaxPatchNr(*pDesc));
185 int slice=AliHLTTPCDefinitions::GetMinSliceNr(*pDesc);
186 assert(slice==AliHLTTPCDefinitions::GetMaxSliceNr(*pDesc));
187 int firstRow=AliHLTTPCTransform::GetFirstRow(part);
188 int lastRow=AliHLTTPCTransform::GetLastRow(part);
189 AliHLTTPCDigitReaderRaw reader(fRawreaderMode);
190 HLTDebug("init reader %p size %d", pDesc->fPtr,pDesc->fSize);
191 reader.InitBlock(pDesc->fPtr,pDesc->fSize,firstRow,lastRow,part,slice);
194 AliHLTUInt32_t iOutputSize=0;
195 AliHLTUInt32_t iCapacity=size;
196 while (reader.NextAltroBlock()) {
200 AliHLTUInt16_t hwAddress=~(AliHLTUInt16_t)0;
201 int channelSize=reader.GetAltroChannelRawData(pChannel, hwAddress);
204 if (pActivePadsArray) {
205 for (; active<iArraySize; active++) {
206 if ((int)pActivePadsArray[active].fRow==reader.GetRow() &&
207 (int)pActivePadsArray[active].fPad==reader.GetPad()) {
212 for (; active<iArraySize; active++) {
213 if (pActiveHwAddressArray[active]==hwAddress) {
218 if (active>=iArraySize) {
219 HLTDebug("ALTRO block Row %d, Pad %d discarded (inactive)", reader.GetRow(), reader.GetPad());
224 HLTDebug("ALTRO block hwAddress 0x%08x Row/Pad %d/%d selected (active), size %d", hwAddress, reader.GetRow(), reader.GetPad(), channelSize);
225 if (channelSize>0 && pChannel!=NULL) {
226 if (iOutputSize==0) {
227 // first add the RCU trailer
228 unsigned rcuTrailerLength=reader.GetRCUDataBlockLength();
229 AliHLTUInt8_t* pSrc=reinterpret_cast<AliHLTUInt8_t*>(pDesc->fPtr);
230 pSrc+=pDesc->fSize-rcuTrailerLength;
231 if ((iResult=CopyBlockToEnd(outputPtr, iCapacity, iOutputSize, pSrc, rcuTrailerLength))>=0) {
232 assert(iResult==rcuTrailerLength);
233 iOutputSize+=rcuTrailerLength;
235 HLTError("failed to write RCU trailer of length %d for block %d", rcuTrailerLength, blockno);
240 if ((iResult=CopyBlockToEnd(outputPtr, iCapacity, iOutputSize, pChannel, channelSize))>=0) {
241 assert(iResult==channelSize);
242 iOutputSize+=channelSize;
244 HLTError("failed to write ALTRO channel of length %d for block %d", channelSize, blockno);
249 // write the common data header
250 int cdhSize=reader.GetCommonDataHeaderSize();
251 if ((iResult=CopyBlockToEnd(outputPtr, iCapacity, iOutputSize, pDesc->fPtr, cdhSize))>=0) {
252 assert(iResult==cdhSize);
253 iOutputSize+=cdhSize;
255 // set new length of the data block
256 AliHLTUInt32_t* pCdhSize=reinterpret_cast<AliHLTUInt32_t*>(outputPtr+iCapacity-iOutputSize+1);
257 *pCdhSize=iOutputSize;
259 // insert block descriptor
260 AliHLTComponentBlockData bd;
262 bd.fOffset=iCapacity-iOutputSize;
263 bd.fSize=iOutputSize;
264 bd.fDataType=pDesc->fDataType;
265 bd.fSpecification=pDesc->fSpecification;
266 outputBlocks.push_back(bd);
267 iCapacity-=iOutputSize;
269 HLTError("failed to write CDH of length %d for block %d", cdhSize, blockno);
273 HLTInfo("data block %d (0x%08x): selected %d out of %d ALTRO channels", blockno, pDesc->fSpecification, iSelected, iTotal);
277 outputBlocks.clear();
280 // !!! do not change the size since the output buffer is filled from the end !!!
285 int AliHLTAltroChannelSelectorComponent::CopyBlockToEnd(AliHLTUInt8_t* pTgt, unsigned capacity, unsigned position, void* pSrc, unsigned size)
288 if (pTgt==NULL || pSrc==NULL) return -EINVAL;
289 if (capacity-position<size) return -ENOSPC;
291 memcpy(pTgt+(capacity-position-size), pSrc, size);