]>
Commit | Line | Data |
---|---|---|
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 AliHLTOUTHomerCollection.cxx | |
20 | @author Matthias Richter | |
21 | @date | |
22 | @brief General collection for HLTOUT data in DDL format. | |
23 | */ | |
24 | ||
25 | #include "AliHLTOUTHomerCollection.h" | |
26 | #include "AliHLTHOMERLibManager.h" | |
27 | #include "AliHLTHOMERReader.h" | |
28 | #include "AliRawDataHeader.h" | |
29 | #include "AliHLTEsdManager.h" | |
30 | ||
31 | /** ROOT macro for the implementation of ROOT specific class methods */ | |
32 | ClassImp(AliHLTOUTHomerCollection) | |
33 | ||
34 | AliHLTOUTHomerCollection::AliHLTOUTHomerCollection(int event, AliHLTEsdManager* pEsdManager) | |
35 | : | |
36 | AliHLTOUTHomerBuffer(NULL, 0), | |
37 | fpCurrent(NULL), | |
38 | fEvent(event), | |
39 | fpEsdManager(pEsdManager) | |
40 | { | |
41 | // see header file for class documentation | |
42 | // or | |
43 | // refer to README to build package | |
44 | // or | |
45 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt | |
46 | } | |
47 | ||
48 | const int AliHLTOUTHomerCollection::fgkIdShift=16; | |
49 | ||
50 | AliHLTOUTHomerCollection::~AliHLTOUTHomerCollection() | |
51 | { | |
52 | // see header file for class documentation | |
53 | if (fpManager) { | |
54 | if (fpCurrent) fpManager->DeleteReader(fpCurrent); | |
55 | fpCurrent=NULL; | |
56 | } | |
57 | } | |
58 | ||
59 | int AliHLTOUTHomerCollection::GenerateIndex() | |
60 | { | |
61 | // see header file for class documentation | |
62 | // step through all HLT ddls, create HOMER readers and | |
63 | // scan data block | |
64 | int iResult=0; | |
65 | if (fpManager) { | |
66 | Reset(); | |
67 | // there was a bug in AliDAQ returning the wrong equipment id | |
68 | // for the HLT links. It has been fixed in the trunk on Feb 5th 2008 | |
69 | // and from v4-10-Release (Rev-02). For the moment we select directly | |
70 | // to support older AliRoot versions | |
71 | //Select("HLT"); | |
72 | SelectEquipment(-1,7680, 7689); | |
73 | UChar_t* pSrc=NULL; | |
74 | while (ReadNextData(pSrc) && pSrc!=NULL && iResult>=0) { | |
75 | AliHLTUInt32_t id=(GetEquipmentId()); | |
76 | unsigned int size=GetDataSize(); | |
77 | ||
78 | AliHLTHOMERReader* pReader=OpenReader(pSrc, size); | |
79 | ||
80 | // we use the equipment id to identify the different homer blocks | |
81 | id<<=fgkIdShift; | |
82 | if (pReader) { | |
83 | iResult=ScanReader(pReader, id); | |
84 | fpManager->DeleteReader(pReader); | |
85 | } | |
86 | } | |
87 | } else { | |
88 | iResult=-ENODEV; | |
89 | } | |
90 | return iResult; | |
91 | } | |
92 | ||
93 | int AliHLTOUTHomerCollection::GetDataBuffer(AliHLTUInt32_t index, const AliHLTUInt8_t* &pBuffer, | |
94 | AliHLTUInt32_t& size) | |
95 | { | |
96 | // see header file for class documentation | |
97 | int iResult=0; | |
98 | pBuffer=NULL; | |
99 | size=0; | |
100 | if (fpManager) { | |
101 | Int_t id = Int_t(index>>fgkIdShift); | |
102 | AliHLTUInt32_t blockNo=index&((0x1<<fgkIdShift)-1); | |
103 | ||
104 | // block from the same ddl requested? | |
105 | if (fpCurrent && GetEquipmentId()!=id) { | |
106 | fpManager->DeleteReader(fpCurrent); | |
107 | fpCurrent=NULL; | |
108 | } | |
109 | ||
110 | // open ddl for equipment id and create HOMER reader | |
111 | if (!fpCurrent) { | |
112 | Reset(); | |
113 | SelectEquipment(-1, id, id); | |
114 | UChar_t* pSrc=NULL; | |
115 | if (ReadNextData(pSrc) && pSrc!=NULL) { | |
116 | int srcSize=GetDataSize(); | |
117 | fpCurrent=OpenReader(pSrc, srcSize); | |
118 | if (fpCurrent && fpCurrent->ReadNextEvent()!=0) { | |
119 | iResult=-ENODATA; | |
120 | } | |
121 | } else { | |
122 | iResult=-ENOSYS; | |
123 | } | |
124 | } | |
125 | ||
126 | // get data | |
127 | if (fpCurrent) { | |
128 | AliHLTMonitoringReader* pReader=fpCurrent; | |
129 | if ((pBuffer=static_cast<const AliHLTUInt8_t*>(pReader->GetBlockData(blockNo)))!=NULL) { | |
130 | size=pReader->GetBlockDataLength(blockNo); | |
131 | } else { | |
132 | iResult=-ENOENT; | |
133 | } | |
134 | } | |
135 | } else { | |
136 | iResult=-ENODEV; | |
137 | } | |
138 | return iResult; | |
139 | } | |
140 | ||
141 | AliHLTHOMERReader* AliHLTOUTHomerCollection::OpenReader(UChar_t* pSrc, unsigned int size) | |
142 | { | |
143 | // see header file for class documentation | |
144 | unsigned int offset=sizeof(AliHLTOUTEventHeader); | |
145 | const AliRawDataHeader* pCDH=GetDataHeader(); | |
146 | AliHLTUInt32_t id=(GetEquipmentId()); | |
147 | AliHLTUInt32_t statusFlags=pCDH->GetStatus(); | |
148 | AliHLTOUTEventHeader* pHLTHeader=reinterpret_cast<AliHLTOUTEventHeader*>(pSrc); | |
149 | ||
150 | // consistency check for the block size | |
151 | if (pHLTHeader->fLength>size) { | |
152 | HLTError("can not treat HLT data block %d: size mismatch, header %d, but buffer is %d", id, pHLTHeader->fLength, size); | |
153 | return NULL; | |
154 | } else if (pHLTHeader->fLength<size-3) { | |
155 | // data payload is aligned to 32bit, so there can be a difference by at most 3 bytes | |
156 | HLTWarning("size mismatch in HLT data block %d: header %d, but buffer is %d", id, pHLTHeader->fLength, size); | |
157 | } | |
158 | ||
159 | // determine the offset of the homer block | |
160 | // the HLT header is mandatory, HLT decision and HLT | |
161 | // payload are optional. HLT decision is always before HLT | |
162 | // payload if existent. | |
163 | if (statusFlags&(0x1<<kCDHFlagsHLTDecision)) { | |
164 | // the block contains HLT decision data, this is just | |
165 | // skipped here | |
166 | AliHLTUInt32_t* pDecisionLen=reinterpret_cast<AliHLTUInt32_t*>(pSrc+offset); | |
167 | if ((*pDecisionLen)*sizeof(AliHLTUInt32_t)+offset<size) { | |
168 | // the first 32bit word specifies the number of 32bit words in the | |
169 | // decision block -> +1 for this length word | |
170 | offset+=((*pDecisionLen)+1)*sizeof(AliHLTUInt32_t); | |
171 | } else { | |
172 | HLTWarning("size mismatch: HLT decision block bigger than total block length, skipping ..."); | |
173 | return NULL; | |
174 | } | |
175 | } | |
176 | ||
177 | // check if there is payload | |
178 | if (!(statusFlags&(0x1<<kCDHFlagsHLTPayload))) return NULL; | |
179 | ||
180 | // continue if there is no data left in the buffer | |
181 | if (offset>=pHLTHeader->fLength) { | |
182 | HLTWarning("no HLT payload available, but bit is set, skipping ..."); | |
183 | return NULL; | |
184 | } | |
185 | ||
186 | // check for the HOME descriptor type id | |
187 | AliHLTUInt64_t* pHomerDesc=reinterpret_cast<AliHLTUInt64_t*>(pSrc+offset); | |
188 | if (*(pHomerDesc+kID_64b_Offset) != HOMER_BLOCK_DESCRIPTOR_TYPEID && | |
189 | ByteSwap64(*(pHomerDesc+kID_64b_Offset)) != HOMER_BLOCK_DESCRIPTOR_TYPEID) { | |
190 | HLTWarning("format error: can not find HOMER block descriptor typid, skipping this data block"); | |
191 | return NULL; | |
192 | } | |
193 | ||
194 | AliHLTUInt64_t eventId=pHLTHeader->fEventIDHigh; | |
195 | eventId = eventId<<32; | |
196 | eventId|=pHLTHeader->fEventIDLow; | |
197 | SetEventId(eventId); | |
198 | return fpManager->OpenReaderBuffer(pSrc+offset, pHLTHeader->fLength-offset); | |
199 | } | |
200 | ||
201 | int AliHLTOUTHomerCollection::WriteESD(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size, AliHLTComponentDataType dt, AliESDEvent* tgtesd) const | |
202 | { | |
203 | // see header file for class documentation | |
204 | if (!pBuffer && size<=0) return -EINVAL; | |
205 | int iResult=0; | |
206 | if (fpEsdManager) { | |
207 | fpEsdManager->WriteESD(pBuffer, size, dt, tgtesd, GetCurrentEventNo()); | |
208 | } | |
209 | return iResult; | |
210 | } |