]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTAltroChannelSelectorComponent.cxx
robustness
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTAltroChannelSelectorComponent.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  *                  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
30 #include <cassert>
31 #include "AliHLTAltroChannelSelectorComponent.h"
32 #include "AliHLTTPCTransform.h"
33 #include "AliHLTTPCDigitReaderRaw.h"
34 #include "AliHLTTPCDefinitions.h"
35 #include "AliHLTTPCPadArray.h"
36
37 /** ROOT macro for the implementation of ROOT specific class methods */
38 ClassImp(AliHLTAltroChannelSelectorComponent)
39
40 AliHLTAltroChannelSelectorComponent::AliHLTAltroChannelSelectorComponent()
41   :
42   AliHLTProcessor(),
43   fRawreaderMode(0)
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
52 AliHLTAltroChannelSelectorComponent::~AliHLTAltroChannelSelectorComponent()
53 {
54   // see header file for class documentation
55 }
56
57 const char* AliHLTAltroChannelSelectorComponent::GetComponentID()
58 {
59   // see header file for class documentation
60   return "AltroChannelSelector";
61 }
62
63 void 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(AliHLTTPCDefinitions::fgkActivePadsDataType);
69   list.push_back(kAliHLTDataTypeHwAddr16);
70 }
71
72 AliHLTComponentDataType AliHLTAltroChannelSelectorComponent::GetOutputDataType()
73 {
74   // see header file for class documentation
75   return kAliHLTDataTypeDDLRaw|kAliHLTDataOriginTPC;
76 }
77
78 void AliHLTAltroChannelSelectorComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
79 {
80   // see header file for class documentation
81   constBase=0;
82   inputMultiplier=1.0;
83 }
84
85 AliHLTComponent* AliHLTAltroChannelSelectorComponent::Spawn()
86 {
87   // see header file for class documentation
88   return new AliHLTAltroChannelSelectorComponent;
89 }
90
91 int AliHLTAltroChannelSelectorComponent::DoInit(int argc, const char** argv)
92 {
93   // see header file for class documentation
94   int iResult=0;
95   TString argument="";
96   bool bMissingParam=0;
97   for (int i=0; i<argc && iResult>=0; i++) {
98     argument=argv[i];
99     if (argument.IsNull()) continue;
100
101     // -rawreadermode
102     if (argument.CompareTo("-rawreadermode")==0) {
103       if ((bMissingParam=(++i>=argc))) break;
104       int mode=AliHLTTPCDigitReaderRaw::DecodeMode(argv[i]);
105       if (mode<0) {
106         HLTError("invalid rawreadermode specifier '%s'", argv[i]);
107         iResult=-EINVAL;
108       } else {
109         fRawreaderMode=static_cast<unsigned>(mode);
110         // always use the reader in unsorted mode regardless of the
111         // argument 
112         if (fRawreaderMode%2==0) fRawreaderMode++;
113       }
114     } else {
115       iResult=-EINVAL;
116     }
117   }
118
119   if (bMissingParam) {
120     HLTError("missing parameter for argument %s", argument.Data());
121     iResult=-EINVAL;
122   }
123
124   return iResult;
125 }
126
127 int AliHLTAltroChannelSelectorComponent::DoDeinit()
128 {
129   // see header file for class documentation
130   return 0;
131 }
132
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 )
139 {
140   // see header file for class documentation
141   int iResult=0;
142
143   // process the DLL input
144   int blockno=0;
145   const AliHLTComponentBlockData* pDesc=NULL;
146
147   for (pDesc=GetFirstInputBlock(kAliHLTDataTypeDDLRaw|kAliHLTDataOriginTPC); pDesc!=NULL; pDesc=GetNextInputBlock(), blockno++) {
148
149     // search for the active pad information
150     AliHLTTPCPadArray::AliHLTTPCActivePads* pActivePadsArray=NULL;
151     AliHLTUInt16_t* pActiveHwAddressArray=NULL;
152     int iArraySize=0;
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);
160           break;
161         }
162       }
163
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);
169           break;
170         }
171       }
172     }
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);
180       continue;
181     }
182
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);
192     int iSelected=0;
193     int iTotal=0;
194     AliHLTUInt32_t iOutputSize=0;
195     AliHLTUInt32_t iCapacity=size;
196     while (reader.NextAltroBlock()) {
197       iTotal++;
198
199       void* pChannel=NULL;
200       AliHLTUInt16_t hwAddress=~(AliHLTUInt16_t)0;
201       int channelSize=reader.GetAltroChannelRawData(pChannel, hwAddress);
202
203       int active=0;
204       if (pActivePadsArray) {
205         for (; active<iArraySize; active++) {
206           if ((int)pActivePadsArray[active].fRow==reader.GetRow() &&
207               (int)pActivePadsArray[active].fPad==reader.GetPad()) {
208             break;
209           }
210         }
211       } else {
212         for (; active<iArraySize; active++) {
213           if (pActiveHwAddressArray[active]==hwAddress) {
214             break;
215           }
216         }
217       }
218       if (active>=iArraySize) {
219         HLTDebug("ALTRO block Row %d, Pad %d discarded (inactive)", reader.GetRow(), reader.GetPad());
220         continue;
221       }
222
223       iSelected++;
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;
234           } else {
235             HLTError("failed to write RCU trailer of length %d for block %d", rcuTrailerLength, blockno);
236             break;
237           }
238         }
239       }
240       if ((iResult=CopyBlockToEnd(outputPtr, iCapacity, iOutputSize, pChannel, channelSize))>=0) {
241         assert(iResult==channelSize);
242         iOutputSize+=channelSize;
243       } else {
244         HLTError("failed to write ALTRO channel of length %d for block %d", channelSize, blockno);
245         break;
246       }
247     }
248     if (iResult>=0) {
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;
254
255         // set new length of the data block
256         AliHLTUInt32_t* pCdhSize=reinterpret_cast<AliHLTUInt32_t*>(outputPtr+iCapacity-iOutputSize+1);
257         *pCdhSize=iOutputSize;
258
259         // insert block descriptor
260         AliHLTComponentBlockData bd;
261         FillBlockData(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;
268       } else {
269         HLTError("failed to write CDH of length %d for block %d", cdhSize, blockno);
270         break;
271       }
272     }
273     HLTInfo("data block %d (0x%08x): selected %d out of %d ALTRO channels", blockno, pDesc->fSpecification, iSelected, iTotal);
274   }
275
276   if (iResult<0) {
277     outputBlocks.clear();
278   }
279
280   // !!! do not change the size since the output buffer is filled from the end !!!
281
282   return iResult;
283 }
284
285 int AliHLTAltroChannelSelectorComponent::CopyBlockToEnd(AliHLTUInt8_t* pTgt, unsigned capacity, unsigned position, void* pSrc, unsigned size)
286 {
287   int iResult=0;
288   if (pTgt==NULL || pSrc==NULL) return -EINVAL;
289   if (capacity-position<size) return -ENOSPC;
290   
291   memcpy(pTgt+(capacity-position-size), pSrc, size);
292   iResult=size;
293   
294   return iResult;
295 }