X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=MUON%2FMUONCheckDI.C;h=8dfd2681766b597505349695804e6c5c22ce60e5;hb=5e1b07ea46e07f006543afbccafb9ae7072a93c3;hp=3ceba7cb81674b3c82dcd0f53db75e36c6c1af44;hpb=5ca1e61a61d076bce7718cc10d0c81bd1073f997;p=u%2Fmrichter%2FAliRoot.git diff --git a/MUON/MUONCheckDI.C b/MUON/MUONCheckDI.C index 3ceba7cb816..8dfd2681766 100644 --- a/MUON/MUONCheckDI.C +++ b/MUON/MUONCheckDI.C @@ -15,324 +15,821 @@ /* $Id$ */ -// -// Macro for checking aliroot output and associated files contents -// with using AliMUONDataInterface -// 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" +/// \ingroup macros +/// \file MUONCheckDI.C +/// \brief Macro for checking AliMUONDataInterface and AliMUONMCDataInterface. +/// +/// \author Bruce Becker, DAPNIA/SPhN/CEA Saclay +/// +/// Modified to updated versions of data interfaces +/// by Artur Szostak (University of Cape Town) -// MUON includes -#include "AliMUON.h" -#include "AliMUONData.h" +#if !defined(__CINT__) || defined(__MAKECINT__) #include "AliMUONHit.h" -#include "AliMUONConstants.h" -#include "AliMUONDigit.h" -#include "AliMUONRawCluster.h" -#include "AliMUONGlobalTrigger.h" +#include "AliMUONVDigit.h" +#include "AliMUONVCluster.h" #include "AliMUONLocalTrigger.h" -#include "AliMUONTrack.h" +#include "AliMUONRegionalTrigger.h" +#include "AliMUONGlobalTrigger.h" +#include "AliMUONMCDataInterface.h" #include "AliMUONDataInterface.h" +#include "AliMUONVHitStore.h" +#include "AliMUONVDigitStore.h" +#include "AliMUONVClusterStore.h" +#include "AliMUONVTriggerStore.h" +#include "AliMpConstants.h" +#include "AliMpDEManager.h" + +#include "AliCDBManager.h" + +#include +#include +#include +#include +#include + +#include + #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>> Event %d, Number of particles is %d \n",ievent, nparticles); - for(iparticle=0; iparticleIsA() == AliMUONLocalTrigger::Class() && b->IsA() == AliMUONLocalTrigger::Class()) + { + result = memcmp(a, b, sizeof(AliMUONLocalTrigger)); + } + else if (a->IsA() == AliMUONRegionalTrigger::Class() && b->IsA() == AliMUONRegionalTrigger::Class()) + { + const AliMUONRegionalTrigger* ra = static_cast(a); + const AliMUONRegionalTrigger* rb = static_cast(b); + if (ra->GetId() < rb->GetId()) return -1; + if (ra->GetId() > rb->GetId()) return 1; + if (ra->GetLocalOutput(0) < rb->GetLocalOutput(0)) return -1; + if (ra->GetLocalOutput(0) > rb->GetLocalOutput(0)) return 1; + if (ra->GetLocalOutput(1) < rb->GetLocalOutput(1)) return -1; + if (ra->GetLocalOutput(1) > rb->GetLocalOutput(1)) return 1; + if (ra->GetLocalMask() < rb->GetLocalMask()) return -1; + if (ra->GetLocalMask() > rb->GetLocalMask()) return 1; + if (ra->GetOutput() < rb->GetOutput()) return -1; + if (ra->GetOutput() > rb->GetOutput()) return 1; + return 0; + } + else if (a->IsA() == AliMUONGlobalTrigger::Class() && b->IsA() == AliMUONGlobalTrigger::Class()) + { + result = memcmp(a, b, sizeof(AliMUONGlobalTrigger)); + } + else { - amdi.Particle(iparticle)->Print(""); + result = memcmp(a, b, sizeof(TObject)); } - } + + if (result < 0) return -1; + if (result > 0) return 1; + return 0; } +/** + * 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 false is returned. + */ +bool SimTriggersOk() +{ + AliMUONMCDataInterface data("generated/galice.root"); + for (Int_t event = 0; event < data.NumberOfEvents(); event++) + { + TObjArray localsFromStore, regionalsFromStore; + localsFromStore.SetOwner(kTRUE); + regionalsFromStore.SetOwner(kTRUE); + AliMUONVTriggerStore* store = data.TriggerStore(event); + if (store == NULL) return false; + AliMUONGlobalTrigger* globalFromStore = static_cast(store->Global()->Clone()); + TIter nextLocal(store->CreateLocalIterator()); + AliMUONLocalTrigger* localTrig; + while ( (localTrig = static_cast( nextLocal() )) != NULL ) + { + localsFromStore.Add(localTrig->Clone()); + } + TIter nextRegional(store->CreateRegionalIterator()); + AliMUONRegionalTrigger* regionalTrig; + while ( (regionalTrig = static_cast( nextRegional() )) != NULL ) + { + regionalsFromStore.Add(regionalTrig->Clone()); + } + + TObjArray localsByIndex, regionalsByIndex; + localsByIndex.SetOwner(kTRUE); + regionalsByIndex.SetOwner(kTRUE); + data.GetEvent(event); + AliMUONGlobalTrigger* globalByMethod = static_cast(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; + } + regionalsFromStore[i]->Print(); + regionalsByIndex[i]->Print(); + } + } + return true; +} -void MUONhits(char * filename="galice.root") +/** + * This method fills internal arrays with s-digits returned by the AliMUONMCDataInterface. + * For each set of interface methods available a TObjArray is filled with copies of + * the s-digits. These arrays are sorted and then compared to each other. The arrays + * should contain the same s-digit information if everything is working correctly with + * AliMUONMCDataInterface. If not then the difference is printed together with an + * error message and false is returned. + */ +bool SimSDigitsOk() { - - AliMUONDataInterface amdi; - amdi.SetFile(filename); - Int_t nevents = amdi.NumberOfEvents(); - - for(Int_t ievent=0; ievent>> Event %d \n",ievent); - // Getting event ievent - amdi.GetEvent(ievent); - Int_t ntracks = amdi.NumberOfTracks(); - for (Int_t itrack=0; itrack>> 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; ihitChamber(); // 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("generated/galice.root"); + for (Int_t event = 0; event < data.NumberOfEvents(); event++) + { + TObjArray digitsFromStore; + digitsFromStore.SetOwner(kTRUE); + AliMUONVDigitStore* store = data.SDigitStore(event); + if (store == NULL) return false; + TIter next(store->CreateIterator()); + AliMUONVDigit* digit; + while ( (digit = static_cast( 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.NumberOfSDigits(detElem); + for (Int_t i = 0; i < ndigits; i++) + { + AliMUONVDigit* digit = data.SDigit(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.NumberOfSDigits(chamber, cathode); + for (Int_t i = 0; i < ndigits; i++) + { + AliMUONVDigit* digit = data.SDigit(chamber, cathode, i); + digitsByChamber.Add(digit->Clone()); + } + } + digitsByChamber.Sort(); + + // Now check that all the lists of s-digits contain the same results. + // They must. If they do not then something is wrong with the implementation + // of AliMUONMCDataInterface. + if (digitsFromStore.GetEntriesFast() != digitsByDetElem.GetEntriesFast() + || digitsFromStore.GetEntriesFast() != digitsByChamber.GetEntriesFast()) + { + Error( "SimSDigitsOk", + "The AliMUONMCDataInterface does not return all the s-digits correctly" + " through all its user interface methods. We got the following" + " numbers of s-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( "SimSDigitsOk", + "The AliMUONMCDataInterface does not return identical s-digits" + " through all its user interface methods. The incorrect" + " s-digit has index %d after sorting.", + i + ); + digitsFromStore[i]->Print(); + digitsByChamber[i]->Print(); + digitsByDetElem[i]->Print(); + return false; + } + } + } + return true; } +/** + * This method fills internal arrays with digits returned by the AliMUONMCDataInterface. + * 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 + * AliMUONMCDataInterface. If not then the difference is printed together with an + * error message and false is returned. + */ +bool SimDigitsOk() +{ + AliMUONMCDataInterface data("generated/galice.root"); + for (Int_t event = 0; event < data.NumberOfEvents(); event++) + { + TObjArray digitsFromStore; + digitsFromStore.SetOwner(kTRUE); + AliMUONVDigitStore* store = data.DigitStore(event); + if (store == NULL) return false; + TIter next(store->CreateIterator()); + AliMUONVDigit* digit; + while ( (digit = static_cast( 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 AliMUONMCDataInterface. + if (digitsFromStore.GetEntriesFast() != digitsByDetElem.GetEntriesFast() + || digitsFromStore.GetEntriesFast() != digitsByChamber.GetEntriesFast()) + { + Error( "SimDigitsOk", + "The AliMUONMCDataInterface 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( "SimDigitsOk", + "The AliMUONMCDataInterface 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 hits returned by the AliMUONMCDataInterface. + * For each set of interface methods available a TObjArray is filled with copies of + * the hits. These arrays are then compared to each other. The arrays should contain + * the same hit information if everything is working correctly with AliMUONMCDataInterface. + * If not then the difference is printed together with an error message and false is returned. + */ +bool SimHitsOk() { - - AliMUONDataInterface amdi; - amdi.SetFile(filename); - Int_t ievent, nevents; - nevents = amdi.NumberOfEvents(); - AliMUONDigit * mDigit; - - for(ievent=0; ievent>> 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>> Chamber %d\n",ichamber+1); - - Int_t idigit, ndigits; - ndigits = amdi.NumberOfDigits(ichamber,0); // second parameter here is cathode... - - for(idigit=0; idigitPadX(); // 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 + if (data.NumberOfTracks(event) != data.NumberOfTracks()) + { + Error( "SimHitsOk", + "The AliMUONMCDataInterface does not return the same number of tracks" + " through all its user interface methods. We got the following" + " numbers of tracks: %d and %d", + data.NumberOfTracks(event), + data.NumberOfTracks() + ); + return false; + } + + for (Int_t track = 0; track < data.NumberOfTracks(); track++) + { + TObjArray hitsFromStore; + hitsFromStore.SetOwner(kTRUE); + AliMUONVHitStore* store = data.HitStore(event, track); + if (store == NULL) return false; + TIter next(store->CreateIterator()); + AliMUONHit* hit; + while ( (hit = static_cast( next() )) != NULL ) + { + hitsFromStore.Add(hit->Clone()); + } + //hitsFromStore.Sort(); // Unfortunately hits do not implement the Compare method. + + TObjArray hitsByMethod; + hitsByMethod.SetOwner(kTRUE); + data.GetEvent(event); + for (Int_t i = 0; i < data.NumberOfHits(track); i++) + { + AliMUONHit* hit = data.Hit(track, i); + hitsByMethod.Add(hit->Clone()); + } + //hitsByMethod.Sort(); // Unfortunately hits do not implement the Compare method. + + // Now check that both lists of hits contain the same results. + // They must. If they do not then something is wrong with the implementation + // of AliMUONMCDataInterface. + if (hitsFromStore.GetEntriesFast() != hitsByMethod.GetEntriesFast()) + { + Error( "SimHitsOk", + "The AliMUONMCDataInterface does not return all the hits correctly" + " through all its user interface methods. We got the following" + " numbers of hits: %d and %d", + hitsFromStore.GetEntriesFast(), + hitsByMethod.GetEntriesFast() + ); + return false; + } + for (Int_t i = 0; i < hitsFromStore.GetEntriesFast(); i++) + { + if (Compare(hitsFromStore[i], hitsByMethod[i]) != 0) + { + Error( "SimHitsOk", + "The AliMUONMCDataInterface does not return identical hits" + " through all its user interface methods. The incorrect" + " hit has index %d after sorting, for track %d.", + i, track + ); + hitsFromStore[i]->Print(); + hitsByMethod[i]->Print(); + return false; + } + } + } + } + return true; } -void MUONrecpoints(char * filename="galice.root") +/** + * 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 false is returned. + */ +bool RecDigitsOk() { - AliMUONDataInterface amdi; - amdi.SetFile(filename); - - Int_t ievent, nevents; - nevents = amdi.NumberOfEvents(); - AliMUONRawCluster * mRecPoint = 0; - - for(ievent=0; ievent>> Event %d \n",ievent); - amdi.GetEvent(ievent); - Int_t ichamber, nchambers; - nchambers = AliMUONConstants::NTrackingCh(); - // Loop on chambers - for( ichamber=0; ichamber>> Chamber %d\n",ichamber); - Int_t irecpoint, nrecpoints; - nrecpoints = amdi.NumberOfRawClusters(ichamber); - printf("number of recpoints = %6d \n",nrecpoints); - for(irecpoint=0; irecpoint0 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 digitsFromStore; + digitsFromStore.SetOwner(kTRUE); + AliMUONVDigitStore* store = data.DigitStore(event); + if (store == NULL) return false; + TIter next(store->CreateIterator()); + AliMUONVDigit* digit; + while ( (digit = static_cast( 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 MUONTestTrigger (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 false is returned. + */ +bool RawClustersOk() { - // 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; ieventSinglePlusLpt(), - 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>> 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 clustersFromStore; + clustersFromStore.SetOwner(kTRUE); + AliMUONVClusterStore* store = data.ClusterStore(event); + if (store == NULL) return false; + TIter next(store->CreateIterator()); + AliMUONVCluster* cluster; + while ( (cluster = static_cast( next() )) != NULL ) + { + clustersFromStore.Add(cluster->Clone()); + } + clustersFromStore.Sort(); + + TObjArray clustersByChamber; + clustersByChamber.SetOwner(kTRUE); + data.GetEvent(event); + for (Int_t chamber = 0; chamber < AliMpConstants::NofTrackingChambers(); chamber++) + { + Int_t nclusters = data.NumberOfRawClusters(chamber); + for (Int_t i = 0; i < nclusters; i++) + { + AliMUONVCluster* 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 MUONRecTracks (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 false is returned. + */ +bool TriggersOk() { - - // 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>> 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 localsFromStore, regionalsFromStore; + localsFromStore.SetOwner(kTRUE); + regionalsFromStore.SetOwner(kTRUE); + AliMUONVTriggerStore* store = data.TriggerStore(event); + if (store == NULL) return false; + AliMUONGlobalTrigger* globalFromStore = static_cast(store->Global()->Clone()); + TIter nextLocal(store->CreateLocalIterator()); + AliMUONLocalTrigger* localTrig; + while ( (localTrig = static_cast( nextLocal() )) != NULL ) + { + localsFromStore.Add(localTrig->Clone()); + } + TIter nextRegional(store->CreateRegionalIterator()); + AliMUONRegionalTrigger* regionalTrig; + while ( (regionalTrig = static_cast( nextRegional() )) != NULL ) + { + regionalsFromStore.Add(regionalTrig->Clone()); + } + + TObjArray localsByIndex, regionalsByIndex; + localsByIndex.SetOwner(kTRUE); + regionalsByIndex.SetOwner(kTRUE); + data.GetEvent(event); + AliMUONGlobalTrigger* globalByMethod = static_cast(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; +} + +/** + * 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(bool checkSim = true, bool checkRec = true) +{ + AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT/OCDB"); + + // Note: we do not bother checking the AliMUONMCDataInterface::Particle, + // AliMUONMCDataInterface::Stack and AliMUONMCDataInterface::TrackRefs methods + // because they are trivial enough to validate from a quick inspecition of + // the source code. + + if (checkSim) + { + cout << "Checking simulated hits..." << endl; + if (! SimHitsOk()) return false; + cout << "Simulated hits look OK." << endl; + + cout << "Checking simulated s-digits..." << endl; + if (! SimSDigitsOk()) return false; + cout << "Simulated s-digits look OK." << endl; + + cout << "Checking simulated digits..." << endl; + if (! SimDigitsOk()) return false; + cout << "Simulated digits look OK." << endl; + + cout << "Checking simulated triggers..." << endl; + if (! SimTriggersOk()) return false; + cout << "Simulated triggers look OK." << endl; + } + + if (checkRec) + { + 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 triggers..." << endl; + if (! TriggersOk()) return false; + cout << "Reconstructed triggers look OK." << endl; + } + + return true; }