a7fb1416d229f5d441da5a5380a01c91d457ccd1
[u/mrichter/AliRoot.git] / HLT / CALO / AliHLTCaloClusterizerComponent.cxx
1 // $Id: AliHLTCaloClusterizerComponent.cxx 36709 2009-11-12 16:57:55Z odjuvsla $
2
3 /**************************************************************************
4  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5  *                                                                        *
6  * Authors: Oystein Djuvsland <oysteind@ift.uib.no>                       *
7  *                                                                        *
8  * Permission to use, copy, modify and distribute this software and its   *
9  * documentation strictly for non-commercial purposes is hereby granted   *
10  * without fee, provided that the above copyright notice appears in all   *
11  * copies and that both the copyright notice and this permission notice   *
12  * appear in the supporting documentation. The authors make no claims     *
13  * about the suitability of this software for any purpose. It is          *
14  * provided "as is" without express or implied warranty.                  *
15  **************************************************************************/
16
17 #include "AliHLTCaloClusterizerComponent.h"
18 #include "AliHLTCaloClusterizer.h"
19 #include "AliHLTCaloClusterAnalyser.h"
20 #include "AliHLTCaloRecPointDataStruct.h"
21 #include "AliHLTCaloRecPointHeaderStruct.h"
22 #include "AliHLTCaloDigitDataStruct.h"
23 #include "AliHLTCaloDigitContainerDataStruct.h"
24 #include "AliHLTCaloDefinitions.h"
25 #include "AliHLTCaloClusterDataStruct.h"
26 #include "AliHLTCaloRecoParamHandler.h"
27 #include "TString.h"
28
29 /** @file   AliHLTCaloClusterizerComponent.cxx
30     @author Oystein Djuvsland
31     @date
32     @brief  A clusterizer component for PHOS HLT
33 */
34
35 // see header file for class documentation
36 // or
37 // refer to README to build package
38 // or
39 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
40
41 ClassImp(AliHLTCaloClusterizerComponent);
42
43 AliHLTCaloClusterizerComponent::AliHLTCaloClusterizerComponent(TString det):
44         AliHLTCaloProcessor(),
45         AliHLTCaloConstantsHandler(det),
46         fDataOrigin('\0'),
47         fAnalyserPtr(0),
48         fRecoParamsPtr(0),
49         fClusterizerPtr(0),
50         fDigitsPointerArray(0),
51         fOutputDigitsArray(0),
52         fDigitCount(0),
53         fCopyDigitsToOuput(kTRUE)
54 {
55     //See headerfile for documentation
56
57
58
59 }
60
61 AliHLTCaloClusterizerComponent::~AliHLTCaloClusterizerComponent()
62 {
63     //See headerfile for documentation
64     if(fAnalyserPtr)
65     {
66       delete fAnalyserPtr;
67       fAnalyserPtr = 0;
68     }
69 }
70
71 int
72 AliHLTCaloClusterizerComponent::DoEvent(const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks,
73                                         AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t& size,
74                                         std::vector<AliHLTComponentBlockData>& outputBlocks)
75 {
76     //See headerfile for documentation
77
78     if (blocks == 0) return 0;
79
80     UInt_t offset           = 0;
81     UInt_t mysize           = 0;
82     Int_t nRecPoints        = 0;
83     Int_t nDigits           = 0;
84     Int_t digCount          = 0;
85
86     UInt_t availableSize = size;
87     AliHLTUInt8_t* outBPtr;
88     outBPtr = outputPtr;
89     const AliHLTComponentBlockData* iter = 0;
90     unsigned long ndx;
91
92     UInt_t specification = 0;
93
94     AliHLTCaloDigitDataStruct *digitDataPtr = 0;
95
96     // Adding together all the digits, should be put in standalone method
97     for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
98     {
99         iter = blocks+ndx;
100
101         if (iter->fDataType == (AliHLTCaloDefinitions::fgkDigitDataType|fDataOrigin))
102         {
103
104             // Update the number of digits
105             nDigits = iter->fSize/sizeof(AliHLTCaloDigitDataStruct);
106             availableSize -= iter->fSize;
107
108             specification = specification|iter->fSpecification;
109
110             digitDataPtr = reinterpret_cast<AliHLTCaloDigitDataStruct*>(iter->fPtr);
111
112             // We copy the digits to the digit buffer used by the clusterizer
113             // This is convinient since we want the digits from all DDLs before starting
114             // Could be changed if this is a bottle neck.
115             for (Int_t i = 0; i < nDigits; i++)
116             {
117                // If we have a digit based on a low gain channel, but there has been no high gain channel, 
118                // we shouldn't use it since we are then very sensitive to noise (e.g. for PHOS 1 LG ADC count = 40 MeV)
119                if(digitDataPtr->fHgPresent)
120                {
121                 fDigitsPointerArray[digCount] = digitDataPtr;
122                 digCount++;
123                 digitDataPtr++;
124                }
125             }
126         }
127     }
128
129     if (digCount > 0)
130     {
131
132         AliHLTCaloClusterHeaderStruct* caloClusterHeaderPtr = reinterpret_cast<AliHLTCaloClusterHeaderStruct*>(outBPtr);
133         caloClusterHeaderPtr->fNDigits = digCount;
134
135         outBPtr += sizeof(AliHLTCaloClusterHeaderStruct);
136         mysize += sizeof(AliHLTCaloClusterHeaderStruct);
137
138         // Sort the digit pointers
139 //      qsort(fDigitsPointerArray, digCount, sizeof(AliHLTCaloDigitDataStruct*), CompareDigits);
140
141
142         if (fCopyDigitsToOuput)
143         {
144             // Copy the digits to the output
145             fOutputDigitsArray = reinterpret_cast<AliHLTCaloDigitDataStruct*>(outBPtr);
146
147             for (Int_t n = 0; n < digCount; n++)
148             {
149                 memcpy(outBPtr, fDigitsPointerArray[n], sizeof(AliHLTCaloDigitDataStruct));
150                 //fOutputDigitsArray[n] = reinterpret_cast<AliHLTCaloDigitDataStruct*>(outBPtr);
151                 outBPtr = outBPtr + sizeof(AliHLTCaloDigitDataStruct);
152             }
153         }
154         
155         // Update the size of the output we have used, needs to be removed if we don't push the digits
156         mysize += digCount*sizeof(AliHLTCaloDigitDataStruct);
157
158         // Do the clusterisation
159         nRecPoints = fClusterizerPtr->ClusterizeEvent(digCount);
160
161         HLTDebug("Number of rec points found: %d", nRecPoints);
162
163         // Give the cluster output to the analyser
164         fAnalyserPtr->SetCaloClusterData(reinterpret_cast<AliHLTCaloClusterDataStruct*>(outBPtr));
165
166         // Give the rec points to the analyser (input)
167         fAnalyserPtr->SetRecPointArray(fClusterizerPtr->GetRecPoints(), nRecPoints);
168
169         // Give the digits to the analyser
170         //fAnalyserPtr->SetDigitDataArray(fOutputDigitsArray);
171         fAnalyserPtr->SetDigitDataArray(fDigitsPointerArray);
172
173         // Then we create the clusters
174         Int_t nClusters = fAnalyserPtr->CreateClusters(nRecPoints, size, mysize);
175
176         if (nClusters < 0)
177         {
178             HLTError("Error in clusterisation");
179             caloClusterHeaderPtr->fNClusters = 0;
180         }
181         else
182         {
183             caloClusterHeaderPtr->fNClusters = nClusters;
184         }
185
186         HLTDebug("Number of clusters: %d", nRecPoints);
187
188         AliHLTComponentBlockData bd;
189         FillBlockData( bd );
190         bd.fOffset = offset;
191         bd.fSize = mysize;
192         bd.fDataType = kAliHLTDataTypeCaloCluster | fDataOrigin;
193         bd.fSpecification = specification;
194         outputBlocks.push_back( bd );
195     }
196
197     size = mysize;
198
199     return 0;
200 }
201
202 int
203 AliHLTCaloClusterizerComponent::Reconfigure(const char* cdbEntry, const char* /*chainId*/)
204 {
205     // see header file for class documentation
206
207     const char* path="HLT/ConfigPHOS/ClusterizerComponent";
208
209     if (cdbEntry) path = cdbEntry;
210
211     return ConfigureFromCDBTObjString(cdbEntry);
212 }
213
214 int
215 AliHLTCaloClusterizerComponent::ScanConfigurationArgument(int argc, const char **argv)
216 {
217     //See header file for documentation
218
219     if (argc <= 0) return 0;
220
221     int i=0;
222
223     TString argument=argv[i];
224
225     if (argument.CompareTo("-digitthreshold") == 0)
226     {
227         if (++i >= argc) return -EPROTO;
228         argument = argv[i];
229         fClusterizerPtr->SetEmcMinEnergyThreshold(argument.Atof());
230         return 1;
231     }
232
233     if (argument.CompareTo("-recpointthreshold") == 0)
234     {
235         if (++i >= argc) return -EPROTO;
236         argument = argv[i];
237         fClusterizerPtr->SetEmcClusteringThreshold(argument.Atof());
238         return 1;
239     }
240
241     if (argument.CompareTo("-cutonsinglecell") == 0)
242     {
243         if (++i >= argc) return -EPROTO;
244         argument = argv[i];
245         fAnalyserPtr->SetCutOnSingleCellClusters(true, argument.Atof());
246         return 1;
247     }
248     if (argument.CompareTo("-sortbyposition") == 0)
249     {
250         fClusterizerPtr->SetSortDigitsByPosition();
251         return 1;
252     }
253
254     return 0;
255 }
256
257 int
258 AliHLTCaloClusterizerComponent::DoInit(int argc, const char** argv )
259 {
260     //See headerfile for documentation
261
262     fDigitsPointerArray = new AliHLTCaloDigitDataStruct*[fCaloConstants->GetNXCOLUMNSMOD()*fCaloConstants->GetNZROWSMOD()];
263
264     fClusterizerPtr->SetDigitArray(fDigitsPointerArray);
265
266     fClusterizerPtr->SetSortDigitsByEnergy();
267
268     fAnalyserPtr = new AliHLTCaloClusterAnalyser();
269
270     if (fCaloConstants->GetDETNAME() == "PHOS")
271     {
272         fAnalyserPtr->SetClusterType(kPHOSCluster);
273     }
274     else if (fCaloConstants->GetDETNAME() == "EMCAL")
275     {
276         fAnalyserPtr->SetClusterType(kEMCALClusterv1);
277     }
278     else
279     {
280         fAnalyserPtr->SetClusterType(kUndef);
281     }
282     InitialiseGeometry();
283     if (fRecoParamsPtr)
284     {
285         if (!fRecoParamsPtr->GetParametersFromCDB())
286         {
287             fAnalyserPtr->SetRecoParamHandler(fRecoParamsPtr);
288             fClusterizerPtr->SetEmcClusteringThreshold(fRecoParamsPtr->GetRecPointThreshold());
289             fClusterizerPtr->SetEmcMinEnergyThreshold(fRecoParamsPtr->GetRecPointMemberThreshold());
290             HLTInfo("Setting thresholds for clusterizer: %f, %f", fRecoParamsPtr->GetRecPointThreshold(), fRecoParamsPtr->GetRecPointMemberThreshold());
291         }
292     }
293     //
294
295     //  const char *path = "HLT/ConfigPHOS/ClusterizerComponent";
296
297     //  ConfigureFromCDBTObjString(path);
298
299     for (int i = 0; i < argc; i++)
300     {
301         ScanConfigurationArgument(i, argv);
302     }
303
304     return 0;
305 }
306 int AliHLTCaloClusterizerComponent::DoDeinit()
307 {
308     // See header file for documentation
309     if (fDigitsPointerArray)
310     {
311         delete []  fDigitsPointerArray;
312         fDigitsPointerArray = 0;
313     }
314     if (fClusterizerPtr)
315     {
316         delete fClusterizerPtr;
317         fClusterizerPtr = 0;
318     }
319     if (fAnalyserPtr)
320     {
321         delete fAnalyserPtr;
322         fAnalyserPtr = 0;
323     }
324     return 0;
325 }
326
327 Int_t
328 AliHLTCaloClusterizerComponent::CompareDigits(const void *dig0, const void *dig1)
329 {
330     // See header file for documentation
331     return (*((AliHLTCaloDigitDataStruct**)(dig0)))->fID - (*((AliHLTCaloDigitDataStruct**)(dig1)))->fID;
332
333     //return (*((AliHLTCaloDigitDataStruct**)(dig0)))->fID - (*((AliHLTCaloDigitDataStruct**)(dig1)))->fID;
334 }