1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
19 // Macro for checking AliMUONDataInterface and AliMUONMCDataInterface.
20 // By Bruce Becker, DAPNIA/SPhN/CEA Saclay
22 // Modified to updated versions of data interfaces.
23 // Artur Szostak <artursz@iafrica.com> (University of Cape Town)
26 #if !defined(__CINT__) || defined(__MAKECINT__)
28 #include <Riostream.h>
29 #include <TObjArray.h>
30 #include <TIterator.h>
32 #include "AliMUONHit.h"
33 #include "AliMUONVDigit.h"
34 #include "AliMUONVCluster.h"
35 #include "AliMUONLocalTrigger.h"
36 #include "AliMUONRegionalTrigger.h"
37 #include "AliMUONGlobalTrigger.h"
38 #include "AliMUONMCDataInterface.h"
39 #include "AliMUONDataInterface.h"
40 #include "AliMUONVDigitStore.h"
41 #include "AliMUONVClusterStore.h"
42 #include "AliMUONVTriggerStore.h"
43 #include "AliMpConstants.h"
44 #include "AliMpDEManager.h"
50 * This routine implements a the comparison functionality which is missing for
51 * classes like AliMUONTrack and the various AliMUONxxxTrigger classes.
52 * A result of -1 is returned if a < b, 0 if a == b and +1 if a > b.
54 Int_t Compare(const TObject* a, const TObject* b)
57 if (a->IsA() == AliMUONLocalTrigger::Class() && b->IsA() == AliMUONLocalTrigger::Class())
59 result = memcmp(a, b, sizeof(AliMUONLocalTrigger));
61 else if (a->IsA() == AliMUONRegionalTrigger::Class() && b->IsA() == AliMUONRegionalTrigger::Class())
63 result = memcmp(a, b, sizeof(AliMUONRegionalTrigger));
65 else if (a->IsA() == AliMUONGlobalTrigger::Class() && b->IsA() == AliMUONGlobalTrigger::Class())
67 result = memcmp(a, b, sizeof(AliMUONGlobalTrigger));
71 result = memcmp(a, b, sizeof(TObject));
74 if (result < 0) return -1;
75 if (result > 0) return 1;
80 * This method fills internal arrays with local and regional triggers returned
81 * by AliMUONMCDataInterface. For each set of interface methods available in
82 * AliMUONMCDataInterface a TObjArray is created for local and another for regional
83 * triggers. These arrays are filled with copies of the trigger objects.
84 * The global trigger object is also copied out using the 2 different methods.
85 * The arrays and objects are then compared to each other. The arrays and objects
86 * should contain the same information if everything is working correctly with
87 * AliMUONMCDataInterface. If not then the difference is printed together with an
88 * error message and kFALSE is returned.
92 AliMUONMCDataInterface data;
93 for (Int_t event = 0; event < data.NumberOfEvents(); event++)
95 TObjArray localsFromStore, regionalsFromStore;
96 localsFromStore.SetOwner(kTRUE);
97 regionalsFromStore.SetOwner(kTRUE);
98 AliMUONVTriggerStore* store = data.TriggerStore(event);
99 AliMUONGlobalTrigger* globalFromStore = static_cast<AliMUONGlobalTrigger*>(store->Global()->Clone());
100 TIter nextLocal(store->CreateLocalIterator());
101 AliMUONLocalTrigger* localTrig;
102 while ( (localTrig = static_cast<AliMUONLocalTrigger*>( nextLocal() )) != NULL )
104 localsFromStore.Add(localTrig->Clone());
106 TIter nextRegional(store->CreateRegionalIterator());
107 AliMUONRegionalTrigger* regionalTrig;
108 while ( (regionalTrig = static_cast<AliMUONRegionalTrigger*>( nextRegional() )) != NULL )
110 regionalsFromStore.Add(regionalTrig->Clone());
113 TObjArray localsByIndex, regionalsByIndex;
114 localsByIndex.SetOwner(kTRUE);
115 regionalsByIndex.SetOwner(kTRUE);
116 data.GetEvent(event);
117 AliMUONGlobalTrigger* globalByMethod = static_cast<AliMUONGlobalTrigger*>(data.GlobalTrigger()->Clone());
118 Int_t nlocals = data.NumberOfLocalTriggers();
119 for (Int_t i = 0; i < nlocals; i++)
121 localTrig = data.LocalTrigger(i);
122 localsByIndex.Add(localTrig->Clone());
124 Int_t nregionals = data.NumberOfRegionalTriggers();
125 for (Int_t i = 0; i < nregionals; i++)
127 regionalTrig = data.RegionalTrigger(i);
128 regionalsByIndex.Add(regionalTrig->Clone());
131 // Now check that all the lists of local, regional and global triggers
132 // contain the same results.
133 // They must. If they do not then something is wrong with the implementation
134 // of AliMUONMCDataInterface.
135 if (Compare(globalFromStore, globalByMethod) != 0)
137 Error( "SimTriggersOk",
138 "The AliMUONMCDataInterface does not return identical global"
139 " triggers through all its user interface methods."
141 globalFromStore->Print();
142 globalByMethod->Print();
145 delete globalFromStore;
146 delete globalByMethod;
147 if (localsFromStore.GetEntriesFast() != localsByIndex.GetEntriesFast())
149 Error( "SimTriggersOk",
150 "The AliMUONMCDataInterface does not return all the local triggers"
151 " correctly through all its user interface methods. We got the"
152 " following numbers of local triggers: %d and %d",
153 localsFromStore.GetEntriesFast(),
154 localsByIndex.GetEntriesFast()
158 if (regionalsFromStore.GetEntriesFast() != regionalsByIndex.GetEntriesFast())
160 Error( "SimTriggersOk",
161 "The AliMUONMCDataInterface does not return all the regional triggers"
162 " correctly through all its user interface methods. We got the"
163 " following numbers of regional triggers: %d and %d",
164 regionalsFromStore.GetEntriesFast(),
165 regionalsByIndex.GetEntriesFast()
169 for (Int_t i = 0; i < localsFromStore.GetEntriesFast(); i++)
171 if (Compare(localsFromStore[i], localsByIndex[i]) != 0)
173 Error( "SimTriggersOk",
174 "The AliMUONMCDataInterface does not return identical local"
175 " triggers through all its user interface methods. The"
176 " incorrect local trigger has index %d.",
179 localsFromStore[i]->Print();
180 localsByIndex[i]->Print();
184 for (Int_t i = 0; i < regionalsFromStore.GetEntriesFast(); i++)
186 if (Compare(regionalsFromStore[i], regionalsByIndex[i]) != 0)
188 Error( "SimTriggersOk",
189 "The AliMUONMCDataInterface does not return identical regional"
190 " triggers through all its user interface methods. The"
191 " incorrect regional trigger has index %d.",
194 regionalsFromStore[i]->Print();
195 regionalsByIndex[i]->Print();
204 * This method fills internal arrays with digits returned by the AliMUONDataInterface.
205 * For each set of interface methods available a TObjArray is filled with copies of
206 * the digits. These arrays are sorted and then compared to each other. The arrays
207 * should contain the same digit information if everything is working correctly with
208 * AliMUONDataInterface. If not then the difference is printed together with an
209 * error message and kFALSE is returned.
213 AliMUONDataInterface data;
214 for (Int_t event = 0; event < data.NumberOfEvents(); event++)
216 TObjArray digitsFromStore;
217 digitsFromStore.SetOwner(kTRUE);
218 AliMUONVDigitStore* store = data.DigitStore(event);
219 TIter next(store->CreateIterator());
220 AliMUONVDigit* digit;
221 while ( (digit = static_cast<AliMUONVDigit*>( next() )) != NULL )
223 digitsFromStore.Add(digit->Clone());
225 digitsFromStore.Sort();
227 TObjArray digitsByDetElem;
228 digitsByDetElem.SetOwner(kTRUE);
229 data.GetEvent(event);
230 for (Int_t detElem = 0; detElem < 1500; detElem++)
232 if (! AliMpDEManager::IsValidDetElemId(detElem)) continue;
233 Int_t ndigits = data.NumberOfDigits(detElem);
234 for (Int_t i = 0; i < ndigits; i++)
236 AliMUONVDigit* digit = data.Digit(detElem, i);
237 digitsByDetElem.Add(digit->Clone());
240 digitsByDetElem.Sort();
242 TObjArray digitsByChamber;
243 digitsByChamber.SetOwner(kTRUE);
244 data.GetEvent(event);
245 for (Int_t chamber = 0; chamber < AliMpConstants::NofChambers(); chamber++)
246 for (Int_t cathode = 0; cathode < 2; cathode++)
248 Int_t ndigits = data.NumberOfDigits(chamber, cathode);
249 for (Int_t i = 0; i < ndigits; i++)
251 AliMUONVDigit* digit = data.Digit(chamber, cathode, i);
252 digitsByChamber.Add(digit->Clone());
255 digitsByChamber.Sort();
257 // Now check that all the lists of digits contain the same results.
258 // They must. If they do not then something is wrong with the implementation
259 // of AliMUONDataInterface.
260 if (digitsFromStore.GetEntriesFast() != digitsByDetElem.GetEntriesFast()
261 || digitsFromStore.GetEntriesFast() != digitsByChamber.GetEntriesFast())
263 Error( "RecDigitsOk",
264 "The AliMUONDataInterface does not return all the digits correctly"
265 " through all its user interface methods. We got the following"
266 " numbers of digits: %d, %d and %d",
267 digitsFromStore.GetEntriesFast(),
268 digitsByDetElem.GetEntriesFast(),
269 digitsByChamber.GetEntriesFast()
273 for (Int_t i = 0; i < digitsFromStore.GetEntriesFast(); i++)
275 if (digitsFromStore[i]->Compare(digitsByDetElem[i]) != 0
276 || digitsFromStore[i]->Compare(digitsByChamber[i]) != 0)
278 Error( "RecDigitsOk",
279 "The AliMUONDataInterface does not return identical digits"
280 " through all its user interface methods. The incorrect"
281 " digit has index %d after sorting.",
284 digitsFromStore[i]->Print();
285 digitsByChamber[i]->Print();
286 digitsByDetElem[i]->Print();
295 * This method fills internal arrays with raw clusters returned by AliMUONDataInterface.
296 * For each set of interface methods available in AliMUONDataInterface a TObjArray is
297 * filled with copies of the raw clusters. These arrays are sorted and then compared
298 * to each other. The arrays should contain the same information if everything is
299 * working correctly with AliMUONDataInterface. If not then the difference is printed
300 * together with an error message and kFALSE is returned.
304 AliMUONDataInterface data;
305 for (Int_t event = 0; event < data.NumberOfEvents(); event++)
307 TObjArray clustersFromStore;
308 clustersFromStore.SetOwner(kTRUE);
309 AliMUONVClusterStore* store = data.ClusterStore(event);
310 TIter next(store->CreateIterator());
311 AliMUONVCluster* cluster;
312 while ( (cluster = static_cast<AliMUONVCluster*>( next() )) != NULL )
314 clustersFromStore.Add(cluster->Clone());
316 clustersFromStore.Sort();
318 TObjArray clustersByChamber;
319 clustersByChamber.SetOwner(kTRUE);
320 data.GetEvent(event);
321 for (Int_t chamber = 0; chamber < AliMpConstants::NofTrackingChambers(); chamber++)
323 Int_t nclusters = data.NumberOfRawClusters(chamber);
324 for (Int_t i = 0; i < nclusters; i++)
326 AliMUONVCluster* cluster = data.RawCluster(chamber, i);
327 clustersByChamber.Add(cluster->Clone());
330 clustersByChamber.Sort();
332 // Now check that all the lists of clusters contain the same results.
333 // They must. If they do not then something is wrong with the implementation
334 // of AliMUONDataInterface.
335 if (clustersFromStore.GetEntriesFast() != clustersByChamber.GetEntriesFast())
337 Error( "RawClustersOk",
338 "The AliMUONDataInterface does not return all the clusters correctly"
339 " through all its user interface methods. We got the following"
340 " numbers of clusters: %d and %d",
341 clustersFromStore.GetEntriesFast(),
342 clustersByChamber.GetEntriesFast()
346 for (Int_t i = 0; i < clustersFromStore.GetEntriesFast(); i++)
348 if (clustersFromStore[i]->Compare(clustersByChamber[i]) != 0)
350 Error( "RawClustersOk",
351 "The AliMUONDataInterface does not return identical clusters"
352 " through all its user interface methods. The incorrect"
353 " cluster has index %d after sorting.",
356 clustersFromStore[i]->Print();
357 clustersByChamber[i]->Print();
366 * This method fills internal arrays with local and regional triggers returned
367 * by AliMUONDataInterface. For each set of interface methods available in
368 * AliMUONDataInterface a TObjArray is created for local and another for regional
369 * triggers. These arrays are filled with copies of the trigger objects.
370 * The global trigger object is also copied out using the 2 different methods.
371 * The arrays and objects are then compared to each other. The arrays and objects
372 * should contain the same information if everything is working correctly with
373 * AliMUONDataInterface. If not then the difference is printed together with an
374 * error message and kFALSE is returned.
378 AliMUONDataInterface data;
379 for (Int_t event = 0; event < data.NumberOfEvents(); event++)
381 TObjArray localsFromStore, regionalsFromStore;
382 localsFromStore.SetOwner(kTRUE);
383 regionalsFromStore.SetOwner(kTRUE);
384 AliMUONVTriggerStore* store = data.TriggerStore(event);
385 AliMUONGlobalTrigger* globalFromStore = static_cast<AliMUONGlobalTrigger*>(store->Global()->Clone());
386 TIter nextLocal(store->CreateLocalIterator());
387 AliMUONLocalTrigger* localTrig;
388 while ( (localTrig = static_cast<AliMUONLocalTrigger*>( nextLocal() )) != NULL )
390 localsFromStore.Add(localTrig->Clone());
392 TIter nextRegional(store->CreateRegionalIterator());
393 AliMUONRegionalTrigger* regionalTrig;
394 while ( (regionalTrig = static_cast<AliMUONRegionalTrigger*>( nextRegional() )) != NULL )
396 regionalsFromStore.Add(regionalTrig->Clone());
399 TObjArray localsByIndex, regionalsByIndex;
400 localsByIndex.SetOwner(kTRUE);
401 regionalsByIndex.SetOwner(kTRUE);
402 data.GetEvent(event);
403 AliMUONGlobalTrigger* globalByMethod = static_cast<AliMUONGlobalTrigger*>(data.GlobalTrigger()->Clone());
404 Int_t nlocals = data.NumberOfLocalTriggers();
405 for (Int_t i = 0; i < nlocals; i++)
407 localTrig = data.LocalTrigger(i);
408 localsByIndex.Add(localTrig->Clone());
410 Int_t nregionals = data.NumberOfRegionalTriggers();
411 for (Int_t i = 0; i < nregionals; i++)
413 regionalTrig = data.RegionalTrigger(i);
414 regionalsByIndex.Add(regionalTrig->Clone());
417 // Now check that all the lists of local, regional and global triggers
418 // contain the same results.
419 // They must. If they do not then something is wrong with the implementation
420 // of AliMUONDataInterface.
421 if (Compare(globalFromStore, globalByMethod) != 0)
424 "The AliMUONDataInterface does not return identical global"
425 " triggers through all its user interface methods."
427 globalFromStore->Print();
428 globalByMethod->Print();
431 delete globalFromStore;
432 delete globalByMethod;
433 if (localsFromStore.GetEntriesFast() != localsByIndex.GetEntriesFast())
436 "The AliMUONDataInterface does not return all the local triggers"
437 " correctly through all its user interface methods. We got the"
438 " following numbers of local triggers: %d and %d",
439 localsFromStore.GetEntriesFast(),
440 localsByIndex.GetEntriesFast()
444 if (regionalsFromStore.GetEntriesFast() != regionalsByIndex.GetEntriesFast())
447 "The AliMUONDataInterface does not return all the regional triggers"
448 " correctly through all its user interface methods. We got the"
449 " following numbers of regional triggers: %d and %d",
450 regionalsFromStore.GetEntriesFast(),
451 regionalsByIndex.GetEntriesFast()
455 for (Int_t i = 0; i < localsFromStore.GetEntriesFast(); i++)
457 if (Compare(localsFromStore[i], localsByIndex[i]) != 0)
460 "The AliMUONDataInterface does not return identical local"
461 " triggers through all its user interface methods. The"
462 " incorrect local trigger has index %d.",
465 localsFromStore[i]->Print();
466 localsByIndex[i]->Print();
470 for (Int_t i = 0; i < regionalsFromStore.GetEntriesFast(); i++)
472 if (Compare(regionalsFromStore[i], regionalsByIndex[i]) != 0)
475 "The AliMUONDataInterface does not return identical regional"
476 " triggers through all its user interface methods. The"
477 " incorrect regional trigger has index %d.",
480 regionalsFromStore[i]->Print();
481 regionalsByIndex[i]->Print();
490 * This method performs a check of the AliMUONDataInterface and AliMUONMCDataInterface
491 * classes. Basically there are at least 2 ways to fetch data using these interfaces:
492 * The expert way using the store objects returned by these interface classes or
493 * the much slower but easier way of using the NumberOfxxx and Digit(...),
494 * RawCluster(...), Track(...) etc. methods to fetch individual data objects.
495 * The MUONCheckDI will check that all these various ways of fetching data results
496 * in the same information being returned. If yes then kTRUE is returned and a
497 * confirmation message is printed, if not then kFALSE is returned with the failure
498 * reason printed to screen.
502 // TODO: complete checking AliMUONMCDataInterface.
503 //cout << "Checking simulated triggers..." << endl;
504 //if (! SimTriggersOk()) return false;
505 //cout << "Simulated triggers look OK." << endl;
507 cout << "Checking reconstructed digits..." << endl;
508 if (! RecDigitsOk()) return false;
509 cout << "Reconstructed digits look OK." << endl;
511 cout << "Checking raw clusters..." << endl;
512 if (! RawClustersOk()) return false;
513 cout << "Raw clusters look OK." << endl;
515 cout << "Checking reconstructed triggers..." << endl;
516 if (! TriggersOk()) return false;
517 cout << "Reconstructed triggers look OK." << endl;