]>
Commit | Line | Data |
---|---|---|
c9537879 | 1 | /************************************************************************** |
2 | * This file is property of and copyright by the ALICE HLT Project * | |
3 | * All rights reserved. * | |
4 | * * | |
5 | * Primary Authors: * | |
6 | * Artur Szostak <artursz@iafrica.com> * | |
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 | ||
1d8ae082 | 17 | // $Id: $ |
c9537879 | 18 | |
19 | /// | |
20 | /// @file AliHLTMUONDecisionComponent.cxx | |
21 | /// @author Artur Szostak <artursz@iafrica.com> | |
22 | /// @date 30 April 2008 | |
23 | /// @brief Implementation of the decision component for dimuon HLT triggering. | |
24 | /// | |
25 | // class documentation is in the header file. | |
26 | ||
27 | #include "AliHLTMUONDecisionComponent.h" | |
28 | #include "AliHLTMUONConstants.h" | |
29 | #include "AliHLTMUONUtils.h" | |
30 | #include "AliHLTMUONCalculations.h" | |
31 | #include "AliHLTMUONDataBlockReader.h" | |
32 | #include "AliHLTMUONDataBlockWriter.h" | |
33 | #include "AliCDBEntry.h" | |
34 | #include "AliCDBManager.h" | |
35 | #include "TObjString.h" | |
36 | #include "TString.h" | |
37 | #include <cstdlib> | |
38 | #include <cstring> | |
39 | #include <cerrno> | |
40 | #include <cmath> | |
41 | #include <new> | |
42 | ||
43 | ||
44 | // Helper type for memory allocation. | |
45 | typedef const AliHLTMUONMansoTrackStruct* AliHLTMUONMansoTrackStructP; | |
46 | ||
47 | ||
48 | ClassImp(AliHLTMUONDecisionComponent); | |
49 | ||
50 | ||
51 | AliHLTMUONDecisionComponent::AliHLTMUONDecisionComponent() : | |
154cba94 | 52 | AliHLTMUONProcessor(), |
c9537879 | 53 | fMaxTracks(1), |
54 | fTrackCount(0), | |
55 | fTracks(new AliHLTMUONMansoTrackStructP[fMaxTracks]), | |
56 | fLowPtCut(1.), // 1 GeV/c cut | |
57 | fHighPtCut(2.), // 2 GeV/c cut | |
58 | fLowMassCut(2.5), // 2.7 GeV/c^2 cut | |
59 | fHighMassCut(7.), // 8 GeV/c^2 cut | |
2b7af22a | 60 | fWarnForUnexpecedBlock(false), |
2b7af22a | 61 | fLowPtCutSet(false), |
62 | fHighPtCutSet(false), | |
63 | fLowMassCutSet(false), | |
cf7b241a | 64 | fHighMassCutSet(false), |
65 | fFillSinglesDetail(false), | |
66 | fFillPairsDetail(false) | |
c9537879 | 67 | { |
68 | /// | |
69 | /// Default constructor. | |
70 | /// | |
71 | } | |
72 | ||
73 | ||
74 | AliHLTMUONDecisionComponent::~AliHLTMUONDecisionComponent() | |
75 | { | |
76 | /// | |
77 | /// Default destructor deletes the fTracks array. | |
78 | /// | |
79 | ||
80 | assert(fTracks != NULL); | |
81 | delete [] fTracks; | |
82 | } | |
83 | ||
84 | ||
85 | const char* AliHLTMUONDecisionComponent::GetComponentID() | |
86 | { | |
87 | /// | |
88 | /// Inherited from AliHLTComponent. Returns the component ID. | |
89 | /// | |
90 | ||
91 | return AliHLTMUONConstants::DecisionComponentId(); | |
92 | } | |
93 | ||
94 | ||
ffb64d3e | 95 | void AliHLTMUONDecisionComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list) |
c9537879 | 96 | { |
97 | /// | |
98 | /// Inherited from AliHLTProcessor. Returns the list of expected input data types. | |
99 | /// | |
100 | ||
101 | assert( list.empty() ); | |
102 | list.push_back( AliHLTMUONConstants::MansoTracksBlockDataType() ); | |
103 | } | |
104 | ||
105 | ||
106 | AliHLTComponentDataType AliHLTMUONDecisionComponent::GetOutputDataType() | |
107 | { | |
108 | /// Inherited from AliHLTComponent. Returns kAliHLTMultipleDataType | |
109 | /// refer to GetOutputDataTypes for all returned data types. | |
110 | ||
111 | return kAliHLTMultipleDataType; | |
112 | } | |
113 | ||
114 | ||
115 | int AliHLTMUONDecisionComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list) | |
116 | { | |
117 | /// Inherited from AliHLTComponent. Returns the output data types. | |
118 | ||
119 | assert( list.empty() ); | |
120 | list.push_back( AliHLTMUONConstants::SinglesDecisionBlockDataType() ); | |
121 | list.push_back( AliHLTMUONConstants::PairsDecisionBlockDataType() ); | |
62a08849 | 122 | return list.size(); |
c9537879 | 123 | } |
124 | ||
125 | ||
126 | void AliHLTMUONDecisionComponent::GetOutputDataSize( | |
127 | unsigned long& constBase, double& inputMultiplier | |
128 | ) | |
129 | { | |
130 | /// | |
131 | /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size. | |
132 | /// | |
133 | ||
134 | constBase = sizeof(AliHLTMUONSinglesDecisionBlockStruct); | |
979076f8 | 135 | constBase += sizeof(AliHLTMUONPairsDecisionBlockStruct) + 1024*1024; |
210736fa | 136 | inputMultiplier = 100; |
c9537879 | 137 | } |
138 | ||
139 | ||
140 | AliHLTComponent* AliHLTMUONDecisionComponent::Spawn() | |
141 | { | |
142 | /// | |
143 | /// Inherited from AliHLTComponent. Creates a new object instance. | |
144 | /// | |
145 | ||
146 | return new AliHLTMUONDecisionComponent; | |
147 | } | |
148 | ||
149 | ||
150 | int AliHLTMUONDecisionComponent::DoInit(int argc, const char** argv) | |
151 | { | |
152 | /// | |
153 | /// Inherited from AliHLTComponent. | |
154 | /// Parses the command line parameters and initialises the component. | |
155 | /// | |
156 | ||
157 | HLTInfo("Initialising dHLT trigger decision component."); | |
158 | ||
ffb64d3e | 159 | // Inherit the parents functionality. |
160 | int result = AliHLTMUONProcessor::DoInit(argc, argv); | |
161 | if (result != 0) return result; | |
162 | ||
c9537879 | 163 | fWarnForUnexpecedBlock = false; |
2b7af22a | 164 | fLowPtCutSet = false; |
165 | fHighPtCutSet = false; | |
166 | fLowMassCutSet = false; | |
167 | fHighMassCutSet = false; | |
cf7b241a | 168 | fFillSinglesDetail = true; |
169 | fFillPairsDetail = true; | |
2b7af22a | 170 | |
c9537879 | 171 | for (int i = 0; i < argc; i++) |
172 | { | |
ffb64d3e | 173 | if (ArgumentAlreadyHandled(i, argv[i])) continue; |
174 | ||
c9537879 | 175 | if (strcmp( argv[i], "-lowptcut" ) == 0) |
176 | { | |
2b7af22a | 177 | if (fLowPtCutSet) |
ffc1a6f6 | 178 | { |
179 | HLTWarning("Low pT cut parameter was already specified." | |
180 | " Will replace previous value given by -lowptcut." | |
181 | ); | |
182 | } | |
183 | ||
c9537879 | 184 | if (argc <= i+1) |
185 | { | |
186 | HLTError("The value for the low pT cut was not specified."); | |
187 | return -EINVAL; | |
188 | } | |
189 | ||
190 | char* cpErr = NULL; | |
191 | double num = strtod(argv[i+1], &cpErr); | |
192 | if (cpErr == NULL or *cpErr != '\0') | |
193 | { | |
194 | HLTError("Cannot convert '%s' to a floating point number.", argv[i+1]); | |
195 | return -EINVAL; | |
196 | } | |
197 | fLowPtCut = (AliHLTFloat32_t)num; | |
2b7af22a | 198 | fLowPtCutSet = true; |
c9537879 | 199 | |
200 | i++; | |
201 | continue; | |
202 | } | |
203 | ||
204 | if (strcmp( argv[i], "-highptcut" ) == 0) | |
205 | { | |
2b7af22a | 206 | if (fHighPtCutSet) |
ffc1a6f6 | 207 | { |
208 | HLTWarning("High pT cut parameter was already specified." | |
209 | " Will replace previous value given by -highptcut." | |
210 | ); | |
211 | } | |
212 | ||
c9537879 | 213 | if (argc <= i+1) |
214 | { | |
215 | HLTError("The value for the high pT cut was not specified."); | |
216 | return -EINVAL; | |
217 | } | |
218 | ||
219 | char* cpErr = NULL; | |
220 | double num = strtod(argv[i+1], &cpErr); | |
221 | if (cpErr == NULL or *cpErr != '\0') | |
222 | { | |
223 | HLTError("Cannot convert '%s' to a floating point number.", argv[i+1]); | |
224 | return -EINVAL; | |
225 | } | |
226 | fHighPtCut = (AliHLTFloat32_t)num; | |
2b7af22a | 227 | fHighPtCutSet = true; |
c9537879 | 228 | |
229 | i++; | |
230 | continue; | |
231 | } | |
232 | ||
233 | if (strcmp( argv[i], "-lowmasscut" ) == 0) | |
234 | { | |
2b7af22a | 235 | if (fLowMassCutSet) |
ffc1a6f6 | 236 | { |
237 | HLTWarning("Low invariant mass cut parameter was already specified." | |
238 | " Will replace previous value given by -lowmasscut." | |
239 | ); | |
240 | } | |
241 | ||
c9537879 | 242 | if (argc <= i+1) |
243 | { | |
244 | HLTError("The value for the low invariant mass cut was not specified."); | |
245 | return -EINVAL; | |
246 | } | |
247 | ||
248 | char* cpErr = NULL; | |
249 | double num = strtod(argv[i+1], &cpErr); | |
250 | if (cpErr == NULL or *cpErr != '\0') | |
251 | { | |
252 | HLTError("Cannot convert '%s' to a floating point number.", argv[i+1]); | |
253 | return -EINVAL; | |
254 | } | |
255 | fLowMassCut = (AliHLTFloat32_t)num; | |
2b7af22a | 256 | fLowMassCutSet = true; |
c9537879 | 257 | |
258 | i++; | |
259 | continue; | |
260 | } | |
261 | ||
262 | if (strcmp( argv[i], "-highmasscut" ) == 0) | |
263 | { | |
2b7af22a | 264 | if (fHighMassCutSet) |
ffc1a6f6 | 265 | { |
266 | HLTWarning("High invariant mass cut parameter was already specified." | |
267 | " Will replace previous value given by -highmasscut." | |
268 | ); | |
269 | } | |
270 | ||
c9537879 | 271 | if (argc <= i+1) |
272 | { | |
273 | HLTError("The value for the high invariant mass cut was not specified."); | |
274 | return -EINVAL; | |
275 | } | |
276 | ||
277 | char* cpErr = NULL; | |
278 | double num = strtod(argv[i+1], &cpErr); | |
279 | if (cpErr == NULL or *cpErr != '\0') | |
280 | { | |
281 | HLTError("Cannot convert '%s' to a floating point number.", argv[i+1]); | |
282 | return -EINVAL; | |
283 | } | |
284 | fHighMassCut = (AliHLTFloat32_t)num; | |
2b7af22a | 285 | fHighMassCutSet = true; |
c9537879 | 286 | |
287 | i++; | |
288 | continue; | |
289 | } | |
290 | ||
291 | if (strcmp(argv[i], "-warn_on_unexpected_block") == 0) | |
292 | { | |
293 | fWarnForUnexpecedBlock = true; | |
294 | continue; | |
295 | } | |
cf7b241a | 296 | |
297 | if (strcmp( argv[i], "-no_singles_detail" ) == 0) | |
298 | { | |
299 | fFillSinglesDetail = false; | |
300 | continue; | |
301 | } | |
302 | ||
303 | if (strcmp( argv[i], "-no_pairs_detail" ) == 0) | |
304 | { | |
305 | fFillPairsDetail = false; | |
306 | continue; | |
307 | } | |
c9537879 | 308 | |
309 | HLTError("Unknown option '%s'.", argv[i]); | |
310 | return -EINVAL; | |
311 | } | |
312 | ||
ffb64d3e | 313 | if (not DelaySetup()) |
2b7af22a | 314 | { |
315 | // Read cut parameters from CDB if they were not specified on the command line. | |
316 | if (not fLowPtCutSet or not fHighPtCutSet or not fLowMassCutSet or not fHighMassCutSet) | |
317 | { | |
318 | HLTInfo("Loading cut parameters from CDB."); | |
4e22efc4 | 319 | result = ReadConfigFromCDB( |
2b7af22a | 320 | not fLowPtCutSet, not fHighPtCutSet, |
321 | not fLowMassCutSet, not fHighMassCutSet | |
322 | ); | |
323 | if (result != 0) return result; | |
324 | } | |
325 | else | |
326 | { | |
327 | // Print the debug messages here since ReadConfigFromCDB does not get called, | |
328 | // in-which the debug messages would have been printed. | |
329 | HLTDebug("Using the following cut parameters:"); | |
330 | HLTDebug(" Low pT cut = %f GeV/c", fLowPtCut); | |
331 | HLTDebug(" High pT cut = %f GeV/c", fHighPtCut); | |
332 | HLTDebug(" Low invariant mass cut = %f GeV/c^2", fLowMassCut); | |
333 | HLTDebug(" High invariant mass cut = %f GeV/c^2", fHighMassCut); | |
334 | } | |
335 | } | |
c9537879 | 336 | |
337 | return 0; | |
338 | } | |
339 | ||
340 | ||
341 | int AliHLTMUONDecisionComponent::DoDeinit() | |
342 | { | |
343 | /// | |
344 | /// Inherited from AliHLTComponent. Performs a cleanup of the component. | |
345 | /// | |
346 | ||
347 | HLTInfo("Deinitialising dHLT trigger decision component."); | |
348 | return 0; | |
349 | } | |
350 | ||
351 | ||
352 | int AliHLTMUONDecisionComponent::Reconfigure(const char* cdbEntry, const char* componentId) | |
353 | { | |
354 | /// Inherited from AliHLTComponent. Reconfigures the component from CDB. | |
355 | ||
2b7af22a | 356 | /// Inherited from AliHLTComponent. This method will reload CDB configuration |
357 | /// entries for this component from the CDB. | |
358 | /// \param cdbEntry If this is NULL or equals "HLT/ConfigMUON/DecisionComponent" | |
359 | /// then new configuration parameters are loaded, otherwise nothing is done. | |
360 | /// \param componentId The name of the component in the current chain. | |
361 | ||
362 | bool givenConfigPath = strcmp(cdbEntry, AliHLTMUONConstants::DecisionComponentCDBPath()) == 0; | |
363 | ||
364 | if (cdbEntry == NULL or givenConfigPath) | |
c9537879 | 365 | { |
2b7af22a | 366 | HLTInfo("Reading new configuration entries from CDB for component '%s'.", componentId); |
367 | int result = ReadConfigFromCDB(); | |
368 | if (result != 0) return result; | |
c9537879 | 369 | } |
2b7af22a | 370 | |
371 | return 0; | |
372 | } | |
373 | ||
374 | ||
375 | int AliHLTMUONDecisionComponent::ReadPreprocessorValues(const char* modules) | |
376 | { | |
377 | /// Inherited from AliHLTComponent. | |
378 | /// Updates the configuration of this component if HLT or ALL has been | |
379 | /// specified in the 'modules' list. | |
380 | ||
381 | TString mods = modules; | |
382 | if (mods.Contains("ALL")) | |
383 | { | |
384 | return Reconfigure(NULL, GetComponentID()); | |
385 | } | |
386 | if (mods.Contains("HLT")) | |
387 | { | |
388 | return Reconfigure(AliHLTMUONConstants::DecisionComponentCDBPath(), GetComponentID()); | |
389 | } | |
390 | return 0; | |
c9537879 | 391 | } |
392 | ||
393 | ||
394 | int AliHLTMUONDecisionComponent::DoEvent( | |
395 | const AliHLTComponentEventData& evtData, | |
396 | const AliHLTComponentBlockData* blocks, | |
ffb64d3e | 397 | AliHLTComponentTriggerData& trigData, |
c9537879 | 398 | AliHLTUInt8_t* outputPtr, |
399 | AliHLTUInt32_t& size, | |
ffb64d3e | 400 | AliHLTComponentBlockDataList& outputBlocks |
c9537879 | 401 | ) |
402 | { | |
403 | /// | |
404 | /// Inherited from AliHLTProcessor. Processes the new event data. | |
405 | /// | |
406 | ||
2b7af22a | 407 | // Initialise the cut parameters from CDB if we were requested to |
408 | // initialise only when the first event was received. | |
ffb64d3e | 409 | if (DelaySetup()) |
2b7af22a | 410 | { |
411 | // Load the cut paramters from CDB if they have not been given | |
412 | // on the command line. | |
413 | if (not fLowPtCutSet or not fHighPtCutSet or not fLowMassCutSet or not fHighMassCutSet) | |
414 | { | |
415 | HLTInfo("Loading cut parameters from CDB."); | |
416 | int result = ReadConfigFromCDB( | |
417 | not fLowPtCutSet, not fHighPtCutSet, | |
418 | not fLowMassCutSet, not fHighMassCutSet | |
419 | ); | |
420 | if (result != 0) return result; | |
421 | } | |
422 | ||
ffb64d3e | 423 | DoneDelayedSetup(); |
2b7af22a | 424 | } |
425 | ||
c9537879 | 426 | AliHLTUInt32_t specification = 0; // Contains the output data block spec bits. |
427 | ||
428 | // Loop over all input blocks in the event with track data and add pointers | |
429 | // to the tracks into the tracks array. These will be used later by the | |
430 | // trigger algorithm to get to the individual tracks. | |
431 | fTrackCount = 0; // reset number of tracks in array. | |
432 | for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++) | |
433 | { | |
450e0b36 | 434 | HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.", |
435 | n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fPtr, blocks[n].fSize | |
436 | ); | |
437 | ||
c9537879 | 438 | if (blocks[n].fDataType == AliHLTMUONConstants::MansoTracksBlockDataType()) |
439 | { | |
440 | // Build up the specification which indicates what DDLs | |
441 | // contributed to the output data. | |
442 | specification |= blocks[n].fSpecification; | |
443 | ||
3240b3ce | 444 | AliHLTMUONMansoTracksBlockReader inblock(blocks[n].fPtr, blocks[n].fSize); |
ffb64d3e | 445 | if (not BlockStructureOk(inblock)) |
446 | { | |
447 | if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks); | |
448 | continue; | |
449 | } | |
c9537879 | 450 | |
451 | for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++) | |
452 | { | |
453 | int result = AddTrack(&inblock[i]); | |
454 | if (result != 0) | |
455 | { | |
ffb64d3e | 456 | if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks); |
c9537879 | 457 | size = 0; // Important to tell framework that nothing was generated. |
458 | return result; | |
459 | } | |
460 | } | |
461 | } | |
450e0b36 | 462 | else |
c9537879 | 463 | { |
464 | // Log a message indicating that we got a data block that we | |
465 | // do not know how to handle. | |
c9537879 | 466 | if (fWarnForUnexpecedBlock) |
450e0b36 | 467 | HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X", |
468 | DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification | |
c9537879 | 469 | ); |
4e22efc4 | 470 | #ifdef __DEBUG |
c9537879 | 471 | else |
450e0b36 | 472 | HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X", |
473 | DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification | |
c9537879 | 474 | ); |
4e22efc4 | 475 | #endif |
c9537879 | 476 | } |
477 | } | |
478 | ||
479 | // Now we can create our two new output data blocks for the single tracks | |
480 | // and track pairs. | |
481 | AliHLTMUONSinglesDecisionBlockWriter singlesBlock(outputPtr, size); | |
482 | ||
483 | if (not singlesBlock.InitCommonHeader()) | |
484 | { | |
485 | Logging(kHLTLogError, | |
486 | "AliHLTMUONDecisionComponent::DoEvent", | |
487 | "Buffer overflow", | |
488 | "The buffer is only %d bytes in size. We need a minimum of" | |
489 | " %d bytes for the singles output data block.", | |
490 | size, sizeof(AliHLTMUONSinglesDecisionBlockWriter::HeaderType) | |
491 | ); | |
ffb64d3e | 492 | if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks); |
c9537879 | 493 | size = 0; // Important to tell framework that nothing was generated. |
494 | return -ENOBUFS; | |
495 | } | |
cf7b241a | 496 | |
497 | AliHLTUInt32_t numOfTracks = fTrackCount; | |
498 | if (not fFillSinglesDetail) numOfTracks = 0; | |
499 | if (not singlesBlock.SetNumberOfEntries(numOfTracks)) | |
c9537879 | 500 | { |
501 | AliHLTUInt32_t bytesneeded = sizeof(AliHLTMUONSinglesDecisionBlockWriter::HeaderType) | |
cf7b241a | 502 | + numOfTracks * sizeof(AliHLTMUONSinglesDecisionBlockWriter::ElementType); |
c9537879 | 503 | HLTError("The buffer is only %d bytes in size. We need a minimum of" |
504 | " %d bytes for the singles output data block.", | |
505 | size, bytesneeded | |
506 | ); | |
ffb64d3e | 507 | if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks); |
c9537879 | 508 | size = 0; // Important to tell framework that nothing was generated. |
509 | return -ENOBUFS; | |
510 | } | |
511 | ||
512 | AliHLTMUONPairsDecisionBlockWriter pairsBlock( | |
513 | outputPtr + singlesBlock.BytesUsed(), | |
514 | size - singlesBlock.BytesUsed() | |
515 | ); | |
516 | ||
517 | if (not pairsBlock.InitCommonHeader()) | |
518 | { | |
519 | Logging(kHLTLogError, | |
520 | "AliHLTMUONDecisionComponent::DoEvent", | |
521 | "Buffer overflow", | |
522 | "The buffer is only %d bytes in size. We need a minimum of" | |
523 | " %d bytes for the pairs output data block.", | |
524 | size, | |
525 | sizeof(AliHLTMUONPairsDecisionBlockWriter::HeaderType) + singlesBlock.BytesUsed() | |
526 | ); | |
ffb64d3e | 527 | if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks); |
c9537879 | 528 | size = 0; // Important to tell framework that nothing was generated. |
529 | return -ENOBUFS; | |
530 | } | |
cf7b241a | 531 | |
c9537879 | 532 | AliHLTUInt32_t numOfPairs = fTrackCount * (fTrackCount-1) / 2; |
cf7b241a | 533 | if (not fFillPairsDetail) numOfPairs = 0; |
c9537879 | 534 | if (not pairsBlock.SetNumberOfEntries(numOfPairs)) |
535 | { | |
536 | AliHLTUInt32_t bytesneeded = sizeof(AliHLTMUONPairsDecisionBlockWriter::HeaderType) | |
8a9e21f6 | 537 | + numOfPairs * sizeof(AliHLTMUONPairsDecisionBlockWriter::ElementType) |
c9537879 | 538 | + singlesBlock.BytesUsed(); |
539 | HLTError("The buffer is only %d bytes in size. We need a minimum of" | |
540 | " %d bytes for the pairs output data block.", | |
541 | size, bytesneeded | |
542 | ); | |
ffb64d3e | 543 | if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks); |
c9537879 | 544 | size = 0; // Important to tell framework that nothing was generated. |
545 | return -ENOBUFS; | |
546 | } | |
547 | ||
548 | ApplyTriggerAlgorithm( | |
549 | singlesBlock.BlockHeader(), | |
550 | singlesBlock.GetArray(), | |
551 | pairsBlock.BlockHeader(), | |
552 | pairsBlock.GetArray() | |
553 | ); | |
554 | ||
555 | AliHLTComponentBlockData sbd; | |
556 | FillBlockData(sbd); | |
557 | sbd.fPtr = outputPtr; | |
558 | sbd.fOffset = 0; | |
559 | sbd.fSize = singlesBlock.BytesUsed(); | |
560 | sbd.fDataType = AliHLTMUONConstants::SinglesDecisionBlockDataType(); | |
561 | sbd.fSpecification = specification; | |
562 | outputBlocks.push_back(sbd); | |
563 | size = singlesBlock.BytesUsed(); | |
564 | ||
565 | AliHLTComponentBlockData pbd; | |
566 | FillBlockData(pbd); | |
567 | pbd.fPtr = outputPtr; | |
568 | pbd.fOffset = singlesBlock.BytesUsed(); | |
569 | pbd.fSize = pairsBlock.BytesUsed(); | |
570 | pbd.fDataType = AliHLTMUONConstants::PairsDecisionBlockDataType(); | |
571 | pbd.fSpecification = specification; | |
572 | outputBlocks.push_back(pbd); | |
573 | size += pairsBlock.BytesUsed(); | |
574 | ||
575 | return 0; | |
576 | } | |
577 | ||
578 | ||
579 | int AliHLTMUONDecisionComponent::ReadConfigFromCDB( | |
c9537879 | 580 | bool setLowPtCut, bool setHighPtCut, |
581 | bool setLowMassCut, bool setHighMassCut | |
582 | ) | |
583 | { | |
584 | /// Reads the cut parameters from the CDB. | |
2b7af22a | 585 | /// \param setLowPtCut Indicates if the low pT cut should be set (default true). |
586 | /// \param setHighPtCut Indicates if the high pT cut should be set (default true). | |
587 | /// \param setLowMassCut Indicates if the low invariant mass cut should be set (default true). | |
588 | /// \param setHighMassCut Indicates if the high invariant mass cut should be set (default true). | |
589 | /// \return 0 is returned on success and a non-zero value to indicate failure. | |
c9537879 | 590 | |
591 | assert(AliCDBManager::Instance() != NULL); | |
592 | ||
593 | const char* pathToEntry = AliHLTMUONConstants::DecisionComponentCDBPath(); | |
c9537879 | 594 | |
ffc1a6f6 | 595 | TMap* map = NULL; |
596 | int result = FetchTMapFromCDB(pathToEntry, map); | |
597 | if (result != 0) return result; | |
c9537879 | 598 | |
599 | if (setLowPtCut) | |
600 | { | |
ffc1a6f6 | 601 | Double_t value = 0; |
602 | result = GetFloatFromTMap(map, "lowptcut", value, pathToEntry, "low pT cut"); | |
603 | if (result != 0) return result; | |
604 | fLowPtCut = (AliHLTFloat32_t) value; | |
c9537879 | 605 | } |
606 | ||
607 | if (setHighPtCut) | |
608 | { | |
ffc1a6f6 | 609 | Double_t value = 0; |
610 | result = GetFloatFromTMap(map, "highptcut", value, pathToEntry, "high pT cut"); | |
611 | if (result != 0) return result; | |
612 | fHighPtCut = (AliHLTFloat32_t) value; | |
c9537879 | 613 | } |
614 | ||
615 | if (setLowMassCut) | |
616 | { | |
ffc1a6f6 | 617 | Double_t value = 0; |
618 | result = GetFloatFromTMap(map, "lowmasscut", value, pathToEntry, "low invariant mass cut"); | |
619 | if (result != 0) return result; | |
620 | fLowMassCut = (AliHLTFloat32_t) value; | |
c9537879 | 621 | } |
622 | ||
623 | if (setHighMassCut) | |
624 | { | |
ffc1a6f6 | 625 | Double_t value = 0; |
626 | result = GetFloatFromTMap(map, "highmasscut", value, pathToEntry, "high invariant mass cut"); | |
627 | if (result != 0) return result; | |
628 | fHighMassCut = (AliHLTFloat32_t) value; | |
c9537879 | 629 | } |
630 | ||
2b7af22a | 631 | HLTDebug("Using the following cut parameters:"); |
632 | HLTDebug(" Low pT cut = %f GeV/c", fLowPtCut); | |
633 | HLTDebug(" High pT cut = %f GeV/c", fHighPtCut); | |
634 | HLTDebug(" Low invariant mass cut = %f GeV/c^2", fLowMassCut); | |
635 | HLTDebug(" High invariant mass cut = %f GeV/c^2", fHighMassCut); | |
636 | ||
c9537879 | 637 | return 0; |
638 | } | |
639 | ||
640 | ||
641 | int AliHLTMUONDecisionComponent::AddTrack(const AliHLTMUONMansoTrackStruct* track) | |
642 | { | |
643 | /// Adds a track to the internal track list for future reference in | |
644 | /// ApplyTriggerAlgorithm when we actually apply the trigger algorithm. | |
645 | ||
646 | assert(fTrackCount <= fMaxTracks); | |
647 | assert(fTracks != NULL); | |
648 | ||
649 | if (fTrackCount == fMaxTracks) | |
650 | { | |
651 | // Buffer full so we need to resize it. | |
652 | const AliHLTMUONMansoTrackStruct** tmp = NULL; | |
653 | try | |
654 | { | |
655 | tmp = new AliHLTMUONMansoTrackStructP[fMaxTracks+1]; | |
656 | } | |
657 | catch (const std::bad_alloc&) | |
658 | { | |
659 | HLTError("Could not allocate more memory for the track array."); | |
660 | return -ENOMEM; | |
661 | } | |
662 | ||
663 | // Copy over the exisiting data and then delete the old array. | |
664 | memcpy(tmp, fTracks, sizeof(AliHLTMUONMansoTrackStructP)*fTrackCount); | |
665 | delete [] fTracks; | |
666 | fTracks = tmp; | |
667 | fMaxTracks = fMaxTracks+1; | |
668 | } | |
669 | ||
670 | fTracks[fTrackCount] = track; | |
671 | fTrackCount++; | |
672 | return 0; | |
673 | } | |
674 | ||
675 | ||
cf7b241a | 676 | int AliHLTMUONDecisionComponent::ApplyTriggerAlgorithm( |
c9537879 | 677 | AliHLTMUONSinglesDecisionBlockStruct& singlesHeader, |
678 | AliHLTMUONTrackDecisionStruct* singlesDecision, | |
679 | AliHLTMUONPairsDecisionBlockStruct& pairsHeader, | |
680 | AliHLTMUONPairDecisionStruct* pairsDecision | |
681 | ) | |
682 | { | |
683 | /// This method applies the dHLT trigger decision algorithm to all the | |
684 | /// tracks found in the input data. | |
cf7b241a | 685 | /// @return zero on success and -ENOMEM if out of memory. |
c9537879 | 686 | |
687 | // Zero the trigger counters for single tracks. | |
688 | singlesHeader.fNlowPt = 0; | |
689 | singlesHeader.fNhighPt = 0; | |
690 | ||
691 | // Zero the trigger counters for pairs. | |
692 | pairsHeader.fNunlikeAnyPt = 0; | |
693 | pairsHeader.fNunlikeLowPt = 0; | |
694 | pairsHeader.fNunlikeHighPt = 0; | |
695 | pairsHeader.fNlikeAnyPt = 0; | |
696 | pairsHeader.fNlikeLowPt = 0; | |
697 | pairsHeader.fNlikeHighPt = 0; | |
698 | pairsHeader.fNmassAny = 0; | |
699 | pairsHeader.fNmassLow = 0; | |
700 | pairsHeader.fNmassHigh = 0; | |
cf7b241a | 701 | |
702 | // Allocate a temporary memory buffer for the calculated pT values if | |
703 | // we are not storing them to shared memory as part of the new block. | |
704 | AliHLTFloat32_t* ptValues = NULL; | |
705 | if (not fFillSinglesDetail) | |
706 | { | |
707 | try | |
708 | { | |
709 | ptValues = new AliHLTFloat32_t[fTrackCount]; | |
710 | } | |
711 | catch(const std::bad_alloc&) | |
712 | { | |
713 | HLTError("Could not allocate memory buffer for pT values."); | |
714 | return -ENOMEM; | |
715 | } | |
716 | } | |
c9537879 | 717 | |
718 | // For the single tracks we check if a track has pT larger than either | |
719 | // the low or high pT cut. If it does then we increment the appropriate | |
720 | // counters in the header. | |
721 | for (AliHLTUInt32_t n = 0; n < fTrackCount; n++) | |
722 | { | |
723 | const AliHLTMUONMansoTrackStruct* track = fTracks[n]; | |
c9537879 | 724 | |
725 | bool passedHighPtCut = false; | |
726 | bool passedLowPtCut = false; | |
727 | ||
728 | AliHLTFloat32_t pt = sqrt(track->fPx * track->fPx + track->fPy * track->fPy); | |
729 | ||
730 | if (pt > fHighPtCut) | |
731 | { | |
732 | passedHighPtCut = true; | |
87e62032 | 733 | singlesHeader.fNhighPt++; |
c9537879 | 734 | } |
735 | if (pt > fLowPtCut) | |
736 | { | |
737 | passedLowPtCut = true; | |
87e62032 | 738 | singlesHeader.fNlowPt++; |
c9537879 | 739 | } |
740 | ||
cf7b241a | 741 | if (fFillSinglesDetail) |
742 | { | |
743 | AliHLTMUONTrackDecisionStruct& decision = singlesDecision[n]; | |
744 | decision.fTrackId = track->fId; | |
745 | decision.fTriggerBits = AliHLTMUONUtils::PackTrackDecisionBits( | |
746 | passedHighPtCut, passedLowPtCut | |
747 | ); | |
748 | decision.fPt = pt; | |
749 | } | |
750 | else | |
751 | { | |
752 | ptValues[n] = pt; | |
753 | } | |
c9537879 | 754 | } |
755 | ||
756 | // Now we generate all the possible pairs of tracks and fill in the | |
757 | // trigger information. This will consist of calculating the invariant | |
758 | // mass for the pair, checking if it passes the low or high mass cut | |
759 | // and incrementing the appropriate statistics. | |
760 | AliHLTUInt32_t currentPair = 0; | |
761 | for (AliHLTUInt32_t i = 0; i < fTrackCount; i++) | |
762 | for (AliHLTUInt32_t j = i+1; j < fTrackCount; j++) | |
763 | { | |
764 | const AliHLTMUONMansoTrackStruct* tracki = fTracks[i]; | |
765 | const AliHLTMUONMansoTrackStruct* trackj = fTracks[j]; | |
c9537879 | 766 | |
767 | AliHLTFloat32_t muMass = 0.1056583568; // muon mass in GeV/c^2 | |
768 | ||
769 | AliHLTFloat32_t mass = AliHLTMUONCalculations::ComputeMass( | |
770 | muMass, tracki->fPx, tracki->fPy, tracki->fPz, | |
771 | muMass, trackj->fPx, trackj->fPy, trackj->fPz | |
772 | ); | |
773 | ||
774 | AliHLTMUONParticleSign signi, signj; | |
775 | bool hitset[4]; | |
776 | AliHLTMUONUtils::UnpackMansoTrackFlags(tracki->fFlags, signi, hitset); | |
777 | AliHLTMUONUtils::UnpackMansoTrackFlags(trackj->fFlags, signj, hitset); | |
778 | ||
779 | AliHLTUInt8_t highPtCount = 0; | |
c9537879 | 780 | AliHLTUInt8_t lowPtCount = 0; |
cf7b241a | 781 | if (fFillSinglesDetail) |
782 | { | |
783 | const AliHLTMUONTrackDecisionStruct& trackidecision = singlesDecision[i]; | |
784 | const AliHLTMUONTrackDecisionStruct& trackjdecision = singlesDecision[j]; | |
785 | if (trackidecision.fPt > fHighPtCut) highPtCount++; | |
786 | if (trackjdecision.fPt > fHighPtCut) highPtCount++; | |
787 | if (trackidecision.fPt > fLowPtCut) lowPtCount++; | |
788 | if (trackjdecision.fPt > fLowPtCut) lowPtCount++; | |
789 | } | |
790 | else | |
791 | { | |
792 | if (ptValues[i] > fHighPtCut) highPtCount++; | |
793 | if (ptValues[j] > fHighPtCut) highPtCount++; | |
794 | if (ptValues[i] > fLowPtCut) lowPtCount++; | |
795 | if (ptValues[j] > fLowPtCut) lowPtCount++; | |
796 | } | |
c9537879 | 797 | |
798 | bool unlikeSign = (signi == kSignMinus and signj == kSignPlus) or | |
799 | (signi == kSignPlus and signj == kSignMinus); | |
800 | ||
801 | bool passedHighMassCut = false; | |
802 | bool passedLowMassCut = false; | |
803 | if (unlikeSign) | |
804 | { | |
805 | pairsHeader.fNunlikeAnyPt++; | |
806 | if (lowPtCount == 2) pairsHeader.fNunlikeLowPt++; | |
807 | if (highPtCount == 2) pairsHeader.fNunlikeHighPt++; | |
808 | ||
809 | if (mass > fHighMassCut) | |
810 | { | |
811 | passedHighMassCut = true; | |
812 | if (highPtCount == 2) pairsHeader.fNmassHigh++; | |
813 | } | |
814 | if (mass > fLowMassCut) | |
815 | { | |
816 | passedLowMassCut = true; | |
817 | pairsHeader.fNmassAny++; | |
818 | if (lowPtCount == 2) pairsHeader.fNmassLow++; | |
819 | } | |
820 | } | |
821 | else | |
822 | { | |
823 | pairsHeader.fNlikeAnyPt++; | |
824 | if (lowPtCount == 2) pairsHeader.fNlikeLowPt++; | |
825 | if (highPtCount == 2) pairsHeader.fNlikeHighPt++; | |
826 | } | |
827 | ||
cf7b241a | 828 | if (fFillPairsDetail) |
829 | { | |
830 | AliHLTMUONPairDecisionStruct& decision = pairsDecision[currentPair]; | |
831 | ||
832 | decision.fTrackAId = tracki->fId; | |
833 | decision.fTrackBId = trackj->fId; | |
834 | decision.fTriggerBits = AliHLTMUONUtils::PackPairDecisionBits( | |
835 | passedHighMassCut, passedLowMassCut, unlikeSign, | |
836 | highPtCount, lowPtCount | |
837 | ); | |
838 | decision.fInvMass = mass; | |
c9537879 | 839 | |
cf7b241a | 840 | currentPair++; |
841 | } | |
c9537879 | 842 | } |
843 | ||
cf7b241a | 844 | assert( fFillPairsDetail == false or (fFillPairsDetail == true and currentPair == fTrackCount * (fTrackCount-1) / 2) ); |
845 | ||
846 | if (not fFillSinglesDetail) | |
847 | { | |
848 | assert(ptValues != NULL); | |
849 | delete [] ptValues; | |
850 | } | |
851 | ||
852 | return 0; | |
c9537879 | 853 | } |
854 |