Revision of macros documentation
[u/mrichter/AliRoot.git] / MUON / MUONCheckDI.C
CommitLineData
6ca54c85 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16/* $Id$ */
17
e54bf126 18/// \ingroup macros
19/// \file MUONCheckDI.C
20/// \brief Macro for checking AliMUONDataInterface and AliMUONMCDataInterface.
21///
22/// \author Bruce Becker, DAPNIA/SPhN/CEA Saclay
23///
24/// Modified to updated versions of data interfaces
25/// by Artur Szostak <artursz@iafrica.com> (University of Cape Town)
6ca54c85 26
9b220edf 27#if !defined(__CINT__) || defined(__MAKECINT__)
6ca54c85 28#include "AliMUONHit.h"
9b220edf 29#include "AliMUONVDigit.h"
2060b217 30#include "AliMUONVCluster.h"
9b220edf 31#include "AliMUONLocalTrigger.h"
32#include "AliMUONRegionalTrigger.h"
33#include "AliMUONGlobalTrigger.h"
9b220edf 34#include "AliMUONMCDataInterface.h"
6ca54c85 35#include "AliMUONDataInterface.h"
22fbde16 36#include "AliMUONVHitStore.h"
9b220edf 37#include "AliMUONVDigitStore.h"
38#include "AliMUONVClusterStore.h"
9b220edf 39#include "AliMUONVTriggerStore.h"
9b220edf 40#include "AliMpConstants.h"
41#include "AliMpDEManager.h"
22fbde16 42
43#include "AliCDBManager.h"
44
45#include <Rtypes.h>
46#include <Riostream.h>
47#include <TObjArray.h>
48#include <TIterator.h>
49#include <TMatrixD.h>
50
9b220edf 51#include <cstdlib>
22fbde16 52
6ca54c85 53#endif
54
55
9b220edf 56/**
57 * This routine implements a the comparison functionality which is missing for
58 * classes like AliMUONTrack and the various AliMUONxxxTrigger classes.
59 * A result of -1 is returned if a < b, 0 if a == b and +1 if a > b.
60 */
61Int_t Compare(const TObject* a, const TObject* b)
6ca54c85 62{
9b220edf 63 int result = -999;
61fed964 64 if (a->IsA() == AliMUONLocalTrigger::Class() && b->IsA() == AliMUONLocalTrigger::Class())
9b220edf 65 {
66 result = memcmp(a, b, sizeof(AliMUONLocalTrigger));
67 }
68 else if (a->IsA() == AliMUONRegionalTrigger::Class() && b->IsA() == AliMUONRegionalTrigger::Class())
69 {
22fbde16 70 const AliMUONRegionalTrigger* ra = static_cast<const AliMUONRegionalTrigger*>(a);
71 const AliMUONRegionalTrigger* rb = static_cast<const AliMUONRegionalTrigger*>(b);
72 if (ra->GetId() < rb->GetId()) return -1;
73 if (ra->GetId() > rb->GetId()) return 1;
74 if (ra->GetLocalOutput(0) < rb->GetLocalOutput(0)) return -1;
75 if (ra->GetLocalOutput(0) > rb->GetLocalOutput(0)) return 1;
76 if (ra->GetLocalOutput(1) < rb->GetLocalOutput(1)) return -1;
77 if (ra->GetLocalOutput(1) > rb->GetLocalOutput(1)) return 1;
78 if (ra->GetLocalMask() < rb->GetLocalMask()) return -1;
79 if (ra->GetLocalMask() > rb->GetLocalMask()) return 1;
80 if (ra->GetOutput() < rb->GetOutput()) return -1;
81 if (ra->GetOutput() > rb->GetOutput()) return 1;
82 return 0;
9b220edf 83 }
84 else if (a->IsA() == AliMUONGlobalTrigger::Class() && b->IsA() == AliMUONGlobalTrigger::Class())
85 {
86 result = memcmp(a, b, sizeof(AliMUONGlobalTrigger));
87 }
9b220edf 88 else
6ca54c85 89 {
9b220edf 90 result = memcmp(a, b, sizeof(TObject));
6ca54c85 91 }
9b220edf 92
93 if (result < 0) return -1;
94 if (result > 0) return 1;
95 return 0;
6ca54c85 96}
97
9b220edf 98/**
99 * This method fills internal arrays with local and regional triggers returned
100 * by AliMUONMCDataInterface. For each set of interface methods available in
101 * AliMUONMCDataInterface a TObjArray is created for local and another for regional
102 * triggers. These arrays are filled with copies of the trigger objects.
103 * The global trigger object is also copied out using the 2 different methods.
104 * The arrays and objects are then compared to each other. The arrays and objects
105 * should contain the same information if everything is working correctly with
106 * AliMUONMCDataInterface. If not then the difference is printed together with an
22fbde16 107 * error message and false is returned.
9b220edf 108 */
109bool SimTriggersOk()
6ca54c85 110{
22fbde16 111 AliMUONMCDataInterface data("generated/galice.root");
9b220edf 112 for (Int_t event = 0; event < data.NumberOfEvents(); event++)
113 {
114 TObjArray localsFromStore, regionalsFromStore;
115 localsFromStore.SetOwner(kTRUE);
116 regionalsFromStore.SetOwner(kTRUE);
117 AliMUONVTriggerStore* store = data.TriggerStore(event);
22fbde16 118 if (store == NULL) return false;
9b220edf 119 AliMUONGlobalTrigger* globalFromStore = static_cast<AliMUONGlobalTrigger*>(store->Global()->Clone());
120 TIter nextLocal(store->CreateLocalIterator());
121 AliMUONLocalTrigger* localTrig;
122 while ( (localTrig = static_cast<AliMUONLocalTrigger*>( nextLocal() )) != NULL )
123 {
124 localsFromStore.Add(localTrig->Clone());
125 }
126 TIter nextRegional(store->CreateRegionalIterator());
127 AliMUONRegionalTrigger* regionalTrig;
128 while ( (regionalTrig = static_cast<AliMUONRegionalTrigger*>( nextRegional() )) != NULL )
129 {
130 regionalsFromStore.Add(regionalTrig->Clone());
131 }
132
133 TObjArray localsByIndex, regionalsByIndex;
134 localsByIndex.SetOwner(kTRUE);
135 regionalsByIndex.SetOwner(kTRUE);
136 data.GetEvent(event);
137 AliMUONGlobalTrigger* globalByMethod = static_cast<AliMUONGlobalTrigger*>(data.GlobalTrigger()->Clone());
138 Int_t nlocals = data.NumberOfLocalTriggers();
139 for (Int_t i = 0; i < nlocals; i++)
140 {
141 localTrig = data.LocalTrigger(i);
142 localsByIndex.Add(localTrig->Clone());
143 }
144 Int_t nregionals = data.NumberOfRegionalTriggers();
145 for (Int_t i = 0; i < nregionals; i++)
146 {
147 regionalTrig = data.RegionalTrigger(i);
148 regionalsByIndex.Add(regionalTrig->Clone());
149 }
150
151 // Now check that all the lists of local, regional and global triggers
152 // contain the same results.
153 // They must. If they do not then something is wrong with the implementation
154 // of AliMUONMCDataInterface.
155 if (Compare(globalFromStore, globalByMethod) != 0)
156 {
157 Error( "SimTriggersOk",
158 "The AliMUONMCDataInterface does not return identical global"
159 " triggers through all its user interface methods."
160 );
161 globalFromStore->Print();
162 globalByMethod->Print();
163 return false;
164 }
165 delete globalFromStore;
166 delete globalByMethod;
167 if (localsFromStore.GetEntriesFast() != localsByIndex.GetEntriesFast())
168 {
169 Error( "SimTriggersOk",
170 "The AliMUONMCDataInterface does not return all the local triggers"
171 " correctly through all its user interface methods. We got the"
172 " following numbers of local triggers: %d and %d",
173 localsFromStore.GetEntriesFast(),
174 localsByIndex.GetEntriesFast()
175 );
176 return false;
177 }
178 if (regionalsFromStore.GetEntriesFast() != regionalsByIndex.GetEntriesFast())
179 {
180 Error( "SimTriggersOk",
181 "The AliMUONMCDataInterface does not return all the regional triggers"
182 " correctly through all its user interface methods. We got the"
183 " following numbers of regional triggers: %d and %d",
184 regionalsFromStore.GetEntriesFast(),
185 regionalsByIndex.GetEntriesFast()
186 );
187 return false;
188 }
189 for (Int_t i = 0; i < localsFromStore.GetEntriesFast(); i++)
190 {
191 if (Compare(localsFromStore[i], localsByIndex[i]) != 0)
192 {
193 Error( "SimTriggersOk",
194 "The AliMUONMCDataInterface does not return identical local"
195 " triggers through all its user interface methods. The"
196 " incorrect local trigger has index %d.",
197 i
198 );
199 localsFromStore[i]->Print();
200 localsByIndex[i]->Print();
201 return false;
202 }
203 }
204 for (Int_t i = 0; i < regionalsFromStore.GetEntriesFast(); i++)
205 {
206 if (Compare(regionalsFromStore[i], regionalsByIndex[i]) != 0)
207 {
208 Error( "SimTriggersOk",
209 "The AliMUONMCDataInterface does not return identical regional"
210 " triggers through all its user interface methods. The"
211 " incorrect regional trigger has index %d.",
212 i
213 );
214 regionalsFromStore[i]->Print();
215 regionalsByIndex[i]->Print();
216 return false;
217 }
22fbde16 218 regionalsFromStore[i]->Print();
219 regionalsByIndex[i]->Print();
220 }
221 }
222 return true;
223}
224
225/**
226 * This method fills internal arrays with s-digits returned by the AliMUONMCDataInterface.
227 * For each set of interface methods available a TObjArray is filled with copies of
228 * the s-digits. These arrays are sorted and then compared to each other. The arrays
229 * should contain the same s-digit information if everything is working correctly with
230 * AliMUONMCDataInterface. If not then the difference is printed together with an
231 * error message and false is returned.
232 */
233bool SimSDigitsOk()
234{
235 AliMUONMCDataInterface data("generated/galice.root");
236 for (Int_t event = 0; event < data.NumberOfEvents(); event++)
237 {
238 TObjArray digitsFromStore;
239 digitsFromStore.SetOwner(kTRUE);
240 AliMUONVDigitStore* store = data.SDigitStore(event);
241 if (store == NULL) return false;
242 TIter next(store->CreateIterator());
243 AliMUONVDigit* digit;
244 while ( (digit = static_cast<AliMUONVDigit*>( next() )) != NULL )
245 {
246 digitsFromStore.Add(digit->Clone());
247 }
248 digitsFromStore.Sort();
249
250 TObjArray digitsByDetElem;
251 digitsByDetElem.SetOwner(kTRUE);
252 data.GetEvent(event);
253 for (Int_t detElem = 0; detElem < 1500; detElem++)
254 {
255 if (! AliMpDEManager::IsValidDetElemId(detElem)) continue;
256 Int_t ndigits = data.NumberOfSDigits(detElem);
257 for (Int_t i = 0; i < ndigits; i++)
258 {
259 AliMUONVDigit* digit = data.SDigit(detElem, i);
260 digitsByDetElem.Add(digit->Clone());
261 }
262 }
263 digitsByDetElem.Sort();
264
265 TObjArray digitsByChamber;
266 digitsByChamber.SetOwner(kTRUE);
267 data.GetEvent(event);
268 for (Int_t chamber = 0; chamber < AliMpConstants::NofChambers(); chamber++)
269 for (Int_t cathode = 0; cathode < 2; cathode++)
270 {
271 Int_t ndigits = data.NumberOfSDigits(chamber, cathode);
272 for (Int_t i = 0; i < ndigits; i++)
273 {
274 AliMUONVDigit* digit = data.SDigit(chamber, cathode, i);
275 digitsByChamber.Add(digit->Clone());
276 }
277 }
278 digitsByChamber.Sort();
279
280 // Now check that all the lists of s-digits contain the same results.
281 // They must. If they do not then something is wrong with the implementation
282 // of AliMUONMCDataInterface.
283 if (digitsFromStore.GetEntriesFast() != digitsByDetElem.GetEntriesFast()
284 || digitsFromStore.GetEntriesFast() != digitsByChamber.GetEntriesFast())
285 {
286 Error( "SimSDigitsOk",
287 "The AliMUONMCDataInterface does not return all the s-digits correctly"
288 " through all its user interface methods. We got the following"
289 " numbers of s-digits: %d, %d and %d",
290 digitsFromStore.GetEntriesFast(),
291 digitsByDetElem.GetEntriesFast(),
292 digitsByChamber.GetEntriesFast()
293 );
294 return false;
295 }
296 for (Int_t i = 0; i < digitsFromStore.GetEntriesFast(); i++)
297 {
298 if (digitsFromStore[i]->Compare(digitsByDetElem[i]) != 0
299 || digitsFromStore[i]->Compare(digitsByChamber[i]) != 0)
300 {
301 Error( "SimSDigitsOk",
302 "The AliMUONMCDataInterface does not return identical s-digits"
303 " through all its user interface methods. The incorrect"
304 " s-digit has index %d after sorting.",
305 i
306 );
307 digitsFromStore[i]->Print();
308 digitsByChamber[i]->Print();
309 digitsByDetElem[i]->Print();
310 return false;
311 }
312 }
313 }
314 return true;
315}
316
317/**
318 * This method fills internal arrays with digits returned by the AliMUONMCDataInterface.
319 * For each set of interface methods available a TObjArray is filled with copies of
320 * the digits. These arrays are sorted and then compared to each other. The arrays
321 * should contain the same digit information if everything is working correctly with
322 * AliMUONMCDataInterface. If not then the difference is printed together with an
323 * error message and false is returned.
324 */
325bool SimDigitsOk()
326{
327 AliMUONMCDataInterface data("generated/galice.root");
328 for (Int_t event = 0; event < data.NumberOfEvents(); event++)
329 {
330 TObjArray digitsFromStore;
331 digitsFromStore.SetOwner(kTRUE);
332 AliMUONVDigitStore* store = data.DigitStore(event);
333 if (store == NULL) return false;
334 TIter next(store->CreateIterator());
335 AliMUONVDigit* digit;
336 while ( (digit = static_cast<AliMUONVDigit*>( next() )) != NULL )
337 {
338 digitsFromStore.Add(digit->Clone());
339 }
340 digitsFromStore.Sort();
341
342 TObjArray digitsByDetElem;
343 digitsByDetElem.SetOwner(kTRUE);
344 data.GetEvent(event);
345 for (Int_t detElem = 0; detElem < 1500; detElem++)
346 {
347 if (! AliMpDEManager::IsValidDetElemId(detElem)) continue;
348 Int_t ndigits = data.NumberOfDigits(detElem);
349 for (Int_t i = 0; i < ndigits; i++)
350 {
351 AliMUONVDigit* digit = data.Digit(detElem, i);
352 digitsByDetElem.Add(digit->Clone());
353 }
354 }
355 digitsByDetElem.Sort();
356
357 TObjArray digitsByChamber;
358 digitsByChamber.SetOwner(kTRUE);
359 data.GetEvent(event);
360 for (Int_t chamber = 0; chamber < AliMpConstants::NofChambers(); chamber++)
361 for (Int_t cathode = 0; cathode < 2; cathode++)
362 {
363 Int_t ndigits = data.NumberOfDigits(chamber, cathode);
364 for (Int_t i = 0; i < ndigits; i++)
365 {
366 AliMUONVDigit* digit = data.Digit(chamber, cathode, i);
367 digitsByChamber.Add(digit->Clone());
368 }
369 }
370 digitsByChamber.Sort();
371
372 // Now check that all the lists of digits contain the same results.
373 // They must. If they do not then something is wrong with the implementation
374 // of AliMUONMCDataInterface.
375 if (digitsFromStore.GetEntriesFast() != digitsByDetElem.GetEntriesFast()
376 || digitsFromStore.GetEntriesFast() != digitsByChamber.GetEntriesFast())
377 {
378 Error( "SimDigitsOk",
379 "The AliMUONMCDataInterface does not return all the digits correctly"
380 " through all its user interface methods. We got the following"
381 " numbers of digits: %d, %d and %d",
382 digitsFromStore.GetEntriesFast(),
383 digitsByDetElem.GetEntriesFast(),
384 digitsByChamber.GetEntriesFast()
385 );
386 return false;
387 }
388 for (Int_t i = 0; i < digitsFromStore.GetEntriesFast(); i++)
389 {
390 if (digitsFromStore[i]->Compare(digitsByDetElem[i]) != 0
391 || digitsFromStore[i]->Compare(digitsByChamber[i]) != 0)
392 {
393 Error( "SimDigitsOk",
394 "The AliMUONMCDataInterface does not return identical digits"
395 " through all its user interface methods. The incorrect"
396 " digit has index %d after sorting.",
397 i
398 );
399 digitsFromStore[i]->Print();
400 digitsByChamber[i]->Print();
401 digitsByDetElem[i]->Print();
402 return false;
403 }
404 }
405 }
406 return true;
407}
408
409/**
410 * This method fills internal arrays with hits returned by the AliMUONMCDataInterface.
411 * For each set of interface methods available a TObjArray is filled with copies of
412 * the hits. These arrays are then compared to each other. The arrays should contain
413 * the same hit information if everything is working correctly with AliMUONMCDataInterface.
414 * If not then the difference is printed together with an error message and false is returned.
415 */
416bool SimHitsOk()
417{
418 AliMUONMCDataInterface data("generated/galice.root");
419 for (Int_t event = 0; event < data.NumberOfEvents(); event++)
420 {
421 if (data.NumberOfTracks(event) != data.NumberOfTracks())
422 {
423 Error( "SimHitsOk",
424 "The AliMUONMCDataInterface does not return the same number of tracks"
425 " through all its user interface methods. We got the following"
426 " numbers of tracks: %d and %d",
427 data.NumberOfTracks(event),
428 data.NumberOfTracks()
429 );
430 return false;
431 }
432
433 for (Int_t track = 0; track < data.NumberOfTracks(); track++)
434 {
435 TObjArray hitsFromStore;
436 hitsFromStore.SetOwner(kTRUE);
437 AliMUONVHitStore* store = data.HitStore(event, track);
438 if (store == NULL) return false;
439 TIter next(store->CreateIterator());
440 AliMUONHit* hit;
441 while ( (hit = static_cast<AliMUONHit*>( next() )) != NULL )
442 {
443 hitsFromStore.Add(hit->Clone());
444 }
445 //hitsFromStore.Sort(); // Unfortunately hits do not implement the Compare method.
446
447 TObjArray hitsByMethod;
448 hitsByMethod.SetOwner(kTRUE);
449 data.GetEvent(event);
450 for (Int_t i = 0; i < data.NumberOfHits(track); i++)
451 {
452 AliMUONHit* hit = data.Hit(track, i);
453 hitsByMethod.Add(hit->Clone());
454 }
455 //hitsByMethod.Sort(); // Unfortunately hits do not implement the Compare method.
456
457 // Now check that both lists of hits contain the same results.
458 // They must. If they do not then something is wrong with the implementation
459 // of AliMUONMCDataInterface.
460 if (hitsFromStore.GetEntriesFast() != hitsByMethod.GetEntriesFast())
461 {
462 Error( "SimHitsOk",
463 "The AliMUONMCDataInterface does not return all the hits correctly"
464 " through all its user interface methods. We got the following"
465 " numbers of hits: %d and %d",
466 hitsFromStore.GetEntriesFast(),
467 hitsByMethod.GetEntriesFast()
468 );
469 return false;
470 }
471 for (Int_t i = 0; i < hitsFromStore.GetEntriesFast(); i++)
472 {
473 if (Compare(hitsFromStore[i], hitsByMethod[i]) != 0)
474 {
475 Error( "SimHitsOk",
476 "The AliMUONMCDataInterface does not return identical hits"
477 " through all its user interface methods. The incorrect"
478 " hit has index %d after sorting, for track %d.",
479 i, track
480 );
481 hitsFromStore[i]->Print();
482 hitsByMethod[i]->Print();
483 return false;
484 }
485 }
9b220edf 486 }
487 }
488 return true;
6ca54c85 489}
490
9b220edf 491/**
492 * This method fills internal arrays with digits returned by the AliMUONDataInterface.
493 * For each set of interface methods available a TObjArray is filled with copies of
494 * the digits. These arrays are sorted and then compared to each other. The arrays
495 * should contain the same digit information if everything is working correctly with
496 * AliMUONDataInterface. If not then the difference is printed together with an
22fbde16 497 * error message and false is returned.
9b220edf 498 */
499bool RecDigitsOk()
500{
501 AliMUONDataInterface data;
502 for (Int_t event = 0; event < data.NumberOfEvents(); event++)
503 {
504 TObjArray digitsFromStore;
505 digitsFromStore.SetOwner(kTRUE);
506 AliMUONVDigitStore* store = data.DigitStore(event);
22fbde16 507 if (store == NULL) return false;
9b220edf 508 TIter next(store->CreateIterator());
509 AliMUONVDigit* digit;
510 while ( (digit = static_cast<AliMUONVDigit*>( next() )) != NULL )
511 {
512 digitsFromStore.Add(digit->Clone());
513 }
514 digitsFromStore.Sort();
515
516 TObjArray digitsByDetElem;
517 digitsByDetElem.SetOwner(kTRUE);
518 data.GetEvent(event);
519 for (Int_t detElem = 0; detElem < 1500; detElem++)
520 {
521 if (! AliMpDEManager::IsValidDetElemId(detElem)) continue;
522 Int_t ndigits = data.NumberOfDigits(detElem);
523 for (Int_t i = 0; i < ndigits; i++)
524 {
525 AliMUONVDigit* digit = data.Digit(detElem, i);
526 digitsByDetElem.Add(digit->Clone());
527 }
528 }
529 digitsByDetElem.Sort();
530
531 TObjArray digitsByChamber;
532 digitsByChamber.SetOwner(kTRUE);
533 data.GetEvent(event);
534 for (Int_t chamber = 0; chamber < AliMpConstants::NofChambers(); chamber++)
535 for (Int_t cathode = 0; cathode < 2; cathode++)
536 {
537 Int_t ndigits = data.NumberOfDigits(chamber, cathode);
538 for (Int_t i = 0; i < ndigits; i++)
539 {
540 AliMUONVDigit* digit = data.Digit(chamber, cathode, i);
541 digitsByChamber.Add(digit->Clone());
542 }
543 }
544 digitsByChamber.Sort();
545
546 // Now check that all the lists of digits contain the same results.
547 // They must. If they do not then something is wrong with the implementation
548 // of AliMUONDataInterface.
549 if (digitsFromStore.GetEntriesFast() != digitsByDetElem.GetEntriesFast()
550 || digitsFromStore.GetEntriesFast() != digitsByChamber.GetEntriesFast())
551 {
552 Error( "RecDigitsOk",
553 "The AliMUONDataInterface does not return all the digits correctly"
554 " through all its user interface methods. We got the following"
555 " numbers of digits: %d, %d and %d",
556 digitsFromStore.GetEntriesFast(),
557 digitsByDetElem.GetEntriesFast(),
558 digitsByChamber.GetEntriesFast()
559 );
560 return false;
561 }
562 for (Int_t i = 0; i < digitsFromStore.GetEntriesFast(); i++)
563 {
564 if (digitsFromStore[i]->Compare(digitsByDetElem[i]) != 0
565 || digitsFromStore[i]->Compare(digitsByChamber[i]) != 0)
566 {
567 Error( "RecDigitsOk",
568 "The AliMUONDataInterface does not return identical digits"
569 " through all its user interface methods. The incorrect"
570 " digit has index %d after sorting.",
571 i
572 );
573 digitsFromStore[i]->Print();
574 digitsByChamber[i]->Print();
575 digitsByDetElem[i]->Print();
576 return false;
577 }
578 }
579 }
580 return true;
581}
6ca54c85 582
9b220edf 583/**
584 * This method fills internal arrays with raw clusters returned by AliMUONDataInterface.
585 * For each set of interface methods available in AliMUONDataInterface a TObjArray is
586 * filled with copies of the raw clusters. These arrays are sorted and then compared
587 * to each other. The arrays should contain the same information if everything is
588 * working correctly with AliMUONDataInterface. If not then the difference is printed
22fbde16 589 * together with an error message and false is returned.
9b220edf 590 */
591bool RawClustersOk()
6ca54c85 592{
9b220edf 593 AliMUONDataInterface data;
594 for (Int_t event = 0; event < data.NumberOfEvents(); event++)
6ca54c85 595 {
9b220edf 596 TObjArray clustersFromStore;
597 clustersFromStore.SetOwner(kTRUE);
598 AliMUONVClusterStore* store = data.ClusterStore(event);
22fbde16 599 if (store == NULL) return false;
9b220edf 600 TIter next(store->CreateIterator());
2060b217 601 AliMUONVCluster* cluster;
602 while ( (cluster = static_cast<AliMUONVCluster*>( next() )) != NULL )
9b220edf 603 {
604 clustersFromStore.Add(cluster->Clone());
605 }
606 clustersFromStore.Sort();
607
608 TObjArray clustersByChamber;
609 clustersByChamber.SetOwner(kTRUE);
610 data.GetEvent(event);
61fed964 611 for (Int_t chamber = 0; chamber < AliMpConstants::NofTrackingChambers(); chamber++)
9b220edf 612 {
613 Int_t nclusters = data.NumberOfRawClusters(chamber);
614 for (Int_t i = 0; i < nclusters; i++)
615 {
2060b217 616 AliMUONVCluster* cluster = data.RawCluster(chamber, i);
9b220edf 617 clustersByChamber.Add(cluster->Clone());
618 }
619 }
620 clustersByChamber.Sort();
621
622 // Now check that all the lists of clusters contain the same results.
623 // They must. If they do not then something is wrong with the implementation
624 // of AliMUONDataInterface.
625 if (clustersFromStore.GetEntriesFast() != clustersByChamber.GetEntriesFast())
626 {
627 Error( "RawClustersOk",
628 "The AliMUONDataInterface does not return all the clusters correctly"
629 " through all its user interface methods. We got the following"
630 " numbers of clusters: %d and %d",
631 clustersFromStore.GetEntriesFast(),
632 clustersByChamber.GetEntriesFast()
633 );
634 return false;
635 }
636 for (Int_t i = 0; i < clustersFromStore.GetEntriesFast(); i++)
637 {
638 if (clustersFromStore[i]->Compare(clustersByChamber[i]) != 0)
639 {
640 Error( "RawClustersOk",
641 "The AliMUONDataInterface does not return identical clusters"
642 " through all its user interface methods. The incorrect"
643 " cluster has index %d after sorting.",
644 i
645 );
646 clustersFromStore[i]->Print();
647 clustersByChamber[i]->Print();
648 return false;
649 }
650 }
651 }
652 return true;
6ca54c85 653}
654
9b220edf 655/**
9b220edf 656 * This method fills internal arrays with local and regional triggers returned
657 * by AliMUONDataInterface. For each set of interface methods available in
658 * AliMUONDataInterface a TObjArray is created for local and another for regional
659 * triggers. These arrays are filled with copies of the trigger objects.
660 * The global trigger object is also copied out using the 2 different methods.
661 * The arrays and objects are then compared to each other. The arrays and objects
662 * should contain the same information if everything is working correctly with
663 * AliMUONDataInterface. If not then the difference is printed together with an
22fbde16 664 * error message and false is returned.
9b220edf 665 */
666bool TriggersOk()
6ca54c85 667{
9b220edf 668 AliMUONDataInterface data;
669 for (Int_t event = 0; event < data.NumberOfEvents(); event++)
670 {
671 TObjArray localsFromStore, regionalsFromStore;
672 localsFromStore.SetOwner(kTRUE);
673 regionalsFromStore.SetOwner(kTRUE);
674 AliMUONVTriggerStore* store = data.TriggerStore(event);
22fbde16 675 if (store == NULL) return false;
9b220edf 676 AliMUONGlobalTrigger* globalFromStore = static_cast<AliMUONGlobalTrigger*>(store->Global()->Clone());
677 TIter nextLocal(store->CreateLocalIterator());
678 AliMUONLocalTrigger* localTrig;
679 while ( (localTrig = static_cast<AliMUONLocalTrigger*>( nextLocal() )) != NULL )
680 {
681 localsFromStore.Add(localTrig->Clone());
682 }
683 TIter nextRegional(store->CreateRegionalIterator());
684 AliMUONRegionalTrigger* regionalTrig;
685 while ( (regionalTrig = static_cast<AliMUONRegionalTrigger*>( nextRegional() )) != NULL )
686 {
687 regionalsFromStore.Add(regionalTrig->Clone());
688 }
689
690 TObjArray localsByIndex, regionalsByIndex;
691 localsByIndex.SetOwner(kTRUE);
692 regionalsByIndex.SetOwner(kTRUE);
693 data.GetEvent(event);
694 AliMUONGlobalTrigger* globalByMethod = static_cast<AliMUONGlobalTrigger*>(data.GlobalTrigger()->Clone());
695 Int_t nlocals = data.NumberOfLocalTriggers();
696 for (Int_t i = 0; i < nlocals; i++)
697 {
698 localTrig = data.LocalTrigger(i);
699 localsByIndex.Add(localTrig->Clone());
700 }
701 Int_t nregionals = data.NumberOfRegionalTriggers();
702 for (Int_t i = 0; i < nregionals; i++)
703 {
704 regionalTrig = data.RegionalTrigger(i);
705 regionalsByIndex.Add(regionalTrig->Clone());
706 }
707
708 // Now check that all the lists of local, regional and global triggers
709 // contain the same results.
710 // They must. If they do not then something is wrong with the implementation
711 // of AliMUONDataInterface.
712 if (Compare(globalFromStore, globalByMethod) != 0)
713 {
714 Error( "TriggersOk",
715 "The AliMUONDataInterface does not return identical global"
716 " triggers through all its user interface methods."
717 );
718 globalFromStore->Print();
719 globalByMethod->Print();
720 return false;
721 }
722 delete globalFromStore;
723 delete globalByMethod;
724 if (localsFromStore.GetEntriesFast() != localsByIndex.GetEntriesFast())
725 {
726 Error( "TriggersOk",
727 "The AliMUONDataInterface does not return all the local triggers"
728 " correctly through all its user interface methods. We got the"
729 " following numbers of local triggers: %d and %d",
730 localsFromStore.GetEntriesFast(),
731 localsByIndex.GetEntriesFast()
732 );
733 return false;
734 }
735 if (regionalsFromStore.GetEntriesFast() != regionalsByIndex.GetEntriesFast())
736 {
737 Error( "TriggersOk",
738 "The AliMUONDataInterface does not return all the regional triggers"
739 " correctly through all its user interface methods. We got the"
740 " following numbers of regional triggers: %d and %d",
741 regionalsFromStore.GetEntriesFast(),
742 regionalsByIndex.GetEntriesFast()
743 );
744 return false;
745 }
746 for (Int_t i = 0; i < localsFromStore.GetEntriesFast(); i++)
747 {
748 if (Compare(localsFromStore[i], localsByIndex[i]) != 0)
749 {
750 Error( "TriggersOk",
751 "The AliMUONDataInterface does not return identical local"
752 " triggers through all its user interface methods. The"
753 " incorrect local trigger has index %d.",
754 i
755 );
756 localsFromStore[i]->Print();
757 localsByIndex[i]->Print();
758 return false;
759 }
760 }
761 for (Int_t i = 0; i < regionalsFromStore.GetEntriesFast(); i++)
762 {
763 if (Compare(regionalsFromStore[i], regionalsByIndex[i]) != 0)
764 {
765 Error( "TriggersOk",
766 "The AliMUONDataInterface does not return identical regional"
767 " triggers through all its user interface methods. The"
768 " incorrect regional trigger has index %d.",
769 i
770 );
771 regionalsFromStore[i]->Print();
772 regionalsByIndex[i]->Print();
773 return false;
774 }
775 }
776 }
777 return true;
6ca54c85 778}
779
9b220edf 780/**
9b220edf 781 * This method performs a check of the AliMUONDataInterface and AliMUONMCDataInterface
782 * classes. Basically there are at least 2 ways to fetch data using these interfaces:
783 * The expert way using the store objects returned by these interface classes or
784 * the much slower but easier way of using the NumberOfxxx and Digit(...),
785 * RawCluster(...), Track(...) etc. methods to fetch individual data objects.
786 * The MUONCheckDI will check that all these various ways of fetching data results
787 * in the same information being returned. If yes then kTRUE is returned and a
788 * confirmation message is printed, if not then kFALSE is returned with the failure
789 * reason printed to screen.
790 */
22fbde16 791bool MUONCheckDI(bool checkSim = true, bool checkRec = true)
9b220edf 792{
22fbde16 793 AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT");
794
795 // Note: we do not bother checking the AliMUONMCDataInterface::Particle,
796 // AliMUONMCDataInterface::Stack and AliMUONMCDataInterface::TrackRefs methods
797 // because they are trivial enough to validate from a quick inspecition of
798 // the source code.
9b220edf 799
22fbde16 800 if (checkSim)
801 {
802 cout << "Checking simulated hits..." << endl;
803 if (! SimHitsOk()) return false;
804 cout << "Simulated hits look OK." << endl;
805
806 cout << "Checking simulated s-digits..." << endl;
807 if (! SimSDigitsOk()) return false;
808 cout << "Simulated s-digits look OK." << endl;
809
810 cout << "Checking simulated digits..." << endl;
811 if (! SimDigitsOk()) return false;
812 cout << "Simulated digits look OK." << endl;
813
814 cout << "Checking simulated triggers..." << endl;
815 if (! SimTriggersOk()) return false;
816 cout << "Simulated triggers look OK." << endl;
817 }
9b220edf 818
22fbde16 819 if (checkRec)
820 {
821 cout << "Checking reconstructed digits..." << endl;
822 if (! RecDigitsOk()) return false;
823 cout << "Reconstructed digits look OK." << endl;
824
825 cout << "Checking raw clusters..." << endl;
826 if (! RawClustersOk()) return false;
827 cout << "Raw clusters look OK." << endl;
828
829 cout << "Checking reconstructed triggers..." << endl;
830 if (! TriggersOk()) return false;
831 cout << "Reconstructed triggers look OK." << endl;
832 }
9b220edf 833
9b220edf 834 return true;
6ca54c85 835}