]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/MUONCheckDI.C
Initialisation.
[u/mrichter/AliRoot.git] / MUON / MUONCheckDI.C
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 //
19 // Macro for checking AliMUONDataInterface and AliMUONMCDataInterface.
20 // By Bruce Becker, DAPNIA/SPhN/CEA Saclay
21 //
22 // Modified to updated versions of data interfaces.
23 //  Artur Szostak <artursz@iafrica.com> (University of Cape Town)
24 //
25
26 #if !defined(__CINT__) || defined(__MAKECINT__)
27 #include <Rtypes.h>
28 #include <Riostream.h>
29 #include <TObjArray.h>
30 #include <TIterator.h>
31 #include <TMatrixD.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"
45 #include <cstdlib>
46 #endif
47
48
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  */
54 Int_t Compare(const TObject* a, const TObject* b)
55 {
56         int result = -999;
57         if (a->IsA() == AliMUONLocalTrigger::Class() && b->IsA() == AliMUONLocalTrigger::Class())
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         }
69         else
70         {
71                 result = memcmp(a, b, sizeof(TObject));
72         }
73         
74         if (result < 0) return -1;
75         if (result > 0) return 1;
76         return 0;
77 }
78
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  */
90 bool SimTriggersOk()
91 {
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;
201 }
202
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  */
211 bool 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 }
293
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  */
302 bool RawClustersOk()
303 {
304         AliMUONDataInterface data;
305         for (Int_t event = 0; event < data.NumberOfEvents(); event++)
306         {
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 )
313                 {
314                         clustersFromStore.Add(cluster->Clone());
315                 }
316                 clustersFromStore.Sort();
317                 
318                 TObjArray clustersByChamber;
319                 clustersByChamber.SetOwner(kTRUE);
320                 data.GetEvent(event);
321                 for (Int_t chamber = 0; chamber < AliMpConstants::NofTrackingChambers(); chamber++)
322                 {
323                         Int_t nclusters = data.NumberOfRawClusters(chamber);
324                         for (Int_t i = 0; i < nclusters; i++)
325                         {
326                                 AliMUONVCluster* cluster = data.RawCluster(chamber, i);
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;
363 }
364
365 /**
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  */
376 bool TriggersOk()
377 {
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;
487 }
488
489 /**
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  */
500 bool 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
515         cout << "Checking reconstructed triggers..." << endl;
516         if (! TriggersOk()) return false;
517         cout << "Reconstructed triggers look OK." << endl;
518
519         return true;
520 }