]>
Commit | Line | Data |
---|---|---|
8356cc1d | 1 | //////////////////////////////////////////////////////////////////////////////// |
2 | // | |
3 | // Author: Artur Szostak | |
4 | // Email: artur@alice.phy.uct.ac.za | artursz@iafrica.com | |
5 | // | |
6 | //////////////////////////////////////////////////////////////////////////////// | |
7 | ||
8 | #include "AliRoot/TriggerSource.hpp" | |
9 | #include "AliRoot/Base.hpp" | |
10 | #include "Tracking/Calculations.hpp" | |
11 | #include "AliRun.h" | |
12 | #include "AliRunLoader.h" | |
13 | #include "AliModule.h" | |
14 | #include "AliMUON.h" | |
15 | #include "AliMUONConstants.h" | |
16 | #include "AliMUONHit.h" | |
17 | #include "AliMUONLocalTrigger.h" | |
18 | #include "AliMUONTriggerCircuit.h" | |
19 | #include "AliMUONDataInterface.h" | |
20 | #include "TDatabasePDG.h" | |
98af1577 | 21 | #ifndef __alpha |
22 | #include <math.h> | |
23 | #else | |
24 | #include <float.h> | |
25 | #endif | |
8356cc1d | 26 | |
cbee67e7 | 27 | ClassImp(AliMUONHLT::TriggerSource) |
28 | ClassImp(AliMUONHLT::TriggerSource::EventData) | |
8356cc1d | 29 | |
30 | namespace AliMUONHLT | |
31 | { | |
32 | ||
33 | TriggerSource::TriggerSource() | |
34 | : TObject(), fEventList(TriggerSource::EventData::Class()) | |
35 | { | |
36 | fAreaToUse = FromWholePlane; | |
37 | fDataToUse = FromLocalTriggers; | |
38 | fMaxBlockSize = 0xFFFFFFFF; | |
39 | fUseLookupTable = kTRUE; | |
40 | fFilename = ""; | |
41 | fFoldername = ""; | |
42 | ResetAllPointers(); | |
43 | fHadToLoadgAlice = kFALSE; | |
cbee67e7 | 44 | } |
8356cc1d | 45 | |
46 | ||
47 | TriggerSource::TriggerSource(AliMUONDataInterface* data) | |
48 | : TObject(), fEventList(TriggerSource::EventData::Class()) | |
49 | { | |
50 | fAreaToUse = FromWholePlane; | |
51 | fDataToUse = FromLocalTriggers; | |
52 | fMaxBlockSize = 0xFFFFFFFF; | |
53 | fUseLookupTable = kTRUE; | |
54 | fFilename = ""; | |
55 | fFoldername = ""; | |
56 | ResetAllPointers(); | |
57 | fHadToLoadgAlice = kFALSE; | |
58 | FillFrom(data); | |
cbee67e7 | 59 | } |
8356cc1d | 60 | |
61 | ||
62 | TriggerSource::~TriggerSource() | |
63 | { | |
64 | fEventList.Clear("C"); | |
cbee67e7 | 65 | } |
8356cc1d | 66 | |
67 | ||
68 | void TriggerSource::FillFrom(AliMUONDataInterface* data) | |
69 | { | |
70 | DebugMsg(1, "FillFrom(AliMUONDataInterface*)"); | |
71 | ||
72 | if (FileAndFolderOk(data)) | |
73 | { | |
74 | AliMUON* module = NULL; | |
75 | if ( not FetchAliMUON(module) ) return; | |
76 | ||
77 | for (Int_t i = 0; i < data->NumberOfEvents(); i++) | |
78 | { | |
79 | AddEventFrom(data, module, i); | |
cbee67e7 | 80 | } |
8356cc1d | 81 | |
82 | FinishedWithAliMUON(); | |
cbee67e7 | 83 | } |
84 | } | |
8356cc1d | 85 | |
86 | ||
e33f3609 | 87 | void TriggerSource::FillFrom(AliMUONDataInterface* data, Int_t event) |
8356cc1d | 88 | { |
89 | DebugMsg(1, "FillFrom(AliMUONDataInterface*, Int_t)"); | |
90 | ||
91 | if (FileAndFolderOk(data)) | |
92 | { | |
93 | AliMUON* module = NULL; | |
94 | if ( not FetchAliMUON(module) ) return; | |
95 | AddEventFrom(data, module, event); | |
96 | FinishedWithAliMUON(); | |
cbee67e7 | 97 | } |
98 | } | |
8356cc1d | 99 | |
100 | ||
101 | void TriggerSource::FillFrom( | |
102 | AliMUONDataInterface* data, | |
e33f3609 | 103 | Int_t event, Int_t trigger, Bool_t newblock |
8356cc1d | 104 | ) |
105 | { | |
106 | DebugMsg(1, "FillFrom(AliMUONDataInterface*, Int_t, Int_t, Bool_t)"); | |
107 | ||
108 | if (FileAndFolderOk(data)) | |
109 | { | |
110 | data->GetEvent(event); | |
111 | AliMUON* module = NULL; | |
112 | if ( not FetchAliMUON(module) ) return; | |
113 | ||
114 | // Check if the current event corresponds to the event number we are | |
115 | // attempting to add to. If they do not or no event is selected then | |
116 | // try find the event or create a new one. | |
117 | if ( fCurrentEvent == NULL ) | |
118 | { | |
119 | Bool_t found = GetEvent(event); | |
120 | if (not found) AddEvent(event); | |
121 | } | |
122 | else | |
123 | { | |
124 | if (fCurrentEvent->fEventNumber != event) | |
125 | { | |
126 | Bool_t found = GetEvent(event); | |
127 | if (not found) AddEvent(event); | |
128 | }; | |
129 | }; | |
130 | ||
131 | if ( fCurrentBlock != NULL ) | |
132 | { | |
133 | Assert( fCurrentEvent != NULL ); | |
134 | // If the newblock flag is set then force a new block. | |
135 | if (newblock) AddBlock(); | |
136 | } | |
137 | else | |
138 | AddBlock(); // No block selected so we need to create a new block. | |
139 | ||
140 | AddTriggerFrom(data, module, trigger); | |
141 | FinishedWithAliMUON(); | |
cbee67e7 | 142 | } |
143 | } | |
8356cc1d | 144 | |
145 | ||
146 | void TriggerSource::Clear() | |
147 | { | |
148 | fFilename = ""; | |
149 | fFoldername = ""; | |
150 | ResetAllPointers(); | |
151 | fEventList.Clear("C"); | |
cbee67e7 | 152 | } |
8356cc1d | 153 | |
154 | ||
e33f3609 | 155 | Bool_t TriggerSource::GetEvent(Int_t eventnumber) const |
8356cc1d | 156 | { |
157 | DebugMsg(1, "TriggerSource::GetEvent(" << eventnumber << ")" ); | |
158 | ||
159 | // Try find the corresponding event in the list of events. | |
160 | for (Int_t i = 0; i < fEventList.GetEntriesFast(); i++) | |
161 | { | |
162 | EventData* current = (EventData*) fEventList[i]; | |
163 | if (current->fEventNumber == eventnumber) | |
164 | { | |
165 | fEventIndex = i; | |
166 | fCurrentEvent = current; | |
167 | GetFirstBlock(); | |
168 | DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex | |
169 | << " , fTriggerIndex = " << fTriggerIndex | |
170 | ); | |
171 | return kTRUE; | |
172 | }; | |
173 | }; | |
174 | return kFALSE; | |
cbee67e7 | 175 | } |
8356cc1d | 176 | |
177 | ||
178 | Bool_t TriggerSource::GetFirstEvent() const | |
179 | { | |
180 | DebugMsg(1, "TriggerSource::GetFirstEvent()"); | |
181 | if (fEventList.GetEntriesFast() > 0) | |
182 | { | |
183 | fEventIndex = 0; | |
184 | fCurrentEvent = (EventData*) fEventList[0]; | |
185 | GetFirstBlock(); | |
186 | DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex | |
187 | << " , fTriggerIndex = " << fTriggerIndex | |
188 | ); | |
189 | return kTRUE; | |
190 | } | |
191 | else | |
192 | { | |
193 | DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex | |
194 | << " , fTriggerIndex = " << fTriggerIndex | |
195 | ); | |
196 | return kFALSE; | |
cbee67e7 | 197 | } |
198 | } | |
8356cc1d | 199 | |
200 | ||
201 | Bool_t TriggerSource::MoreEvents() const | |
202 | { | |
203 | return 0 <= fEventIndex and fEventIndex < fEventList.GetEntriesFast(); | |
cbee67e7 | 204 | } |
8356cc1d | 205 | |
206 | ||
207 | Bool_t TriggerSource::GetNextEvent() const | |
208 | { | |
209 | DebugMsg(1, "TriggerSource::GetNextEvent()"); | |
210 | if (fEventIndex < fEventList.GetEntriesFast() - 1) | |
211 | { | |
212 | fCurrentEvent = (EventData*) fEventList[ ++fEventIndex ]; | |
213 | GetFirstBlock(); | |
214 | DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex | |
215 | << " , fTriggerIndex = " << fTriggerIndex | |
216 | ); | |
217 | return kTRUE; | |
218 | } | |
219 | else | |
220 | { | |
221 | ResetAllPointers(); | |
222 | return kFALSE; | |
cbee67e7 | 223 | } |
224 | } | |
8356cc1d | 225 | |
226 | ||
227 | Int_t TriggerSource::CurrentEvent() const | |
228 | { | |
229 | if (fCurrentEvent != NULL) | |
230 | return fCurrentEvent->fEventNumber; | |
231 | else | |
232 | return -1; | |
cbee67e7 | 233 | } |
8356cc1d | 234 | |
235 | ||
236 | Int_t TriggerSource::NumberOfBlocks() const | |
237 | { | |
238 | DebugMsg(1, "TriggerSource::NumberOfBlocks()"); | |
239 | if (fCurrentEvent == NULL) | |
240 | { | |
241 | Error("NumberOfBlocks", "No event selected."); | |
242 | return -1; | |
243 | } | |
244 | else | |
245 | return fCurrentEvent->fBlocks.GetEntriesFast(); | |
cbee67e7 | 246 | } |
8356cc1d | 247 | |
248 | ||
e33f3609 | 249 | Bool_t TriggerSource::GetBlock(Int_t index) const |
8356cc1d | 250 | { |
251 | DebugMsg(1, "TriggerSource::GetBlock(" << index << ")"); | |
252 | ||
253 | // Note NumberOfBlocks() also checks if the event was selected. | |
254 | Int_t numberofblocks = NumberOfBlocks(); | |
255 | if (numberofblocks < 0) return kFALSE; | |
256 | ||
257 | if ( 0 <= index and index < numberofblocks ) | |
258 | { | |
259 | fBlockIndex = index; | |
260 | fCurrentBlock = (TClonesArray*) fCurrentEvent->fBlocks[index]; | |
261 | GetFirstTrigger(); | |
262 | DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex | |
263 | << " , fTriggerIndex = " << fTriggerIndex | |
264 | ); | |
265 | return kTRUE; | |
266 | } | |
267 | else | |
268 | { | |
269 | // The index is out of bounds so inform the user. | |
270 | if (numberofblocks > 0) | |
271 | Error( "GetBlock", | |
272 | "The block index (%d) is out of bounds. Valid range is [0, %d]", | |
273 | index, numberofblocks - 1 | |
274 | ); | |
275 | else | |
276 | Error( "GetBlock", | |
277 | "The block index (%d) is out of bounds. No blocks found.", | |
278 | index | |
279 | ); | |
280 | return kFALSE; | |
cbee67e7 | 281 | } |
282 | } | |
8356cc1d | 283 | |
284 | ||
285 | Bool_t TriggerSource::GetFirstBlock() const | |
286 | { | |
287 | DebugMsg(1, "TriggerSource::GetFirstBlock()"); | |
288 | // Note: NumberOfBlocks() also checks if fCurrentEvent != NULL. | |
289 | if (NumberOfBlocks() > 0) | |
290 | { | |
291 | fBlockIndex = 0; | |
292 | fCurrentBlock = (TClonesArray*) fCurrentEvent->fBlocks[fBlockIndex]; | |
293 | GetFirstTrigger(); | |
294 | DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex | |
295 | << " , fTriggerIndex = " << fTriggerIndex | |
296 | ); | |
297 | return kTRUE; | |
298 | } | |
299 | else | |
300 | return kFALSE; | |
cbee67e7 | 301 | } |
8356cc1d | 302 | |
303 | ||
304 | Bool_t TriggerSource::MoreBlocks() const | |
305 | { | |
306 | return 0 <= fBlockIndex and fBlockIndex < NumberOfBlocks(); | |
cbee67e7 | 307 | } |
8356cc1d | 308 | |
309 | ||
310 | Bool_t TriggerSource::GetNextBlock() const | |
311 | { | |
312 | DebugMsg(1, "TriggerSource::GetNextBlock()"); | |
313 | ||
314 | // Note: NumberOfBlocks() checks if fCurrentEvent != NULL. If it is then it returns -1 | |
315 | // and since fBlockIndex is always >= -1 the if statement must go to the else part. | |
316 | if (fBlockIndex < NumberOfBlocks() - 1) | |
317 | { | |
318 | fCurrentBlock = (TClonesArray*) fCurrentEvent->fBlocks[ ++fBlockIndex ]; | |
319 | GetFirstTrigger(); | |
320 | DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex | |
321 | << " , fTriggerIndex = " << fTriggerIndex | |
322 | ); | |
323 | return kTRUE; | |
324 | } | |
325 | else | |
326 | { | |
327 | ResetBlockPointers(); | |
328 | return kFALSE; | |
cbee67e7 | 329 | } |
330 | } | |
8356cc1d | 331 | |
332 | ||
333 | Int_t TriggerSource::NumberOfTriggers() const | |
334 | { | |
335 | DebugMsg(1, "TriggerSource::NumberOfTriggers()"); | |
336 | if (fCurrentBlock == NULL) | |
337 | { | |
338 | Error("NumberOfTriggers", "No block selected."); | |
339 | return -1; | |
340 | } | |
341 | else | |
342 | return fCurrentBlock->GetEntriesFast(); | |
cbee67e7 | 343 | } |
8356cc1d | 344 | |
345 | ||
e33f3609 | 346 | const TriggerRecord* TriggerSource::GetTrigger(Int_t triggernumber) const |
8356cc1d | 347 | { |
348 | DebugMsg(1, "TriggerSource::GetTrigger(" << triggernumber << ")"); | |
349 | ||
350 | if (fCurrentBlock == NULL) | |
351 | { | |
352 | Error("GetTrigger", "No block selected."); | |
353 | return NULL; | |
354 | }; | |
355 | ||
356 | // Try find the corresponding trigger record in the list of events. | |
357 | for (Int_t i = 0; i < fCurrentBlock->GetEntriesFast(); i++) | |
358 | { | |
359 | TriggerRecord* current = (TriggerRecord*) fCurrentBlock->At(i); | |
360 | if (current->TriggerNumber() == triggernumber) | |
361 | { | |
362 | fTriggerIndex = i; | |
363 | fCurrentTrigger = current; | |
364 | DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex | |
365 | << " , fTriggerIndex = " << fTriggerIndex | |
366 | ); | |
367 | return current; | |
cbee67e7 | 368 | } |
369 | } | |
8356cc1d | 370 | return NULL; |
cbee67e7 | 371 | } |
8356cc1d | 372 | |
373 | ||
374 | const TriggerRecord* TriggerSource::GetFirstTrigger() const | |
375 | { | |
376 | DebugMsg(1, "TriggerSource::GetFirstTrigger()"); | |
377 | // Note: NumberOfTriggers() also checks if fCurrentBlock != NULL. | |
378 | if (NumberOfTriggers() > 0) | |
379 | { | |
380 | fTriggerIndex = 0; | |
381 | fCurrentTrigger = (TriggerRecord*) fCurrentBlock->At(0); | |
382 | DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex | |
383 | << " , fTriggerIndex = " << fTriggerIndex | |
384 | ); | |
385 | return fCurrentTrigger; | |
386 | } | |
387 | else | |
388 | return NULL; | |
389 | }; | |
390 | ||
391 | ||
392 | Bool_t TriggerSource::MoreTriggers() const | |
393 | { | |
394 | return 0 <= fTriggerIndex and fTriggerIndex < NumberOfTriggers(); | |
cbee67e7 | 395 | } |
8356cc1d | 396 | |
397 | ||
398 | const TriggerRecord* TriggerSource::GetNextTrigger() const | |
399 | { | |
400 | DebugMsg(1, "TriggerSource::GetNextTrigger()"); | |
401 | ||
402 | // Note: NumberOfTriggers() checks if fCurrentBlock != NULL. If it is then it returns -1 | |
403 | // and since fTriggerIndex is always >= -1 the if statement must go to the else part. | |
404 | if (fTriggerIndex < NumberOfTriggers() - 1) | |
405 | { | |
406 | fCurrentTrigger = (TriggerRecord*) fCurrentBlock->At( ++fTriggerIndex ); | |
407 | DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex | |
408 | << " , fTriggerIndex = " << fTriggerIndex | |
409 | ); | |
410 | return fCurrentTrigger; | |
411 | } | |
412 | else | |
413 | { | |
414 | ResetTriggerPointers(); | |
415 | return NULL; | |
416 | }; | |
417 | }; | |
418 | ||
419 | ||
420 | Int_t TriggerSource::CurrentTrigger() const | |
421 | { | |
422 | if (fCurrentTrigger != NULL) | |
423 | { | |
424 | return fCurrentTrigger->TriggerNumber(); | |
425 | } | |
426 | else | |
427 | { | |
428 | Error("CurrentTrigger", "No trigger record selected."); | |
429 | return -1; | |
cbee67e7 | 430 | } |
431 | } | |
8356cc1d | 432 | |
433 | ||
e33f3609 | 434 | void TriggerSource::AddEvent(Int_t eventnumber) |
8356cc1d | 435 | { |
436 | DebugMsg(1, "TriggerSource::AddEvent(" << eventnumber << ")"); | |
437 | Assert( eventnumber >= 0 ); | |
438 | ||
439 | // Assume the eventnumber does not already exist in the event list. | |
440 | fEventIndex = fEventList.GetEntriesFast(); | |
441 | new ( fEventList[fEventIndex] ) EventData(eventnumber); | |
442 | fCurrentEvent = (EventData*) fEventList[fEventIndex]; | |
443 | ||
444 | // Remember to reset the other pointers because the new event is empty. | |
445 | ResetBlockPointers(); | |
446 | ||
447 | DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex | |
448 | << " , fTriggerIndex = " << fTriggerIndex | |
449 | ); | |
cbee67e7 | 450 | } |
8356cc1d | 451 | |
452 | ||
453 | void TriggerSource::AddBlock() | |
454 | { | |
455 | DebugMsg(1, "TriggerSource::AddBlock()"); | |
456 | ||
457 | if (fCurrentEvent == NULL) | |
458 | { | |
459 | Error("AddBlock", "No event selected."); | |
460 | return; | |
461 | }; | |
462 | ||
463 | fBlockIndex = fCurrentEvent->fBlocks.GetEntriesFast(); | |
464 | new ( fCurrentEvent->fBlocks[fBlockIndex] ) TClonesArray(TriggerRecord::Class()); | |
465 | fCurrentBlock = (TClonesArray*) fCurrentEvent->fBlocks[fBlockIndex]; | |
466 | ||
467 | // Remember to reset the trigger pointer because the new block is empty. | |
468 | ResetTriggerPointers(); | |
469 | ||
470 | DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex | |
471 | << " , fTriggerIndex = " << fTriggerIndex | |
472 | ); | |
cbee67e7 | 473 | } |
8356cc1d | 474 | |
475 | ||
476 | void TriggerSource::AddTrigger(const TriggerRecord& data) | |
477 | { | |
478 | DebugMsg(1, "TriggerSource::AddTrigger(" << (void*)&data << ")"); | |
479 | ||
480 | if (fCurrentBlock == NULL) | |
481 | { | |
482 | Error("AddTrigger", "No block selected."); | |
483 | return; | |
cbee67e7 | 484 | } |
8356cc1d | 485 | |
486 | fTriggerIndex = fCurrentBlock->GetEntriesFast(); | |
487 | new ( (*fCurrentBlock)[fTriggerIndex] ) TriggerRecord(data); | |
488 | fCurrentTrigger = (TriggerRecord*) (*fCurrentBlock)[fTriggerIndex]; | |
489 | ||
490 | DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex | |
491 | << " , fTriggerIndex = " << fTriggerIndex | |
492 | ); | |
cbee67e7 | 493 | } |
8356cc1d | 494 | |
495 | ||
496 | Bool_t TriggerSource::FileAndFolderOk(AliMUONDataInterface* data) | |
497 | { | |
498 | if (fFilename == "") | |
499 | { | |
500 | // Nothing filled yet so set the file and folder names. | |
501 | fFilename = data->CurrentFile(); | |
502 | fFoldername = data->CurrentFolder(); | |
503 | return kTRUE; | |
504 | }; | |
505 | ||
506 | if ( fFilename != data->CurrentFile() ) | |
507 | { | |
508 | Error( "FileAndFolderOk", | |
509 | "The Trigger source already contains data from file '%s', cannot add data from file '%s'", | |
510 | fFilename.Data(), data->CurrentFile().Data() | |
511 | ); | |
512 | return kFALSE; | |
513 | }; | |
514 | ||
515 | if ( fFoldername != data->CurrentFolder() ) | |
516 | { | |
517 | Error( "FileAndFolderOk", | |
518 | "The Trigger source already contains data from folder '%s', cannot add data from folder '%s'", | |
519 | fFoldername.Data(), data->CurrentFolder().Data() | |
520 | ); | |
521 | return kFALSE; | |
522 | }; | |
523 | ||
524 | return kTRUE; | |
cbee67e7 | 525 | } |
8356cc1d | 526 | |
527 | ||
e33f3609 | 528 | void TriggerSource::AddEventFrom(AliMUONDataInterface* data, AliMUON* module, Int_t event) |
8356cc1d | 529 | { |
530 | if ( data->GetEvent(event) ) | |
531 | { | |
532 | AddEvent(event); | |
533 | ||
534 | AddBlock(); | |
535 | UInt_t currentblocksize = 0; | |
536 | TriggerRecord trigdata; | |
537 | ||
538 | switch (fDataToUse) | |
539 | { | |
540 | case FromHits: | |
541 | for (Int_t track = 0; track < data->NumberOfTracks(); track++) | |
542 | { | |
543 | if ( not FillTriggerFromHits(data, track, trigdata) ) | |
544 | continue; // Continue if unable to find hits. | |
545 | ||
546 | if (InFillRegion(trigdata)) | |
547 | { | |
548 | AddTrigger(trigdata); | |
549 | ||
550 | // Create a new block if we reached the maximum block size. | |
551 | if ( ++currentblocksize == fMaxBlockSize ) | |
552 | { | |
553 | AddBlock(); | |
554 | currentblocksize = 0; | |
555 | }; | |
556 | }; | |
557 | }; | |
558 | break; | |
559 | ||
560 | case FromLocalTriggers: | |
561 | Assert( module != NULL ); | |
562 | DebugMsg(4, "Taking FromLocalTriggers branch..."); | |
563 | for (Int_t i = 0; i < data->NumberOfLocalTriggers(); i++) | |
564 | { | |
565 | DebugMsg(4, "for loop: i = " << i); | |
566 | AliMUONLocalTrigger* lt = data->LocalTrigger(i); | |
567 | FillTriggerFromLocalTrigger(lt, module, trigdata); | |
568 | trigdata.TriggerNumber(i); | |
569 | ||
570 | if (InFillRegion(trigdata)) | |
571 | { | |
572 | AddTrigger(trigdata); | |
573 | ||
574 | // Create a new block if we reached the maximum block size. | |
575 | if ( ++currentblocksize == fMaxBlockSize ) | |
576 | { | |
577 | AddBlock(); | |
578 | currentblocksize = 0; | |
579 | }; | |
580 | }; | |
581 | }; | |
582 | break; | |
583 | ||
584 | default: | |
585 | Error("AddChamberFrom", "fDataToUse is not set to a valid value."); | |
cbee67e7 | 586 | } |
587 | } // Loop on events. | |
588 | } | |
8356cc1d | 589 | |
590 | ||
e33f3609 | 591 | void TriggerSource::AddTriggerFrom(AliMUONDataInterface* data, AliMUON* module, Int_t trigger) |
8356cc1d | 592 | { |
593 | DebugMsg(1, "Entering AddTriggerFrom"); | |
594 | ||
595 | TriggerRecord trigdata; | |
596 | ||
597 | switch (fDataToUse) | |
598 | { | |
599 | case FromHits: | |
600 | { | |
601 | // Note: in this case we treat the trigger parameter as a track number. | |
602 | if ( not FillTriggerFromHits(data, trigger, trigdata) ) | |
603 | return; // Continue if unable to find hits. | |
604 | } | |
605 | break; | |
606 | ||
607 | case FromLocalTriggers: | |
608 | { | |
609 | Assert( module != NULL ); | |
610 | AliMUONLocalTrigger* lt = data->LocalTrigger(trigger); | |
611 | FillTriggerFromLocalTrigger(lt, module, trigdata); | |
612 | trigdata.TriggerNumber(trigger); | |
613 | } | |
614 | break; | |
615 | ||
616 | default: | |
617 | Error("AddTriggerFrom", "fDataToUse is not set to a valid value."); | |
618 | return; | |
619 | }; | |
620 | ||
621 | AddTrigger(trigdata); | |
622 | ||
623 | DebugMsg(1, "Leaving AddTriggerFrom"); | |
cbee67e7 | 624 | } |
8356cc1d | 625 | |
626 | ||
627 | Bool_t TriggerSource::InFillRegion(const TriggerRecord& data) | |
628 | { | |
629 | switch (fAreaToUse) | |
630 | { | |
631 | case FromWholePlane: return kTRUE; | |
632 | case FromLeftHalfPlane: return data.Station1Point().fX <= 0; | |
633 | case FromRightHalfPlane: return data.Station1Point().fX > 0; | |
634 | ||
635 | default: | |
636 | Error("InFillRegion", "fAreaToUse is not set to a valid value."); | |
637 | return kFALSE; | |
cbee67e7 | 638 | } |
639 | } | |
8356cc1d | 640 | |
641 | ||
642 | void TriggerSource::FillTriggerFromLocalTrigger( | |
643 | AliMUONLocalTrigger* trigger, AliMUON* module, TriggerRecord& record | |
644 | ) | |
645 | { | |
646 | DebugMsg(2, "Creating TriggerRecord from AliMUONLocalTrigger object: " << (void*)trigger ); | |
647 | AliMUONTriggerCircuit& circuit = module->TriggerCircuit(trigger->LoCircuit()); | |
648 | ||
649 | // Get the sign of the particle the sign of the muon. | |
650 | if (trigger->LoLpt() == 1 || trigger->LoHpt() == 1 || trigger->LoApt() == 1) | |
651 | { | |
652 | record.ParticleSign(-1); | |
653 | } | |
654 | else | |
655 | if (trigger->LoLpt() == 2 || trigger->LoHpt() == 2 || trigger->LoApt() == 2) | |
656 | { | |
657 | record.ParticleSign(+1); | |
658 | } | |
659 | else | |
660 | { | |
661 | record.ParticleSign(0); | |
662 | }; | |
663 | DebugMsg(2, "Particle sign = " << record.ParticleSign() ); | |
664 | ||
665 | // Compute the transverse momentum. | |
666 | if (fUseLookupTable) | |
667 | { | |
668 | // TODO: implement use of the L0 lookup table. | |
669 | Error("FillTriggerFromLocalTrigger", "Use of L0 lookup table is not yet implemented!"); | |
670 | } | |
671 | else | |
672 | { | |
673 | Float_t pt = circuit.PtCal( trigger->LoStripX(), trigger->LoDev(), trigger->LoStripY() ); | |
674 | record.Pt(pt); | |
675 | }; | |
676 | DebugMsg(2, "Pt = " << record.Pt() ); | |
677 | ||
678 | // Build the impact points. | |
679 | record.Station1Point().fX = circuit.GetX11Pos(trigger->LoStripY()); | |
680 | record.Station1Point().fY = circuit.GetY11Pos(trigger->LoStripX()); | |
681 | record.Station2Point().fY = circuit.GetY21Pos(trigger->LoStripX() + trigger->LoDev() + 1); // Why + 1? | |
682 | record.Station2Point().fX = module->Chamber(12).Z() * record.Station1Point().fX / module->Chamber(10).Z(); | |
683 | DebugMsg(2, "fStation1x = " << record.Station1Point().fX); | |
684 | DebugMsg(2, "fStation1y = " << record.Station1Point().fY); | |
685 | DebugMsg(2, "fStation2x = " << record.Station2Point().fX); | |
686 | DebugMsg(2, "fStation2y = " << record.Station2Point().fY); | |
cbee67e7 | 687 | } |
8356cc1d | 688 | |
689 | ||
e33f3609 | 690 | Bool_t TriggerSource::FillTriggerFromHits(AliMUONDataInterface* data, Int_t track, TriggerRecord& record) |
8356cc1d | 691 | { |
692 | DebugMsg(2, "Creating TriggerRecord from hits on track: " << track ); | |
693 | ||
694 | Float_t x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4; | |
98af1577 | 695 | #ifndef __alpha |
cbee67e7 | 696 | #ifndef __sparc |
8356cc1d | 697 | x1 = y1 = z1 = x2 = y2 = z2 = x3 = y3 = z3 = x4 = y4 = z4 = NAN; |
cbee67e7 | 698 | #else |
699 | x1 = y1 = z1 = x2 = y2 = z2 = x3 = y3 = z3 = x4 = y4 = z4 = 0; | |
700 | #endif | |
98af1577 | 701 | #else |
702 | x1 = y1 = z1 = x2 = y2 = z2 = x3 = y3 = z3 = x4 = y4 = z4 = FLT_QNAN; | |
703 | #endif | |
8356cc1d | 704 | // Find the hit that corresponds to chambers. 11 to 14. We can ignore any |
705 | // hits above the first 14. If there are that many it means the particle | |
706 | // is cycling in the detector. | |
707 | for (Int_t i = 0; i < data->NumberOfHits(track) and i < 14; i++) | |
708 | { | |
709 | AliMUONHit* h = data->Hit(track, i); | |
710 | ||
711 | // Note AliMUONHit::Chamber() returns a value in the range 1..14 | |
712 | // It is also important to have positive Z coordinates and under the | |
713 | // new version of Aliroot we use GEANT coordinates which return | |
714 | // negatives. So we use the fabs routine. | |
715 | switch ( h->Chamber() ) | |
716 | { | |
717 | case 11: x1 = h->X(); y1 = h->Y(); z1 = (Float_t)fabs(h->Z()); break; | |
718 | case 12: x2 = h->X(); y2 = h->Y(); z2 = (Float_t)fabs(h->Z()); break; | |
719 | case 13: x3 = h->X(); y3 = h->Y(); z3 = (Float_t)fabs(h->Z()); break; | |
720 | case 14: x4 = h->X(); y4 = h->Y(); z4 = (Float_t)fabs(h->Z()); break; | |
721 | }; | |
722 | }; | |
723 | DebugMsg(4, "Found: x1 = " << x1 << ", y1 = " << y1 << ", z1 = " << z1); | |
724 | DebugMsg(4, "Found: x2 = " << x2 << ", y2 = " << y2 << ", z2 = " << z2); | |
725 | DebugMsg(4, "Found: x3 = " << x3 << ", y3 = " << y3 << ", z3 = " << z3); | |
726 | DebugMsg(4, "Found: x4 = " << x4 << ", y4 = " << y4 << ", z4 = " << z4); | |
727 | ||
728 | // Get a coordinate for station 1, perferably from chamber 11 otherwise | |
729 | // use hits from chamber 12. | |
730 | if (not TMath::IsNaN(x1)) | |
731 | { | |
732 | record.Station1Point().fX = x1; | |
733 | record.Station1Point().fY = y1; | |
734 | DebugMsg(3, "Using value from chamber 11: x1 = " << x1 << ", y1 = " << y1 << ", z1 = " << z1 ); | |
735 | } | |
736 | else if (not TMath::IsNaN(x2)) | |
737 | { | |
738 | record.Station1Point().fX = x2; | |
739 | record.Station1Point().fY = y2; | |
740 | z1 = z2; | |
741 | DebugMsg(3, "Using value from chamber 12: x2 = " << x2 << ", y2 = " << y2 << ", z2 = " << z2 ); | |
742 | } | |
743 | else | |
744 | { | |
745 | // Return false if we could not find any hits on chambers 11 or 12. | |
746 | Warning("FillTriggerFromHits", "Could not find any hits on chambers 11 and 12."); | |
747 | return kFALSE; | |
748 | }; | |
749 | ||
750 | // Get a coordinate for station 2, perferably from chamber 13 otherwise | |
751 | // use hits from chamber 14. | |
752 | if (not TMath::IsNaN(x3)) | |
753 | { | |
754 | record.Station2Point().fX = x3; | |
755 | record.Station2Point().fY = y3; | |
756 | z2 = z3; | |
757 | DebugMsg(3, "Using value from chamber 13: x3 = " << x3 << ", y3 = " << y3 << ", z3 = " << z3 ); | |
758 | } | |
759 | else if (not TMath::IsNaN(x4)) | |
760 | { | |
761 | record.Station2Point().fX = x4; | |
762 | record.Station2Point().fY = y4; | |
763 | z2 = z4; | |
764 | DebugMsg(3, "Using value from chamber 14: x4 = " << x4 << ", y4 = " << y4 << ", z4 = " << z4 ); | |
765 | } | |
766 | else | |
767 | { | |
768 | // Return false if we could not find any hits on chambers 13 or 14. | |
769 | Warning("FillTriggerFromHits", "Could not find any hits on chambers 13 and 14."); | |
770 | return kFALSE; | |
771 | }; | |
772 | ||
773 | record.TriggerNumber(track); | |
774 | ||
775 | // Get the sign of the particle. | |
776 | Int_t particlecode = (Int_t) data->Hit(track, 0)->Particle(); | |
777 | DebugMsg(3, "particle code = " << particlecode); | |
778 | TDatabasePDG* pdb = TDatabasePDG::Instance(); | |
779 | TParticlePDG* pdata = pdb->GetParticle(particlecode); | |
780 | if (pdata->Charge() < 0) | |
781 | record.ParticleSign(-1); | |
782 | else if (pdata->Charge() > 0) | |
783 | record.ParticleSign(+1); | |
784 | else | |
785 | record.ParticleSign(0); | |
786 | DebugMsg(3, "Particle sign = " << record.ParticleSign()); | |
787 | ||
788 | DebugMsg(3, "Calculating Pt: x1 = " << record.Station1Point().fX | |
789 | << ", y1 = " << record.Station1Point().fY | |
790 | << ", y2 = " << record.Station2Point().fY | |
791 | << ", z1 = " << z1 | |
792 | << ", z2 = " << z2 | |
793 | ); | |
794 | // Calculate and assign the transverse momentum. | |
795 | Float_t pt = dHLT::Tracking::CalculatePt( | |
796 | record.Station1Point().fX, | |
797 | record.Station1Point().fY, record.Station2Point().fY, | |
798 | z1, z2 | |
799 | ); | |
800 | record.Pt(pt); | |
801 | ||
802 | DebugMsg(3, "Pt = " << record.Pt()); | |
803 | ||
804 | return kTRUE; | |
cbee67e7 | 805 | } |
8356cc1d | 806 | |
807 | ||
808 | Bool_t TriggerSource::FetchAliMUON(AliMUON*& module) | |
809 | { | |
810 | // Check if we even need the MUON module. Not having to load it will | |
811 | // save a lot of loading time for AliRoot. | |
812 | if (fDataToUse == FromHits) | |
813 | { | |
814 | // Make sure we do not attempt to unload gAlice in FinishedWithAliMUON, | |
815 | // by setting the fHadToLoadgAlice to false. | |
816 | fHadToLoadgAlice = kFALSE; | |
817 | return kTRUE; | |
818 | }; | |
819 | ||
820 | AliRunLoader* runloader = AliRunLoader::GetRunLoader(); | |
821 | if ( runloader == NULL ) | |
822 | { | |
823 | Error("FetchAliMUON", "AliRunLoader not initialised!"); | |
824 | return kFALSE; | |
825 | }; | |
826 | ||
827 | // Try fetch the AliRun object. If it is not found then try load it using | |
828 | // the runloader. | |
829 | AliRun* alirun = runloader->GetAliRun(); | |
830 | if (alirun == NULL) | |
831 | { | |
832 | if (runloader->LoadgAlice() != 0) | |
833 | { | |
834 | // Error. | |
835 | DebugMsg(1, "Leaving FillFrom(AliMUONDataInterface*)"); | |
836 | return kFALSE; | |
837 | }; | |
838 | fHadToLoadgAlice = kTRUE; | |
839 | alirun = runloader->GetAliRun(); | |
840 | } | |
841 | else | |
842 | fHadToLoadgAlice = kFALSE; | |
843 | ||
844 | // Get the MUON module pointer and return it. | |
845 | module = dynamic_cast<AliMUON*>( alirun->GetModule("MUON") ); | |
846 | return kTRUE; | |
cbee67e7 | 847 | } |
8356cc1d | 848 | |
849 | ||
850 | void TriggerSource::FinishedWithAliMUON() | |
851 | { | |
852 | // Only unload the gAlice object if we had to load it ourselves. | |
853 | if (fHadToLoadgAlice) | |
854 | AliRunLoader::GetRunLoader()->UnloadgAlice(); | |
cbee67e7 | 855 | } |
8356cc1d | 856 | |
857 | ||
858 | void TriggerSource::ResetAllPointers() const | |
859 | { | |
860 | fEventIndex = -1; | |
861 | fCurrentEvent = NULL; | |
862 | fBlockIndex = -1; | |
863 | fCurrentBlock = NULL; | |
864 | fTriggerIndex = -1; | |
865 | fCurrentTrigger = NULL; | |
866 | DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex | |
867 | << " , fTriggerIndex = " << fTriggerIndex | |
868 | ); | |
cbee67e7 | 869 | } |
8356cc1d | 870 | |
871 | ||
872 | void TriggerSource::ResetBlockPointers() const | |
873 | { | |
874 | fBlockIndex = -1; | |
875 | fCurrentBlock = NULL; | |
876 | fTriggerIndex = -1; | |
877 | fCurrentTrigger = NULL; | |
878 | DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex | |
879 | << " , fTriggerIndex = " << fTriggerIndex | |
880 | ); | |
cbee67e7 | 881 | } |
8356cc1d | 882 | |
883 | ||
884 | void TriggerSource::ResetTriggerPointers() const | |
885 | { | |
886 | fTriggerIndex = -1; | |
887 | fCurrentTrigger = NULL; | |
888 | DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex | |
889 | << " , fTriggerIndex = " << fTriggerIndex | |
890 | ); | |
cbee67e7 | 891 | } |
8356cc1d | 892 | |
893 | ||
894 | TriggerSource::EventData::EventData() : fBlocks(TClonesArray::Class()) | |
895 | { | |
896 | fEventNumber = -1; | |
cbee67e7 | 897 | } |
8356cc1d | 898 | |
899 | ||
e33f3609 | 900 | TriggerSource::EventData::EventData(Int_t eventnumber) |
8356cc1d | 901 | : fBlocks(TClonesArray::Class()) |
902 | { | |
903 | fEventNumber = eventnumber; | |
904 | ||
905 | // If the following is not set then we do not write the fBlocks properly. | |
906 | fBlocks.BypassStreamer(kFALSE); | |
cbee67e7 | 907 | } |
8356cc1d | 908 | |
909 | ||
910 | TriggerSource::EventData::~EventData() | |
911 | { | |
912 | fBlocks.Clear("C"); | |
cbee67e7 | 913 | } |
8356cc1d | 914 | |
915 | ||
cbee67e7 | 916 | } // AliMUONHLT |