- Added track parameters at DCA in AliESDMuonTrack
[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
18//
9b220edf 19// Macro for checking AliMUONDataInterface and AliMUONMCDataInterface.
6ca54c85 20// By Bruce Becker, DAPNIA/SPhN/CEA Saclay
6ca54c85 21//
9b220edf 22// Modified to updated versions of data interfaces.
23// Artur Szostak <artursz@iafrica.com> (University of Cape Town)
24//
6ca54c85 25
9b220edf 26#if !defined(__CINT__) || defined(__MAKECINT__)
27#include <Rtypes.h>
28#include <Riostream.h>
29#include <TObjArray.h>
30#include <TIterator.h>
61fed964 31#include <TMatrixD.h>
6ca54c85 32#include "AliMUONHit.h"
9b220edf 33#include "AliMUONVDigit.h"
2060b217 34#include "AliMUONVCluster.h"
9b220edf 35#include "AliMUONLocalTrigger.h"
36#include "AliMUONRegionalTrigger.h"
37#include "AliMUONGlobalTrigger.h"
9b220edf 38#include "AliMUONMCDataInterface.h"
6ca54c85 39#include "AliMUONDataInterface.h"
9b220edf 40#include "AliMUONVDigitStore.h"
41#include "AliMUONVClusterStore.h"
9b220edf 42#include "AliMUONVTriggerStore.h"
9b220edf 43#include "AliMpConstants.h"
44#include "AliMpDEManager.h"
45#include <cstdlib>
6ca54c85 46#endif
47
48
9b220edf 49/**
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.
53 */
54Int_t Compare(const TObject* a, const TObject* b)
6ca54c85 55{
9b220edf 56 int result = -999;
61fed964 57 if (a->IsA() == AliMUONLocalTrigger::Class() && b->IsA() == AliMUONLocalTrigger::Class())
9b220edf 58 {
59 result = memcmp(a, b, sizeof(AliMUONLocalTrigger));
60 }
61 else if (a->IsA() == AliMUONRegionalTrigger::Class() && b->IsA() == AliMUONRegionalTrigger::Class())
62 {
63 result = memcmp(a, b, sizeof(AliMUONRegionalTrigger));
64 }
65 else if (a->IsA() == AliMUONGlobalTrigger::Class() && b->IsA() == AliMUONGlobalTrigger::Class())
66 {
67 result = memcmp(a, b, sizeof(AliMUONGlobalTrigger));
68 }
9b220edf 69 else
6ca54c85 70 {
9b220edf 71 result = memcmp(a, b, sizeof(TObject));
6ca54c85 72 }
9b220edf 73
74 if (result < 0) return -1;
75 if (result > 0) return 1;
76 return 0;
6ca54c85 77}
78
9b220edf 79/**
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.
89 */
90bool SimTriggersOk()
6ca54c85 91{
9b220edf 92 AliMUONMCDataInterface data;
93 for (Int_t event = 0; event < data.NumberOfEvents(); event++)
94 {
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 )
103 {
104 localsFromStore.Add(localTrig->Clone());
105 }
106 TIter nextRegional(store->CreateRegionalIterator());
107 AliMUONRegionalTrigger* regionalTrig;
108 while ( (regionalTrig = static_cast<AliMUONRegionalTrigger*>( nextRegional() )) != NULL )
109 {
110 regionalsFromStore.Add(regionalTrig->Clone());
111 }
112
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++)
120 {
121 localTrig = data.LocalTrigger(i);
122 localsByIndex.Add(localTrig->Clone());
123 }
124 Int_t nregionals = data.NumberOfRegionalTriggers();
125 for (Int_t i = 0; i < nregionals; i++)
126 {
127 regionalTrig = data.RegionalTrigger(i);
128 regionalsByIndex.Add(regionalTrig->Clone());
129 }
130
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)
136 {
137 Error( "SimTriggersOk",
138 "The AliMUONMCDataInterface does not return identical global"
139 " triggers through all its user interface methods."
140 );
141 globalFromStore->Print();
142 globalByMethod->Print();
143 return false;
144 }
145 delete globalFromStore;
146 delete globalByMethod;
147 if (localsFromStore.GetEntriesFast() != localsByIndex.GetEntriesFast())
148 {
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()
155 );
156 return false;
157 }
158 if (regionalsFromStore.GetEntriesFast() != regionalsByIndex.GetEntriesFast())
159 {
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()
166 );
167 return false;
168 }
169 for (Int_t i = 0; i < localsFromStore.GetEntriesFast(); i++)
170 {
171 if (Compare(localsFromStore[i], localsByIndex[i]) != 0)
172 {
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.",
177 i
178 );
179 localsFromStore[i]->Print();
180 localsByIndex[i]->Print();
181 return false;
182 }
183 }
184 for (Int_t i = 0; i < regionalsFromStore.GetEntriesFast(); i++)
185 {
186 if (Compare(regionalsFromStore[i], regionalsByIndex[i]) != 0)
187 {
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.",
192 i
193 );
194 regionalsFromStore[i]->Print();
195 regionalsByIndex[i]->Print();
196 return false;
197 }
198 }
199 }
200 return true;
6ca54c85 201}
202
9b220edf 203/**
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.
210 */
211bool RecDigitsOk()
212{
213 AliMUONDataInterface data;
214 for (Int_t event = 0; event < data.NumberOfEvents(); event++)
215 {
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 )
222 {
223 digitsFromStore.Add(digit->Clone());
224 }
225 digitsFromStore.Sort();
226
227 TObjArray digitsByDetElem;
228 digitsByDetElem.SetOwner(kTRUE);
229 data.GetEvent(event);
230 for (Int_t detElem = 0; detElem < 1500; detElem++)
231 {
232 if (! AliMpDEManager::IsValidDetElemId(detElem)) continue;
233 Int_t ndigits = data.NumberOfDigits(detElem);
234 for (Int_t i = 0; i < ndigits; i++)
235 {
236 AliMUONVDigit* digit = data.Digit(detElem, i);
237 digitsByDetElem.Add(digit->Clone());
238 }
239 }
240 digitsByDetElem.Sort();
241
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++)
247 {
248 Int_t ndigits = data.NumberOfDigits(chamber, cathode);
249 for (Int_t i = 0; i < ndigits; i++)
250 {
251 AliMUONVDigit* digit = data.Digit(chamber, cathode, i);
252 digitsByChamber.Add(digit->Clone());
253 }
254 }
255 digitsByChamber.Sort();
256
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())
262 {
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()
270 );
271 return false;
272 }
273 for (Int_t i = 0; i < digitsFromStore.GetEntriesFast(); i++)
274 {
275 if (digitsFromStore[i]->Compare(digitsByDetElem[i]) != 0
276 || digitsFromStore[i]->Compare(digitsByChamber[i]) != 0)
277 {
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.",
282 i
283 );
284 digitsFromStore[i]->Print();
285 digitsByChamber[i]->Print();
286 digitsByDetElem[i]->Print();
287 return false;
288 }
289 }
290 }
291 return true;
292}
6ca54c85 293
9b220edf 294/**
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.
301 */
302bool RawClustersOk()
6ca54c85 303{
9b220edf 304 AliMUONDataInterface data;
305 for (Int_t event = 0; event < data.NumberOfEvents(); event++)
6ca54c85 306 {
9b220edf 307 TObjArray clustersFromStore;
308 clustersFromStore.SetOwner(kTRUE);
309 AliMUONVClusterStore* store = data.ClusterStore(event);
310 TIter next(store->CreateIterator());
2060b217 311 AliMUONVCluster* cluster;
312 while ( (cluster = static_cast<AliMUONVCluster*>( next() )) != NULL )
9b220edf 313 {
314 clustersFromStore.Add(cluster->Clone());
315 }
316 clustersFromStore.Sort();
317
318 TObjArray clustersByChamber;
319 clustersByChamber.SetOwner(kTRUE);
320 data.GetEvent(event);
61fed964 321 for (Int_t chamber = 0; chamber < AliMpConstants::NofTrackingChambers(); chamber++)
9b220edf 322 {
323 Int_t nclusters = data.NumberOfRawClusters(chamber);
324 for (Int_t i = 0; i < nclusters; i++)
325 {
2060b217 326 AliMUONVCluster* cluster = data.RawCluster(chamber, i);
9b220edf 327 clustersByChamber.Add(cluster->Clone());
328 }
329 }
330 clustersByChamber.Sort();
331
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())
336 {
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()
343 );
344 return false;
345 }
346 for (Int_t i = 0; i < clustersFromStore.GetEntriesFast(); i++)
347 {
348 if (clustersFromStore[i]->Compare(clustersByChamber[i]) != 0)
349 {
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.",
354 i
355 );
356 clustersFromStore[i]->Print();
357 clustersByChamber[i]->Print();
358 return false;
359 }
360 }
361 }
362 return true;
6ca54c85 363}
364
9b220edf 365/**
9b220edf 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.
375 */
376bool TriggersOk()
6ca54c85 377{
9b220edf 378 AliMUONDataInterface data;
379 for (Int_t event = 0; event < data.NumberOfEvents(); event++)
380 {
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 )
389 {
390 localsFromStore.Add(localTrig->Clone());
391 }
392 TIter nextRegional(store->CreateRegionalIterator());
393 AliMUONRegionalTrigger* regionalTrig;
394 while ( (regionalTrig = static_cast<AliMUONRegionalTrigger*>( nextRegional() )) != NULL )
395 {
396 regionalsFromStore.Add(regionalTrig->Clone());
397 }
398
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++)
406 {
407 localTrig = data.LocalTrigger(i);
408 localsByIndex.Add(localTrig->Clone());
409 }
410 Int_t nregionals = data.NumberOfRegionalTriggers();
411 for (Int_t i = 0; i < nregionals; i++)
412 {
413 regionalTrig = data.RegionalTrigger(i);
414 regionalsByIndex.Add(regionalTrig->Clone());
415 }
416
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)
422 {
423 Error( "TriggersOk",
424 "The AliMUONDataInterface does not return identical global"
425 " triggers through all its user interface methods."
426 );
427 globalFromStore->Print();
428 globalByMethod->Print();
429 return false;
430 }
431 delete globalFromStore;
432 delete globalByMethod;
433 if (localsFromStore.GetEntriesFast() != localsByIndex.GetEntriesFast())
434 {
435 Error( "TriggersOk",
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()
441 );
442 return false;
443 }
444 if (regionalsFromStore.GetEntriesFast() != regionalsByIndex.GetEntriesFast())
445 {
446 Error( "TriggersOk",
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()
452 );
453 return false;
454 }
455 for (Int_t i = 0; i < localsFromStore.GetEntriesFast(); i++)
456 {
457 if (Compare(localsFromStore[i], localsByIndex[i]) != 0)
458 {
459 Error( "TriggersOk",
460 "The AliMUONDataInterface does not return identical local"
461 " triggers through all its user interface methods. The"
462 " incorrect local trigger has index %d.",
463 i
464 );
465 localsFromStore[i]->Print();
466 localsByIndex[i]->Print();
467 return false;
468 }
469 }
470 for (Int_t i = 0; i < regionalsFromStore.GetEntriesFast(); i++)
471 {
472 if (Compare(regionalsFromStore[i], regionalsByIndex[i]) != 0)
473 {
474 Error( "TriggersOk",
475 "The AliMUONDataInterface does not return identical regional"
476 " triggers through all its user interface methods. The"
477 " incorrect regional trigger has index %d.",
478 i
479 );
480 regionalsFromStore[i]->Print();
481 regionalsByIndex[i]->Print();
482 return false;
483 }
484 }
485 }
486 return true;
6ca54c85 487}
488
9b220edf 489/**
9b220edf 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.
499 */
500bool MUONCheckDI()
501{
502 // TODO: complete checking AliMUONMCDataInterface.
503 //cout << "Checking simulated triggers..." << endl;
504 //if (! SimTriggersOk()) return false;
505 //cout << "Simulated triggers look OK." << endl;
506
507 cout << "Checking reconstructed digits..." << endl;
508 if (! RecDigitsOk()) return false;
509 cout << "Reconstructed digits look OK." << endl;
510
511 cout << "Checking raw clusters..." << endl;
512 if (! RawClustersOk()) return false;
513 cout << "Raw clusters look OK." << endl;
514
9b220edf 515 cout << "Checking reconstructed triggers..." << endl;
516 if (! TriggersOk()) return false;
517 cout << "Reconstructed triggers look OK." << endl;
518
9b220edf 519 return true;
6ca54c85 520}