]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
Modified to updated versions of data interfaces.
authorivana <ivana@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 6 Aug 2007 13:38:16 +0000 (13:38 +0000)
committerivana <ivana@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 6 Aug 2007 13:38:16 +0000 (13:38 +0000)
(Artur)

MUON/MUONCheckDI.C

index 3ceba7cb81674b3c82dcd0f53db75e36c6c1af44..b5ad1febe6902f0f86b090cb9de08d2b0d4a80a6 100644 (file)
 /* $Id$ */
 
 //
-// Macro for checking aliroot output and associated files contents
-// with using AliMUONDataInterface
+// Macro for checking AliMUONDataInterface and AliMUONMCDataInterface.
 // By Bruce Becker, DAPNIA/SPhN/CEA Saclay
-// According to MUONCheck.C
 //
-#if !defined(__CINT__) || defined(__MAKECINT__)
-// ROOT includes
-#include "TBranch.h"
-#include "TClonesArray.h"
-#include "TFile.h"
-#include "TH1.h"
-#include "TParticle.h"
-#include "TTree.h"
-
-// STEER includes
-#include "AliRun.h"
-#include "AliRunLoader.h"
-#include "AliHeader.h"
-#include "AliLoader.h"
-#include "AliStack.h"
+// Modified to updated versions of data interfaces.
+//  Artur Szostak <artursz@iafrica.com> (University of Cape Town)
+//
 
-// MUON includes
-#include "AliMUON.h"
-#include "AliMUONData.h"
+#if !defined(__CINT__) || defined(__MAKECINT__)
+#include <Rtypes.h>
+#include <Riostream.h>
+#include <TObjArray.h>
+#include <TIterator.h>
 #include "AliMUONHit.h"
-#include "AliMUONConstants.h"
-#include "AliMUONDigit.h"
+#include "AliMUONVDigit.h"
 #include "AliMUONRawCluster.h"
-#include "AliMUONGlobalTrigger.h"
-#include "AliMUONLocalTrigger.h"
 #include "AliMUONTrack.h"
+#include "AliMUONLocalTrigger.h"
+#include "AliMUONRegionalTrigger.h"
+#include "AliMUONGlobalTrigger.h"
+#include "AliMUONTriggerTrack.h"
+#include "AliMUONMCDataInterface.h"
 #include "AliMUONDataInterface.h"
+#include "AliMUONVDigitStore.h"
+#include "AliMUONVClusterStore.h"
+#include "AliMUONVTrackStore.h"
+#include "AliMUONVTriggerStore.h"
+#include "AliMUONVTriggerTrackStore.h"
+#include "AliMpConstants.h"
+#include "AliMpDEManager.h"
+#include <cstdlib>
 #endif
 
 
-void MUONkine(char * filename="galice.root")
+/**
+ * This routine implements a the comparison functionality which is missing for
+ * classes like AliMUONTrack and the various AliMUONxxxTrigger classes.
+ * A result of -1 is returned if a < b, 0 if a == b and +1 if a > b.
+ */
+Int_t Compare(const TObject* a, const TObject* b)
 {
-  AliMUONDataInterface amdi;
-  amdi.SetFile(filename);
-  Int_t nevents = amdi.NumberOfEvents();
-  
-  for(Int_t ievent=0; ievent<nevents; ievent++) 
-    {  // Event loop
-      Int_t iparticle, nparticles;
-      // Getting event ievent
-      amdi.GetEvent(ievent); 
-      nparticles = amdi.NumberOfParticles();
-      printf(">>> Event %d, Number of particles is %d \n",ievent, nparticles);
-      for(iparticle=0; iparticle<nparticles; iparticle++) 
+       int result = -999;
+       if (a->IsA() == AliMUONTrack::Class() && b->IsA() == AliMUONTrack::Class())
+       {
+               const AliMUONTrack* ta = static_cast<const AliMUONTrack*>(a);
+               const AliMUONTrack* tb = static_cast<const AliMUONTrack*>(b);
+               if (ta->GetNTrackHits() < tb->GetNTrackHits()) return -1;
+               if (ta->GetNTrackHits() > tb->GetNTrackHits()) return 1;
+               if (ta->GetMatchTrigger() < tb->GetMatchTrigger()) return -1;
+               if (ta->GetMatchTrigger() > tb->GetMatchTrigger()) return 1;
+               if (ta->GetLoTrgNum() < tb->GetLoTrgNum()) return -1;
+               if (ta->GetLoTrgNum() > tb->GetLoTrgNum()) return 1;
+               if (ta->GetChi2MatchTrigger() < tb->GetChi2MatchTrigger()) return -1;
+               if (ta->GetChi2MatchTrigger() > tb->GetChi2MatchTrigger()) return 1;
+               const AliMUONTrackParam* tpa = static_cast<const AliMUONTrackParam*>(ta->GetTrackParamAtHit()->First());
+               const AliMUONTrackParam* tpb = static_cast<const AliMUONTrackParam*>(tb->GetTrackParamAtHit()->First());
+               if (tpa->GetNonBendingCoor() < tpb->GetNonBendingCoor()) return -1;
+               if (tpa->GetNonBendingCoor() > tpb->GetNonBendingCoor()) return 1;
+               if (tpa->GetNonBendingSlope() < tpb->GetNonBendingSlope()) return -1;
+               if (tpa->GetNonBendingSlope() > tpb->GetNonBendingSlope()) return 1;
+               if (tpa->GetBendingCoor() < tpb->GetBendingCoor()) return -1;
+               if (tpa->GetBendingCoor() > tpb->GetBendingCoor()) return 1;
+               if (tpa->GetBendingSlope() < tpb->GetBendingSlope()) return -1;
+               if (tpa->GetBendingSlope() > tpb->GetBendingSlope()) return 1;
+               if (tpa->GetInverseBendingMomentum() < tpb->GetInverseBendingMomentum()) return -1;
+               if (tpa->GetInverseBendingMomentum() > tpb->GetInverseBendingMomentum()) return 1;
+               if (tpa->GetCharge() < tpb->GetCharge()) return -1;
+               if (tpa->GetCharge() > tpb->GetCharge()) return 1;
+               return 0;
+       }
+       else if (a->IsA() == AliMUONLocalTrigger::Class() && b->IsA() == AliMUONLocalTrigger::Class())
+       {
+               result = memcmp(a, b, sizeof(AliMUONLocalTrigger));
+       }
+       else if (a->IsA() == AliMUONRegionalTrigger::Class() && b->IsA() == AliMUONRegionalTrigger::Class())
+       {
+               result = memcmp(a, b, sizeof(AliMUONRegionalTrigger));
+       }
+       else if (a->IsA() == AliMUONGlobalTrigger::Class() && b->IsA() == AliMUONGlobalTrigger::Class())
+       {
+               result = memcmp(a, b, sizeof(AliMUONGlobalTrigger));
+       }
+       else if (a->IsA() == AliMUONTriggerTrack::Class() && b->IsA() == AliMUONTriggerTrack::Class())
+       {
+               const AliMUONTriggerTrack* ta = static_cast<const AliMUONTriggerTrack*>(a);
+               const AliMUONTriggerTrack* tb = static_cast<const AliMUONTriggerTrack*>(b);
+               if (ta->GetX11() < tb->GetX11()) return -1;
+               if (ta->GetX11() > tb->GetX11()) return 1;
+               if (ta->GetY11() < tb->GetY11()) return -1;
+               if (ta->GetY11() > tb->GetY11()) return 1;
+               if (ta->GetThetax() < tb->GetThetax()) return -1;
+               if (ta->GetThetax() > tb->GetThetax()) return 1;
+               if (ta->GetThetay() < tb->GetThetay()) return -1;
+               if (ta->GetThetay() > tb->GetThetay()) return 1;
+               if (ta->GetLoTrgNum() < tb->GetLoTrgNum()) return -1;
+               if (ta->GetLoTrgNum() > tb->GetLoTrgNum()) return 1;
+               if (ta->GetGTPattern() < tb->GetGTPattern()) return -1;
+               if (ta->GetGTPattern() > tb->GetGTPattern()) return 1;
+               return 0;
+       }
+       else
        {
-       amdi.Particle(iparticle)->Print("");
+               result = memcmp(a, b, sizeof(TObject));
        }
-    }
+       
+       if (result < 0) return -1;
+       if (result > 0) return 1;
+       return 0;
 }
 
-
-void MUONhits(char * filename="galice.root")
+/**
+ * This method fills internal arrays with local and regional triggers returned
+ * by AliMUONMCDataInterface. For each set of interface methods available in
+ * AliMUONMCDataInterface a TObjArray is created for local and another for regional
+ * triggers. These arrays are filled with copies of the trigger objects.
+ * The global trigger object is also copied out using the 2 different methods.
+ * The arrays and objects are then compared to each other. The arrays and objects
+ * should contain the same information if everything is working correctly with
+ * AliMUONMCDataInterface. If not then the difference is printed together with an
+ * error message and kFALSE is returned.
+ */
+bool SimTriggersOk()
 {
-  
-  AliMUONDataInterface amdi;
-  amdi.SetFile(filename);
-  Int_t nevents = amdi.NumberOfEvents();
-  
-  for(Int_t ievent=0; ievent<nevents; ievent++) 
-    {  // Event loop
-      printf(">>> Event %d \n",ievent);
-      // Getting event ievent
-      amdi.GetEvent(ievent); 
-      Int_t ntracks = amdi.NumberOfTracks();
-      for (Int_t itrack=0; itrack<ntracks; itrack++) 
-       { // Track loop
-         printf(">>> Track %d \n",itrack);
-         //Getting List of Hits of Track itrack
-         // amdi.GetTrack(itrack); 
-         
-         Int_t ihit, nhits;
-         nhits = amdi.NumberOfHits(itrack);
-         printf(">>> Number of hits  %d \n",nhits);
-         AliMUONHit* mHit;
-         for(ihit=0; ihit<nhits; ihit++) 
-           {
-             mHit = amdi.Hit(itrack,ihit);
-             Int_t Nch      = mHit->Chamber();  // chamber number
-             Int_t detele   = mHit-> DetElemId(); // Detection element if defined
-             Int_t hittrack = mHit->Track();
-             Float_t x      = mHit->X();
-             Float_t y      = mHit->Y();
-             Float_t z      = mHit->Z();
-             Float_t elos   = mHit->Eloss();
-             // Float_t theta  = mHit->Theta();
-             // Float_t phi    = mHit->Phi();
-             Float_t momentum = mHit->Momentum();
-             printf(">>> Hit %2d Chamber %2d DetEle %4d Track %4d x %6.3f y %6.3f z %7.3f elos %g  momentum %5.3f\n",
-                    ihit, Nch, detele, hittrack,x,y,z,elos,momentum);
-           }
-       } // end track loop
-    }  // end event loop
+       AliMUONMCDataInterface data;
+       for (Int_t event = 0; event < data.NumberOfEvents(); event++)
+       {
+               TObjArray localsFromStore, regionalsFromStore;
+               localsFromStore.SetOwner(kTRUE);
+               regionalsFromStore.SetOwner(kTRUE);
+               AliMUONVTriggerStore* store = data.TriggerStore(event);
+               AliMUONGlobalTrigger* globalFromStore = static_cast<AliMUONGlobalTrigger*>(store->Global()->Clone());
+               TIter nextLocal(store->CreateLocalIterator());
+               AliMUONLocalTrigger* localTrig;
+               while ( (localTrig = static_cast<AliMUONLocalTrigger*>( nextLocal() )) != NULL )
+               {
+                       localsFromStore.Add(localTrig->Clone());
+               }
+               TIter nextRegional(store->CreateRegionalIterator());
+               AliMUONRegionalTrigger* regionalTrig;
+               while ( (regionalTrig = static_cast<AliMUONRegionalTrigger*>( nextRegional() )) != NULL )
+               {
+                       regionalsFromStore.Add(regionalTrig->Clone());
+               }
+               
+               TObjArray localsByIndex, regionalsByIndex;
+               localsByIndex.SetOwner(kTRUE);
+               regionalsByIndex.SetOwner(kTRUE);
+               data.GetEvent(event);
+               AliMUONGlobalTrigger* globalByMethod = static_cast<AliMUONGlobalTrigger*>(data.GlobalTrigger()->Clone());
+               Int_t nlocals = data.NumberOfLocalTriggers();
+               for (Int_t i = 0; i < nlocals; i++)
+               {
+                       localTrig = data.LocalTrigger(i);
+                       localsByIndex.Add(localTrig->Clone());
+               }
+               Int_t nregionals = data.NumberOfRegionalTriggers();
+               for (Int_t i = 0; i < nregionals; i++)
+               {
+                       regionalTrig = data.RegionalTrigger(i);
+                       regionalsByIndex.Add(regionalTrig->Clone());
+               }
+               
+               // Now check that all the lists of local, regional and global triggers
+               // contain the same results.
+               // They must. If they do not then something is wrong with the implementation
+               // of AliMUONMCDataInterface.
+               if (Compare(globalFromStore, globalByMethod) != 0)
+               {
+                       Error(  "SimTriggersOk",
+                               "The AliMUONMCDataInterface does not return identical global"
+                                 " triggers through all its user interface methods."
+                       );
+                       globalFromStore->Print();
+                       globalByMethod->Print();
+                       return false;
+               }
+               delete globalFromStore;
+               delete globalByMethod;
+               if (localsFromStore.GetEntriesFast() != localsByIndex.GetEntriesFast())
+               {
+                       Error(  "SimTriggersOk",
+                               "The AliMUONMCDataInterface does not return all the local triggers"
+                                 " correctly through all its user interface methods. We got the"
+                                 " following numbers of local triggers: %d and %d",
+                               localsFromStore.GetEntriesFast(),
+                               localsByIndex.GetEntriesFast()
+                       );
+                       return false;
+               }
+               if (regionalsFromStore.GetEntriesFast() != regionalsByIndex.GetEntriesFast())
+               {
+                       Error(  "SimTriggersOk",
+                               "The AliMUONMCDataInterface does not return all the regional triggers"
+                                 " correctly through all its user interface methods. We got the"
+                                 " following numbers of regional triggers: %d and %d",
+                               regionalsFromStore.GetEntriesFast(),
+                               regionalsByIndex.GetEntriesFast()
+                       );
+                       return false;
+               }
+               for (Int_t i = 0; i < localsFromStore.GetEntriesFast(); i++)
+               {
+                       if (Compare(localsFromStore[i], localsByIndex[i]) != 0)
+                       {
+                               Error(  "SimTriggersOk",
+                                       "The AliMUONMCDataInterface does not return identical local"
+                                         " triggers through all its user interface methods. The"
+                                         " incorrect local trigger has index %d.",
+                                       i
+                               );
+                               localsFromStore[i]->Print();
+                               localsByIndex[i]->Print();
+                               return false;
+                       }
+               }
+               for (Int_t i = 0; i < regionalsFromStore.GetEntriesFast(); i++)
+               {
+                       if (Compare(regionalsFromStore[i], regionalsByIndex[i]) != 0)
+                       {
+                               Error(  "SimTriggersOk",
+                                       "The AliMUONMCDataInterface does not return identical regional"
+                                         " triggers through all its user interface methods. The"
+                                         " incorrect regional trigger has index %d.",
+                                       i
+                               );
+                               regionalsFromStore[i]->Print();
+                               regionalsByIndex[i]->Print();
+                               return false;
+                       }
+               }
+       }
+       return true;
 }
 
+/**
+ * This method fills internal arrays with digits returned by the AliMUONDataInterface.
+ * For each set of interface methods available a TObjArray is filled with copies of 
+ * the digits. These arrays are sorted and then compared to each other. The arrays
+ * should contain the same digit information if everything is working correctly with
+ * AliMUONDataInterface. If not then the difference is printed together with an
+ * error message and kFALSE is returned.
+ */
+bool RecDigitsOk()
+{
+       AliMUONDataInterface data;
+       for (Int_t event = 0; event < data.NumberOfEvents(); event++)
+       {
+               TObjArray digitsFromStore;
+               digitsFromStore.SetOwner(kTRUE);
+               AliMUONVDigitStore* store = data.DigitStore(event);
+               TIter next(store->CreateIterator());
+               AliMUONVDigit* digit;
+               while ( (digit = static_cast<AliMUONVDigit*>( next() )) != NULL )
+               {
+                       digitsFromStore.Add(digit->Clone());
+               }
+               digitsFromStore.Sort();
+               
+               TObjArray digitsByDetElem;
+               digitsByDetElem.SetOwner(kTRUE);
+               data.GetEvent(event);
+               for (Int_t detElem = 0; detElem < 1500; detElem++)
+               {
+                       if (! AliMpDEManager::IsValidDetElemId(detElem)) continue;
+                       Int_t ndigits = data.NumberOfDigits(detElem);
+                       for (Int_t i = 0; i < ndigits; i++)
+                       {
+                               AliMUONVDigit* digit = data.Digit(detElem, i);
+                               digitsByDetElem.Add(digit->Clone());
+                       }
+               }
+               digitsByDetElem.Sort();
+               
+               TObjArray digitsByChamber;
+               digitsByChamber.SetOwner(kTRUE);
+               data.GetEvent(event);
+               for (Int_t chamber = 0; chamber < AliMpConstants::NofChambers(); chamber++)
+               for (Int_t cathode = 0; cathode < 2; cathode++)
+               {
+                       Int_t ndigits = data.NumberOfDigits(chamber, cathode);
+                       for (Int_t i = 0; i < ndigits; i++)
+                       {
+                               AliMUONVDigit* digit = data.Digit(chamber, cathode, i);
+                               digitsByChamber.Add(digit->Clone());
+                       }
+               }
+               digitsByChamber.Sort();
+               
+               // Now check that all the lists of digits contain the same results.
+               // They must. If they do not then something is wrong with the implementation
+               // of AliMUONDataInterface.
+               if (digitsFromStore.GetEntriesFast() != digitsByDetElem.GetEntriesFast()
+                   || digitsFromStore.GetEntriesFast() != digitsByChamber.GetEntriesFast())
+               {
+                       Error(  "RecDigitsOk",
+                               "The AliMUONDataInterface does not return all the digits correctly"
+                                 " through all its user interface methods. We got the following"
+                                 " numbers of digits: %d, %d and %d",
+                               digitsFromStore.GetEntriesFast(),
+                               digitsByDetElem.GetEntriesFast(),
+                               digitsByChamber.GetEntriesFast()
+                       );
+                       return false;
+               }
+               for (Int_t i = 0; i < digitsFromStore.GetEntriesFast(); i++)
+               {
+                       if (digitsFromStore[i]->Compare(digitsByDetElem[i]) != 0
+                           || digitsFromStore[i]->Compare(digitsByChamber[i]) != 0)
+                       {
+                               Error(  "RecDigitsOk",
+                                       "The AliMUONDataInterface does not return identical digits"
+                                         " through all its user interface methods. The incorrect"
+                                         " digit has index %d after sorting.",
+                                       i
+                               );
+                               digitsFromStore[i]->Print();
+                               digitsByChamber[i]->Print();
+                               digitsByDetElem[i]->Print();
+                               return false;
+                       }
+               }
+       }
+       return true;
+}
 
-void MUONdigits(char * filename="galice.root")
+/**
+ * This method fills internal arrays with raw clusters returned by AliMUONDataInterface.
+ * For each set of interface methods available in AliMUONDataInterface a TObjArray is
+ * filled with copies of the raw clusters. These arrays are sorted and then compared
+ * to each other. The arrays should contain the same information if everything is
+ * working correctly with AliMUONDataInterface. If not then the difference is printed
+ * together with an error message and kFALSE is returned.
+ */
+bool RawClustersOk()
 {
-  
-  AliMUONDataInterface amdi;
-  amdi.SetFile(filename);
-  Int_t ievent, nevents;
-  nevents = amdi.NumberOfEvents();
-  AliMUONDigit * mDigit;
-  
-  for(ievent=0; ievent<nevents; ievent++) 
-    {
-      printf(">>> Event %d \n",ievent);
-      amdi.GetEvent(ievent);
-      
-      // Addressing
-      Int_t ichamber, nchambers;
-      nchambers = AliMUONConstants::NCh(); ;
-      
-      //      Int_t icathode, ncathodes;
-      //      ncathodes=2;
-      for( ichamber=0; ichamber<nchambers; ichamber++) 
+       AliMUONDataInterface data;
+       for (Int_t event = 0; event < data.NumberOfEvents(); event++)
        {
-         printf(">>> Chamber %d\n",ichamber+1);
-         
-         Int_t idigit, ndigits;
-         ndigits = amdi.NumberOfDigits(ichamber,0); // second parameter here is cathode...
-         
-         for(idigit=0; idigit<ndigits; idigit++) 
-           {
-             mDigit = amdi.Digit(ichamber,0,idigit);
-             Int_t PadX   = mDigit->PadX();     // Pad X number
-             Int_t PadY   = mDigit->PadY();     // Pad Y number
-             Int_t Signal = mDigit->Charge();   // Physics Signal
-             Int_t Physics= mDigit->Physics();  // Physics contribution to signal
-             Int_t Hit    = mDigit->Hit();      // iHit
-             Int_t Cathode= mDigit->Cathode();  // Cathode
-             Int_t Track0 = mDigit->Track(0);
-             Int_t Track1 = mDigit->Track(1); 
-             Int_t Track2 = mDigit->Track(2);
-             Int_t TCharges0 = mDigit->TrackCharge(0);  //charge per track making this digit (up to 10)
-             Int_t TCharges1 = mDigit->TrackCharge(1);
-             Int_t TCharges2 = mDigit->TrackCharge(2);
-             Int_t idDE = mDigit->DetElemId();
-             //          printf(">>> Cathode %d\n",Cathode);
-             
-             printf(">>>IdDE %d Digit %4d cathode %1d hit %4d PadX %3d PadY %3d Signal %4d Physics %4d Track0 %4d TrackCharge0 %4d Track1 %4d TrackCharge1 %4d Track2 %4d TrackCharge2 %4d \n",
-                    idDE, idigit, Cathode,Hit, PadX, PadY, Signal, Physics, Track0, 
-                    TCharges0, Track1, TCharges1, Track2, TCharges2);
-           } // end digit loop
-       } // end chamber loop
-    }  // end event loop
+               TObjArray clustersFromStore;
+               clustersFromStore.SetOwner(kTRUE);
+               AliMUONVClusterStore* store = data.ClusterStore(event);
+               TIter next(store->CreateIterator());
+               AliMUONRawCluster* cluster;
+               while ( (cluster = static_cast<AliMUONRawCluster*>( next() )) != NULL )
+               {
+                       clustersFromStore.Add(cluster->Clone());
+               }
+               clustersFromStore.Sort();
+               
+               TObjArray clustersByChamber;
+               clustersByChamber.SetOwner(kTRUE);
+               data.GetEvent(event);
+               for (Int_t chamber = 0; chamber < AliMpConstants::NofChambers(); chamber++)
+               {
+                       Int_t nclusters = data.NumberOfRawClusters(chamber);
+                       for (Int_t i = 0; i < nclusters; i++)
+                       {
+                               AliMUONRawCluster* cluster = data.RawCluster(chamber, i);
+                               clustersByChamber.Add(cluster->Clone());
+                       }
+               }
+               clustersByChamber.Sort();
+               
+               // Now check that all the lists of clusters contain the same results.
+               // They must. If they do not then something is wrong with the implementation
+               // of AliMUONDataInterface.
+               if (clustersFromStore.GetEntriesFast() != clustersByChamber.GetEntriesFast())
+               {
+                       Error(  "RawClustersOk",
+                               "The AliMUONDataInterface does not return all the clusters correctly"
+                                 " through all its user interface methods. We got the following"
+                                 " numbers of clusters: %d and %d",
+                               clustersFromStore.GetEntriesFast(),
+                               clustersByChamber.GetEntriesFast()
+                       );
+                       return false;
+               }
+               for (Int_t i = 0; i < clustersFromStore.GetEntriesFast(); i++)
+               {
+                       if (clustersFromStore[i]->Compare(clustersByChamber[i]) != 0)
+                       {
+                               Error(  "RawClustersOk",
+                                       "The AliMUONDataInterface does not return identical clusters"
+                                         " through all its user interface methods. The incorrect"
+                                         " cluster has index %d after sorting.",
+                                       i
+                               );
+                               clustersFromStore[i]->Print();
+                               clustersByChamber[i]->Print();
+                               return false;
+                       }
+               }
+       }
+       return true;
 }
 
-void MUONrecpoints(char * filename="galice.root") 
+/**
+ * This method fills internal arrays with tracks returned by AliMUONDataInterface.
+ * For each set of interface methods available in AliMUONDataInterface a TObjArray is
+ * filled with copies of the raw clusters. These arrays are then compared to each
+ * other. The arrays should contain the same information if everything is working
+ * correctly with AliMUONDataInterface. If not then the difference is printed
+ * together with an error message and kFALSE is returned.
+ */
+bool TracksOk()
 {
-  AliMUONDataInterface amdi;
-  amdi.SetFile(filename);
-  
-  Int_t ievent, nevents;
-  nevents = amdi.NumberOfEvents();
-  AliMUONRawCluster * mRecPoint = 0;
-  
-  for(ievent=0; ievent<nevents; ievent++) 
-    {
-      printf(">>> Event %d \n",ievent);
-      amdi.GetEvent(ievent);
-      Int_t ichamber, nchambers;
-      nchambers = AliMUONConstants::NTrackingCh();
-      // Loop on chambers
-      for( ichamber=0; ichamber<nchambers; ichamber++) 
+       AliMUONDataInterface data;
+       for (Int_t event = 0; event < data.NumberOfEvents(); event++)
        {
-         printf(">>> Chamber %d\n",ichamber);
-         Int_t irecpoint, nrecpoints;
-         nrecpoints = amdi.NumberOfRawClusters(ichamber);
-         printf("number of recpoints = %6d \n",nrecpoints);
-         for(irecpoint=0; irecpoint<nrecpoints; irecpoint++) 
-           {
-             mRecPoint = amdi.RawCluster(ichamber,irecpoint);
-             //     Int_t       fTracks[3];        //labels of overlapped tracks
-             //     Int_t       fQ[2]  ;           // Q of cluster (in ADC counts)     
-             //     Float_t     fX[2]  ;           // X of cluster
-             //     Float_t     fY[2]  ;           // Y of cluster
-             //     Float_t     fZ[2]  ;           // Z of cluster
-             //     Int_t       fPeakSignal[2];    // Peak signal 
-             //     Int_t       fIndexMap[50][2];  // indeces of digits
-             //     Int_t       fOffsetMap[50][2]; // Emmanuel special
-             //     Float_t     fContMap[50][2];   // Contribution from digit
-             //     Int_t       fPhysicsMap[50];   // Distinguish signal and background contr.
-             //     Int_t       fMultiplicity[2];  // Cluster multiplicity
-             //     Int_t       fNcluster[2];      // Number of clusters
-             //     Int_t       fClusterType;      // Cluster type
-             //     Float_t     fChi2[2];          // Chi**2 of fit
-             //     Int_t       fGhost;            // 0 if not a ghost or ghost problem solved
-             //                                    // >0 if ghost problem remains because
-             //                                    // 1 both (true and ghost) satify 
-             //                                    //   charge chi2 compatibility
-             //                                    // 2 none give satisfactory chi2
-             
-             Int_t Track0 = mRecPoint->GetTrack(0);
-             Int_t Track1 = mRecPoint->GetTrack(1); 
-             Int_t Track2 = mRecPoint->GetTrack(2);
-             Int_t Q0 = mRecPoint->GetCharge(0);
-             Int_t Q1 = mRecPoint->GetCharge(1);
-             Float_t x0 = mRecPoint->GetX(0);
-             Float_t x1 = mRecPoint->GetX(1);
-             Float_t y0 = mRecPoint->GetY(0);
-             Float_t y1 = mRecPoint->GetY(1);
-             Float_t z0 = mRecPoint->GetZ(0);
-             Float_t z1 = mRecPoint->GetZ(1);
-             Float_t chi2_0 =  mRecPoint->GetChi2(0);
-             Float_t chi2_1 =  mRecPoint->GetChi2(1);
-             Int_t de = mRecPoint->GetDetElemId();
-             printf(">>> RecPoint %4d  DetElem %2d x %6.3f %6.3f y %6.3f %6.3f z %6.3f %6.3f Q0 %4d  Q1 %4d Hit %4d Track1 %4d Track2 %4d Chi2 %6.3f %6.3f \n",
-                    irecpoint,de,x0,x1,y0,y1,z0,z1,Q0,Q1,Track0, Track1, Track2, chi2_0, chi2_1);
-           } // end recpoint loop
-       } // end chamber loop
-    }  // end event loop
+               TObjArray tracksFromStore;
+               tracksFromStore.SetOwner(kTRUE);
+               AliMUONVTrackStore* store = data.TrackStore(event);
+               TIter next(store->CreateIterator());
+               AliMUONTrack* track;
+               while ( (track = static_cast<AliMUONTrack*>( next() )) != NULL )
+               {
+                       tracksFromStore.Add(track->Clone());
+               }
+               
+               TObjArray tracksByIndex;
+               tracksByIndex.SetOwner(kTRUE);
+               data.GetEvent(event);
+               Int_t ntracks = data.NumberOfTracks();
+               for (Int_t i = 0; i < ntracks; i++)
+               {
+                       AliMUONTrack* track = data.Track(i);
+                       tracksByIndex.Add(track->Clone());
+               }
+               
+               // Now check that all the lists of tracks contain the same results.
+               // They must. If they do not then something is wrong with the implementation
+               // of AliMUONDataInterface.
+               if (tracksFromStore.GetEntriesFast() != tracksByIndex.GetEntriesFast())
+               {
+                       Error(  "TracksOk",
+                               "The AliMUONDataInterface does not return all the tracks correctly"
+                                 " through all its user interface methods. We got the following"
+                                 " numbers of tracks: %d and %d",
+                               tracksFromStore.GetEntriesFast(),
+                               tracksByIndex.GetEntriesFast()
+                       );
+                       return false;
+               }
+               for (Int_t i = 0; i < tracksFromStore.GetEntriesFast(); i++)
+               {
+                       if (Compare(tracksFromStore[i], tracksByIndex[i]) != 0)
+                       {
+                               Error(  "TracksOk",
+                                       "The AliMUONDataInterface does not return identical tracks"
+                                         " through all its user interface methods. The incorrect"
+                                         " track has index %d.",
+                                       i
+                               );
+                               tracksFromStore[i]->Print();
+                               tracksByIndex[i]->Print();
+                               return false;
+                       }
+               }
+       }
+       return true;
 }
 
-void MUONTestTrigger (char * filename="galice.root")
+/**
+ * This method fills internal arrays with local and regional triggers returned
+ * by AliMUONDataInterface. For each set of interface methods available in
+ * AliMUONDataInterface a TObjArray is created for local and another for regional
+ * triggers. These arrays are filled with copies of the trigger objects.
+ * The global trigger object is also copied out using the 2 different methods.
+ * The arrays and objects are then compared to each other. The arrays and objects
+ * should contain the same information if everything is working correctly with
+ * AliMUONDataInterface. If not then the difference is printed together with an
+ * error message and kFALSE is returned.
+ */
+bool TriggersOk()
 {
-  // reads and dumps trigger objects from MUON.RecPoints.root
-  
-  AliMUONDataInterface amdi;
-  amdi.SetFile(filename);
-  
-  Int_t ievent, nevents;
-  nevents = amdi.NumberOfEvents();
-  
-  AliMUONGlobalTrigger *gloTrg;
-  AliMUONLocalTrigger *locTrg;
-  
-  for (ievent=0; ievent<nevents; ievent++) 
-    {
-      amdi.GetEvent(ievent);
-      Int_t nglobals = amdi.NumberOfGlobalTriggers(); // should be 1
-      Int_t nlocals  = amdi.NumberOfLocalTriggers(); // up to 234
-      printf("###################################################\n");
-      cout << " event " << ievent 
-          << " nglobals nlocals: " << nglobals << " " << nlocals << "\n"; 
-      
-      for (Int_t iglobal=0; iglobal<nglobals; iglobal++) 
-       { // Global Trigger
-         gloTrg = amdi.GlobalTrigger(iglobal);
-         
-         printf("===================================================\n");
-         printf(" Global Trigger output       Low pt  High pt   All\n");
-         printf(" number of Single Plus      :\t");
-         printf("%i\t%i\t%i\t",gloTrg->SinglePlusLpt(),
-                gloTrg->SinglePlusHpt(),gloTrg->SinglePlusApt());
-         printf("\n");
-         printf(" number of Single Minus     :\t");
-         printf("%i\t%i\t%i\t",gloTrg->SingleMinusLpt(),
-                gloTrg->SingleMinusHpt(),gloTrg->SingleMinusApt());
-         printf("\n");
-         printf(" number of Single Undefined :\t"); 
-         printf("%i\t%i\t%i\t",gloTrg->SingleUndefLpt(),
-                gloTrg->SingleUndefHpt(),gloTrg->SingleUndefApt());
-         printf("\n");
-         printf(" number of UnlikeSign pair  :\t"); 
-         printf("%i\t%i\t%i\t",gloTrg->PairUnlikeLpt(),
-                gloTrg->PairUnlikeHpt(),gloTrg->PairUnlikeApt());
-         printf("\n");
-         printf(" number of LikeSign pair    :\t");  
-         printf("%i\t%i\t%i\t",gloTrg->PairLikeLpt(),
-                gloTrg->PairLikeHpt(),gloTrg->PairLikeApt());
-         printf("\n");
-         printf("===================================================\n");
-         
-       } // end of loop on Global Trigger
-      
-      for (Int_t ilocal=0; ilocal<nlocals; ilocal++) 
-       { // Local Trigger
-         cout << " >>> Output for Local Trigger " << ilocal << "\n";
-         locTrg = amdi.LocalTrigger(ilocal);
-         cout << "Circuit StripX Dev StripY: " 
-              << locTrg->LoCircuit() << " " 
-              << locTrg->LoStripX() << " " 
-              << locTrg->LoDev() << " " 
-              << locTrg->LoStripY() 
-              << "\n";
-         cout << "Lpt Hpt Apt: "     
-              << locTrg->LoLpt() << " "   
-              << locTrg->LoHpt() << " "  
-              << locTrg->LoApt() << "\n";
-         
-       } // end of loop on Local Trigger
-    } // end loop on event  
+       AliMUONDataInterface data;
+       for (Int_t event = 0; event < data.NumberOfEvents(); event++)
+       {
+               TObjArray localsFromStore, regionalsFromStore;
+               localsFromStore.SetOwner(kTRUE);
+               regionalsFromStore.SetOwner(kTRUE);
+               AliMUONVTriggerStore* store = data.TriggerStore(event);
+               AliMUONGlobalTrigger* globalFromStore = static_cast<AliMUONGlobalTrigger*>(store->Global()->Clone());
+               TIter nextLocal(store->CreateLocalIterator());
+               AliMUONLocalTrigger* localTrig;
+               while ( (localTrig = static_cast<AliMUONLocalTrigger*>( nextLocal() )) != NULL )
+               {
+                       localsFromStore.Add(localTrig->Clone());
+               }
+               TIter nextRegional(store->CreateRegionalIterator());
+               AliMUONRegionalTrigger* regionalTrig;
+               while ( (regionalTrig = static_cast<AliMUONRegionalTrigger*>( nextRegional() )) != NULL )
+               {
+                       regionalsFromStore.Add(regionalTrig->Clone());
+               }
+               
+               TObjArray localsByIndex, regionalsByIndex;
+               localsByIndex.SetOwner(kTRUE);
+               regionalsByIndex.SetOwner(kTRUE);
+               data.GetEvent(event);
+               AliMUONGlobalTrigger* globalByMethod = static_cast<AliMUONGlobalTrigger*>(data.GlobalTrigger()->Clone());
+               Int_t nlocals = data.NumberOfLocalTriggers();
+               for (Int_t i = 0; i < nlocals; i++)
+               {
+                       localTrig = data.LocalTrigger(i);
+                       localsByIndex.Add(localTrig->Clone());
+               }
+               Int_t nregionals = data.NumberOfRegionalTriggers();
+               for (Int_t i = 0; i < nregionals; i++)
+               {
+                       regionalTrig = data.RegionalTrigger(i);
+                       regionalsByIndex.Add(regionalTrig->Clone());
+               }
+               
+               // Now check that all the lists of local, regional and global triggers
+               // contain the same results.
+               // They must. If they do not then something is wrong with the implementation
+               // of AliMUONDataInterface.
+               if (Compare(globalFromStore, globalByMethod) != 0)
+               {
+                       Error(  "TriggersOk",
+                               "The AliMUONDataInterface does not return identical global"
+                                 " triggers through all its user interface methods."
+                       );
+                       globalFromStore->Print();
+                       globalByMethod->Print();
+                       return false;
+               }
+               delete globalFromStore;
+               delete globalByMethod;
+               if (localsFromStore.GetEntriesFast() != localsByIndex.GetEntriesFast())
+               {
+                       Error(  "TriggersOk",
+                               "The AliMUONDataInterface does not return all the local triggers"
+                                 " correctly through all its user interface methods. We got the"
+                                 " following numbers of local triggers: %d and %d",
+                               localsFromStore.GetEntriesFast(),
+                               localsByIndex.GetEntriesFast()
+                       );
+                       return false;
+               }
+               if (regionalsFromStore.GetEntriesFast() != regionalsByIndex.GetEntriesFast())
+               {
+                       Error(  "TriggersOk",
+                               "The AliMUONDataInterface does not return all the regional triggers"
+                                 " correctly through all its user interface methods. We got the"
+                                 " following numbers of regional triggers: %d and %d",
+                               regionalsFromStore.GetEntriesFast(),
+                               regionalsByIndex.GetEntriesFast()
+                       );
+                       return false;
+               }
+               for (Int_t i = 0; i < localsFromStore.GetEntriesFast(); i++)
+               {
+                       if (Compare(localsFromStore[i], localsByIndex[i]) != 0)
+                       {
+                               Error(  "TriggersOk",
+                                       "The AliMUONDataInterface does not return identical local"
+                                         " triggers through all its user interface methods. The"
+                                         " incorrect local trigger has index %d.",
+                                       i
+                               );
+                               localsFromStore[i]->Print();
+                               localsByIndex[i]->Print();
+                               return false;
+                       }
+               }
+               for (Int_t i = 0; i < regionalsFromStore.GetEntriesFast(); i++)
+               {
+                       if (Compare(regionalsFromStore[i], regionalsByIndex[i]) != 0)
+                       {
+                               Error(  "TriggersOk",
+                                       "The AliMUONDataInterface does not return identical regional"
+                                         " triggers through all its user interface methods. The"
+                                         " incorrect regional trigger has index %d.",
+                                       i
+                               );
+                               regionalsFromStore[i]->Print();
+                               regionalsByIndex[i]->Print();
+                               return false;
+                       }
+               }
+       }
+       return true;
 }
 
-void MUONRecTracks (char * filename="galice.root")
+/**
+ * This method fills internal arrays with trigger tracks returned by AliMUONDataInterface.
+ * For each set of interface methods available in AliMUONDataInterface a TObjArray is
+ * filled with copies of the trigger tracks. These arrays are then compared to each
+ * other. The arrays should contain the same information if everything is working
+ * correctly with AliMUONDataInterface. If not then the difference is printed
+ * together with an error message and kFALSE is returned.
+ */
+bool TriggerTracksOk()
 {
-  
-  // reads and dumps trigger objects from MUON.RecPoints.root
-  AliMUONDataInterface amdi;
-  amdi.SetFile(filename);
-  AliMUONTrack* rectrack;
-  AliMUONTrackParam* trackparam;
-  Double_t x,y,z;
-  Int_t ievent, nevents;
-  nevents = amdi.NumberOfEvents();
-  
-  
-  for (ievent=0; ievent<nevents; ievent++) 
-    {
-      amdi.GetEvent(ievent);
-      Int_t nrectracks = amdi.NumberOfRecTracks(); 
-      printf(">>> Event %d Number of Recconstructed tracks %d \n",ievent, nrectracks);
-      // loop over rec tracks and print vertex parameters
-      for(Int_t rectracki=0; rectracki < nrectracks;rectracki++)
+       AliMUONDataInterface data;
+       for (Int_t event = 0; event < data.NumberOfEvents(); event++)
        {
-         rectrack  = amdi.RecTrack(rectracki);
-         trackparam = rectrack->GetTrackParamAtVertex(); // meaningless since the vertex is not known at the tracking level
-         x = trackparam->GetNonBendingCoor();
-         y = trackparam->GetBendingCoor();
-         z = trackparam->GetZ();
-         printf("Track Vertex : (x,y,z) = (%f,%f,%f \n",x,y,z);
-       } // end of loop over tracks
-    } // end loop on event  
+               TObjArray tracksFromStore;
+               tracksFromStore.SetOwner(kTRUE);
+               AliMUONVTriggerTrackStore* store = data.TriggerTrackStore(event);
+               TIter next(store->CreateIterator());
+               AliMUONTriggerTrack* track;
+               while ( (track = static_cast<AliMUONTriggerTrack*>( next() )) != NULL )
+               {
+                       tracksFromStore.Add(track->Clone());
+               }
+               
+               TObjArray tracksByIndex;
+               tracksByIndex.SetOwner(kTRUE);
+               data.GetEvent(event);
+               Int_t ntracks = data.NumberOfTriggerTracks();
+               for (Int_t i = 0; i < ntracks; i++)
+               {
+                       AliMUONTriggerTrack* track = data.TriggerTrack(i);
+                       tracksByIndex.Add(track->Clone());
+               }
+               
+               // Now check that all the lists of trigger tracks contain the same results.
+               // They must. If they do not then something is wrong with the implementation
+               // of AliMUONDataInterface.
+               if (tracksFromStore.GetEntriesFast() != tracksByIndex.GetEntriesFast())
+               {
+                       Error(  "TriggerTracksOk",
+                               "The AliMUONDataInterface does not return all the trigger tracks"
+                                 " correctly through all its user interface methods. We got the"
+                                 " following numbers of tracks: %d and %d",
+                               tracksFromStore.GetEntriesFast(),
+                               tracksByIndex.GetEntriesFast()
+                       );
+                       return false;
+               }
+               for (Int_t i = 0; i < tracksFromStore.GetEntriesFast(); i++)
+               {
+                       if (Compare(tracksFromStore[i], tracksByIndex[i]) != 0)
+                       {
+                               Error(  "TriggerTracksOk",
+                                       "The AliMUONDataInterface does not return identical trigger"
+                                         " tracks through all its user interface methods. The"
+                                         " incorrect track has index %d.",
+                                       i
+                               );
+                               tracksFromStore[i]->Print();
+                               tracksByIndex[i]->Print();
+                               return false;
+                       }
+               }
+       }
+       return true;
+}
+
+/**
+ * This method performs a check of the AliMUONDataInterface and AliMUONMCDataInterface
+ * classes. Basically there are at least 2 ways to fetch data using these interfaces:
+ * The expert way using the store objects returned by these interface classes or
+ * the much slower but easier way of using the NumberOfxxx and Digit(...),
+ * RawCluster(...), Track(...) etc. methods to fetch individual data objects.
+ * The MUONCheckDI will check that all these various ways of fetching data results
+ * in the same information being returned. If yes then kTRUE is returned and a
+ * confirmation message is printed, if not then kFALSE is returned with the failure
+ * reason printed to screen.
+ */
+bool MUONCheckDI()
+{
+       // TODO: complete checking AliMUONMCDataInterface.
+       //cout << "Checking simulated triggers..." << endl;
+       //if (! SimTriggersOk()) return false;
+       //cout << "Simulated triggers look OK." << endl;
+       
+       cout << "Checking reconstructed digits..." << endl;
+       if (! RecDigitsOk()) return false;
+       cout << "Reconstructed digits look OK." << endl;
+       
+       cout << "Checking raw clusters..." << endl;
+       if (! RawClustersOk()) return false;
+       cout << "Raw clusters look OK." << endl;
+
+       cout << "Checking reconstructed tracks..." << endl;
+       if (! TracksOk()) return false;
+       cout << "Reconstructed tracks look OK." << endl;
+
+       cout << "Checking reconstructed triggers..." << endl;
+       if (! TriggersOk()) return false;
+       cout << "Reconstructed triggers look OK." << endl;
+
+       cout << "Checking reconstructed trigger tracks..." << endl;
+       if (! TriggerTracksOk()) return false;
+       cout << "Reconstructed trigger tracks look OK." << endl;
+       
+       return true;
 }