]>
Commit | Line | Data |
---|---|---|
6ca54c85 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | /* $Id$ */ | |
17 | ||
18 | // | |
9b220edf | 19 | // Macro for checking AliMUONDataInterface and AliMUONMCDataInterface. |
6ca54c85 | 20 | // By Bruce Becker, DAPNIA/SPhN/CEA Saclay |
6ca54c85 | 21 | // |
9b220edf | 22 | // Modified to updated versions of data interfaces. |
23 | // Artur Szostak <artursz@iafrica.com> (University of Cape Town) | |
24 | // | |
6ca54c85 | 25 | |
9b220edf | 26 | #if !defined(__CINT__) || defined(__MAKECINT__) |
27 | #include <Rtypes.h> | |
28 | #include <Riostream.h> | |
29 | #include <TObjArray.h> | |
30 | #include <TIterator.h> | |
6ca54c85 | 31 | #include "AliMUONHit.h" |
9b220edf | 32 | #include "AliMUONVDigit.h" |
6ca54c85 | 33 | #include "AliMUONRawCluster.h" |
6ca54c85 | 34 | #include "AliMUONTrack.h" |
9b220edf | 35 | #include "AliMUONLocalTrigger.h" |
36 | #include "AliMUONRegionalTrigger.h" | |
37 | #include "AliMUONGlobalTrigger.h" | |
38 | #include "AliMUONTriggerTrack.h" | |
39 | #include "AliMUONMCDataInterface.h" | |
6ca54c85 | 40 | #include "AliMUONDataInterface.h" |
9b220edf | 41 | #include "AliMUONVDigitStore.h" |
42 | #include "AliMUONVClusterStore.h" | |
43 | #include "AliMUONVTrackStore.h" | |
44 | #include "AliMUONVTriggerStore.h" | |
45 | #include "AliMUONVTriggerTrackStore.h" | |
46 | #include "AliMpConstants.h" | |
47 | #include "AliMpDEManager.h" | |
48 | #include <cstdlib> | |
6ca54c85 | 49 | #endif |
50 | ||
51 | ||
9b220edf | 52 | /** |
53 | * This routine implements a the comparison functionality which is missing for | |
54 | * classes like AliMUONTrack and the various AliMUONxxxTrigger classes. | |
55 | * A result of -1 is returned if a < b, 0 if a == b and +1 if a > b. | |
56 | */ | |
57 | Int_t Compare(const TObject* a, const TObject* b) | |
6ca54c85 | 58 | { |
9b220edf | 59 | int result = -999; |
60 | if (a->IsA() == AliMUONTrack::Class() && b->IsA() == AliMUONTrack::Class()) | |
61 | { | |
62 | const AliMUONTrack* ta = static_cast<const AliMUONTrack*>(a); | |
63 | const AliMUONTrack* tb = static_cast<const AliMUONTrack*>(b); | |
64 | if (ta->GetNTrackHits() < tb->GetNTrackHits()) return -1; | |
65 | if (ta->GetNTrackHits() > tb->GetNTrackHits()) return 1; | |
66 | if (ta->GetMatchTrigger() < tb->GetMatchTrigger()) return -1; | |
67 | if (ta->GetMatchTrigger() > tb->GetMatchTrigger()) return 1; | |
68 | if (ta->GetLoTrgNum() < tb->GetLoTrgNum()) return -1; | |
69 | if (ta->GetLoTrgNum() > tb->GetLoTrgNum()) return 1; | |
70 | if (ta->GetChi2MatchTrigger() < tb->GetChi2MatchTrigger()) return -1; | |
71 | if (ta->GetChi2MatchTrigger() > tb->GetChi2MatchTrigger()) return 1; | |
72 | const AliMUONTrackParam* tpa = static_cast<const AliMUONTrackParam*>(ta->GetTrackParamAtHit()->First()); | |
73 | const AliMUONTrackParam* tpb = static_cast<const AliMUONTrackParam*>(tb->GetTrackParamAtHit()->First()); | |
74 | if (tpa->GetNonBendingCoor() < tpb->GetNonBendingCoor()) return -1; | |
75 | if (tpa->GetNonBendingCoor() > tpb->GetNonBendingCoor()) return 1; | |
76 | if (tpa->GetNonBendingSlope() < tpb->GetNonBendingSlope()) return -1; | |
77 | if (tpa->GetNonBendingSlope() > tpb->GetNonBendingSlope()) return 1; | |
78 | if (tpa->GetBendingCoor() < tpb->GetBendingCoor()) return -1; | |
79 | if (tpa->GetBendingCoor() > tpb->GetBendingCoor()) return 1; | |
80 | if (tpa->GetBendingSlope() < tpb->GetBendingSlope()) return -1; | |
81 | if (tpa->GetBendingSlope() > tpb->GetBendingSlope()) return 1; | |
82 | if (tpa->GetInverseBendingMomentum() < tpb->GetInverseBendingMomentum()) return -1; | |
83 | if (tpa->GetInverseBendingMomentum() > tpb->GetInverseBendingMomentum()) return 1; | |
84 | if (tpa->GetCharge() < tpb->GetCharge()) return -1; | |
85 | if (tpa->GetCharge() > tpb->GetCharge()) return 1; | |
86 | return 0; | |
87 | } | |
88 | else if (a->IsA() == AliMUONLocalTrigger::Class() && b->IsA() == AliMUONLocalTrigger::Class()) | |
89 | { | |
90 | result = memcmp(a, b, sizeof(AliMUONLocalTrigger)); | |
91 | } | |
92 | else if (a->IsA() == AliMUONRegionalTrigger::Class() && b->IsA() == AliMUONRegionalTrigger::Class()) | |
93 | { | |
94 | result = memcmp(a, b, sizeof(AliMUONRegionalTrigger)); | |
95 | } | |
96 | else if (a->IsA() == AliMUONGlobalTrigger::Class() && b->IsA() == AliMUONGlobalTrigger::Class()) | |
97 | { | |
98 | result = memcmp(a, b, sizeof(AliMUONGlobalTrigger)); | |
99 | } | |
100 | else if (a->IsA() == AliMUONTriggerTrack::Class() && b->IsA() == AliMUONTriggerTrack::Class()) | |
101 | { | |
102 | const AliMUONTriggerTrack* ta = static_cast<const AliMUONTriggerTrack*>(a); | |
103 | const AliMUONTriggerTrack* tb = static_cast<const AliMUONTriggerTrack*>(b); | |
104 | if (ta->GetX11() < tb->GetX11()) return -1; | |
105 | if (ta->GetX11() > tb->GetX11()) return 1; | |
106 | if (ta->GetY11() < tb->GetY11()) return -1; | |
107 | if (ta->GetY11() > tb->GetY11()) return 1; | |
108 | if (ta->GetThetax() < tb->GetThetax()) return -1; | |
109 | if (ta->GetThetax() > tb->GetThetax()) return 1; | |
110 | if (ta->GetThetay() < tb->GetThetay()) return -1; | |
111 | if (ta->GetThetay() > tb->GetThetay()) return 1; | |
112 | if (ta->GetLoTrgNum() < tb->GetLoTrgNum()) return -1; | |
113 | if (ta->GetLoTrgNum() > tb->GetLoTrgNum()) return 1; | |
114 | if (ta->GetGTPattern() < tb->GetGTPattern()) return -1; | |
115 | if (ta->GetGTPattern() > tb->GetGTPattern()) return 1; | |
116 | return 0; | |
117 | } | |
118 | else | |
6ca54c85 | 119 | { |
9b220edf | 120 | result = memcmp(a, b, sizeof(TObject)); |
6ca54c85 | 121 | } |
9b220edf | 122 | |
123 | if (result < 0) return -1; | |
124 | if (result > 0) return 1; | |
125 | return 0; | |
6ca54c85 | 126 | } |
127 | ||
9b220edf | 128 | /** |
129 | * This method fills internal arrays with local and regional triggers returned | |
130 | * by AliMUONMCDataInterface. For each set of interface methods available in | |
131 | * AliMUONMCDataInterface a TObjArray is created for local and another for regional | |
132 | * triggers. These arrays are filled with copies of the trigger objects. | |
133 | * The global trigger object is also copied out using the 2 different methods. | |
134 | * The arrays and objects are then compared to each other. The arrays and objects | |
135 | * should contain the same information if everything is working correctly with | |
136 | * AliMUONMCDataInterface. If not then the difference is printed together with an | |
137 | * error message and kFALSE is returned. | |
138 | */ | |
139 | bool SimTriggersOk() | |
6ca54c85 | 140 | { |
9b220edf | 141 | AliMUONMCDataInterface data; |
142 | for (Int_t event = 0; event < data.NumberOfEvents(); event++) | |
143 | { | |
144 | TObjArray localsFromStore, regionalsFromStore; | |
145 | localsFromStore.SetOwner(kTRUE); | |
146 | regionalsFromStore.SetOwner(kTRUE); | |
147 | AliMUONVTriggerStore* store = data.TriggerStore(event); | |
148 | AliMUONGlobalTrigger* globalFromStore = static_cast<AliMUONGlobalTrigger*>(store->Global()->Clone()); | |
149 | TIter nextLocal(store->CreateLocalIterator()); | |
150 | AliMUONLocalTrigger* localTrig; | |
151 | while ( (localTrig = static_cast<AliMUONLocalTrigger*>( nextLocal() )) != NULL ) | |
152 | { | |
153 | localsFromStore.Add(localTrig->Clone()); | |
154 | } | |
155 | TIter nextRegional(store->CreateRegionalIterator()); | |
156 | AliMUONRegionalTrigger* regionalTrig; | |
157 | while ( (regionalTrig = static_cast<AliMUONRegionalTrigger*>( nextRegional() )) != NULL ) | |
158 | { | |
159 | regionalsFromStore.Add(regionalTrig->Clone()); | |
160 | } | |
161 | ||
162 | TObjArray localsByIndex, regionalsByIndex; | |
163 | localsByIndex.SetOwner(kTRUE); | |
164 | regionalsByIndex.SetOwner(kTRUE); | |
165 | data.GetEvent(event); | |
166 | AliMUONGlobalTrigger* globalByMethod = static_cast<AliMUONGlobalTrigger*>(data.GlobalTrigger()->Clone()); | |
167 | Int_t nlocals = data.NumberOfLocalTriggers(); | |
168 | for (Int_t i = 0; i < nlocals; i++) | |
169 | { | |
170 | localTrig = data.LocalTrigger(i); | |
171 | localsByIndex.Add(localTrig->Clone()); | |
172 | } | |
173 | Int_t nregionals = data.NumberOfRegionalTriggers(); | |
174 | for (Int_t i = 0; i < nregionals; i++) | |
175 | { | |
176 | regionalTrig = data.RegionalTrigger(i); | |
177 | regionalsByIndex.Add(regionalTrig->Clone()); | |
178 | } | |
179 | ||
180 | // Now check that all the lists of local, regional and global triggers | |
181 | // contain the same results. | |
182 | // They must. If they do not then something is wrong with the implementation | |
183 | // of AliMUONMCDataInterface. | |
184 | if (Compare(globalFromStore, globalByMethod) != 0) | |
185 | { | |
186 | Error( "SimTriggersOk", | |
187 | "The AliMUONMCDataInterface does not return identical global" | |
188 | " triggers through all its user interface methods." | |
189 | ); | |
190 | globalFromStore->Print(); | |
191 | globalByMethod->Print(); | |
192 | return false; | |
193 | } | |
194 | delete globalFromStore; | |
195 | delete globalByMethod; | |
196 | if (localsFromStore.GetEntriesFast() != localsByIndex.GetEntriesFast()) | |
197 | { | |
198 | Error( "SimTriggersOk", | |
199 | "The AliMUONMCDataInterface does not return all the local triggers" | |
200 | " correctly through all its user interface methods. We got the" | |
201 | " following numbers of local triggers: %d and %d", | |
202 | localsFromStore.GetEntriesFast(), | |
203 | localsByIndex.GetEntriesFast() | |
204 | ); | |
205 | return false; | |
206 | } | |
207 | if (regionalsFromStore.GetEntriesFast() != regionalsByIndex.GetEntriesFast()) | |
208 | { | |
209 | Error( "SimTriggersOk", | |
210 | "The AliMUONMCDataInterface does not return all the regional triggers" | |
211 | " correctly through all its user interface methods. We got the" | |
212 | " following numbers of regional triggers: %d and %d", | |
213 | regionalsFromStore.GetEntriesFast(), | |
214 | regionalsByIndex.GetEntriesFast() | |
215 | ); | |
216 | return false; | |
217 | } | |
218 | for (Int_t i = 0; i < localsFromStore.GetEntriesFast(); i++) | |
219 | { | |
220 | if (Compare(localsFromStore[i], localsByIndex[i]) != 0) | |
221 | { | |
222 | Error( "SimTriggersOk", | |
223 | "The AliMUONMCDataInterface does not return identical local" | |
224 | " triggers through all its user interface methods. The" | |
225 | " incorrect local trigger has index %d.", | |
226 | i | |
227 | ); | |
228 | localsFromStore[i]->Print(); | |
229 | localsByIndex[i]->Print(); | |
230 | return false; | |
231 | } | |
232 | } | |
233 | for (Int_t i = 0; i < regionalsFromStore.GetEntriesFast(); i++) | |
234 | { | |
235 | if (Compare(regionalsFromStore[i], regionalsByIndex[i]) != 0) | |
236 | { | |
237 | Error( "SimTriggersOk", | |
238 | "The AliMUONMCDataInterface does not return identical regional" | |
239 | " triggers through all its user interface methods. The" | |
240 | " incorrect regional trigger has index %d.", | |
241 | i | |
242 | ); | |
243 | regionalsFromStore[i]->Print(); | |
244 | regionalsByIndex[i]->Print(); | |
245 | return false; | |
246 | } | |
247 | } | |
248 | } | |
249 | return true; | |
6ca54c85 | 250 | } |
251 | ||
9b220edf | 252 | /** |
253 | * This method fills internal arrays with digits returned by the AliMUONDataInterface. | |
254 | * For each set of interface methods available a TObjArray is filled with copies of | |
255 | * the digits. These arrays are sorted and then compared to each other. The arrays | |
256 | * should contain the same digit information if everything is working correctly with | |
257 | * AliMUONDataInterface. If not then the difference is printed together with an | |
258 | * error message and kFALSE is returned. | |
259 | */ | |
260 | bool RecDigitsOk() | |
261 | { | |
262 | AliMUONDataInterface data; | |
263 | for (Int_t event = 0; event < data.NumberOfEvents(); event++) | |
264 | { | |
265 | TObjArray digitsFromStore; | |
266 | digitsFromStore.SetOwner(kTRUE); | |
267 | AliMUONVDigitStore* store = data.DigitStore(event); | |
268 | TIter next(store->CreateIterator()); | |
269 | AliMUONVDigit* digit; | |
270 | while ( (digit = static_cast<AliMUONVDigit*>( next() )) != NULL ) | |
271 | { | |
272 | digitsFromStore.Add(digit->Clone()); | |
273 | } | |
274 | digitsFromStore.Sort(); | |
275 | ||
276 | TObjArray digitsByDetElem; | |
277 | digitsByDetElem.SetOwner(kTRUE); | |
278 | data.GetEvent(event); | |
279 | for (Int_t detElem = 0; detElem < 1500; detElem++) | |
280 | { | |
281 | if (! AliMpDEManager::IsValidDetElemId(detElem)) continue; | |
282 | Int_t ndigits = data.NumberOfDigits(detElem); | |
283 | for (Int_t i = 0; i < ndigits; i++) | |
284 | { | |
285 | AliMUONVDigit* digit = data.Digit(detElem, i); | |
286 | digitsByDetElem.Add(digit->Clone()); | |
287 | } | |
288 | } | |
289 | digitsByDetElem.Sort(); | |
290 | ||
291 | TObjArray digitsByChamber; | |
292 | digitsByChamber.SetOwner(kTRUE); | |
293 | data.GetEvent(event); | |
294 | for (Int_t chamber = 0; chamber < AliMpConstants::NofChambers(); chamber++) | |
295 | for (Int_t cathode = 0; cathode < 2; cathode++) | |
296 | { | |
297 | Int_t ndigits = data.NumberOfDigits(chamber, cathode); | |
298 | for (Int_t i = 0; i < ndigits; i++) | |
299 | { | |
300 | AliMUONVDigit* digit = data.Digit(chamber, cathode, i); | |
301 | digitsByChamber.Add(digit->Clone()); | |
302 | } | |
303 | } | |
304 | digitsByChamber.Sort(); | |
305 | ||
306 | // Now check that all the lists of digits contain the same results. | |
307 | // They must. If they do not then something is wrong with the implementation | |
308 | // of AliMUONDataInterface. | |
309 | if (digitsFromStore.GetEntriesFast() != digitsByDetElem.GetEntriesFast() | |
310 | || digitsFromStore.GetEntriesFast() != digitsByChamber.GetEntriesFast()) | |
311 | { | |
312 | Error( "RecDigitsOk", | |
313 | "The AliMUONDataInterface does not return all the digits correctly" | |
314 | " through all its user interface methods. We got the following" | |
315 | " numbers of digits: %d, %d and %d", | |
316 | digitsFromStore.GetEntriesFast(), | |
317 | digitsByDetElem.GetEntriesFast(), | |
318 | digitsByChamber.GetEntriesFast() | |
319 | ); | |
320 | return false; | |
321 | } | |
322 | for (Int_t i = 0; i < digitsFromStore.GetEntriesFast(); i++) | |
323 | { | |
324 | if (digitsFromStore[i]->Compare(digitsByDetElem[i]) != 0 | |
325 | || digitsFromStore[i]->Compare(digitsByChamber[i]) != 0) | |
326 | { | |
327 | Error( "RecDigitsOk", | |
328 | "The AliMUONDataInterface does not return identical digits" | |
329 | " through all its user interface methods. The incorrect" | |
330 | " digit has index %d after sorting.", | |
331 | i | |
332 | ); | |
333 | digitsFromStore[i]->Print(); | |
334 | digitsByChamber[i]->Print(); | |
335 | digitsByDetElem[i]->Print(); | |
336 | return false; | |
337 | } | |
338 | } | |
339 | } | |
340 | return true; | |
341 | } | |
6ca54c85 | 342 | |
9b220edf | 343 | /** |
344 | * This method fills internal arrays with raw clusters returned by AliMUONDataInterface. | |
345 | * For each set of interface methods available in AliMUONDataInterface a TObjArray is | |
346 | * filled with copies of the raw clusters. These arrays are sorted and then compared | |
347 | * to each other. The arrays should contain the same information if everything is | |
348 | * working correctly with AliMUONDataInterface. If not then the difference is printed | |
349 | * together with an error message and kFALSE is returned. | |
350 | */ | |
351 | bool RawClustersOk() | |
6ca54c85 | 352 | { |
9b220edf | 353 | AliMUONDataInterface data; |
354 | for (Int_t event = 0; event < data.NumberOfEvents(); event++) | |
6ca54c85 | 355 | { |
9b220edf | 356 | TObjArray clustersFromStore; |
357 | clustersFromStore.SetOwner(kTRUE); | |
358 | AliMUONVClusterStore* store = data.ClusterStore(event); | |
359 | TIter next(store->CreateIterator()); | |
360 | AliMUONRawCluster* cluster; | |
361 | while ( (cluster = static_cast<AliMUONRawCluster*>( next() )) != NULL ) | |
362 | { | |
363 | clustersFromStore.Add(cluster->Clone()); | |
364 | } | |
365 | clustersFromStore.Sort(); | |
366 | ||
367 | TObjArray clustersByChamber; | |
368 | clustersByChamber.SetOwner(kTRUE); | |
369 | data.GetEvent(event); | |
370 | for (Int_t chamber = 0; chamber < AliMpConstants::NofChambers(); chamber++) | |
371 | { | |
372 | Int_t nclusters = data.NumberOfRawClusters(chamber); | |
373 | for (Int_t i = 0; i < nclusters; i++) | |
374 | { | |
375 | AliMUONRawCluster* cluster = data.RawCluster(chamber, i); | |
376 | clustersByChamber.Add(cluster->Clone()); | |
377 | } | |
378 | } | |
379 | clustersByChamber.Sort(); | |
380 | ||
381 | // Now check that all the lists of clusters contain the same results. | |
382 | // They must. If they do not then something is wrong with the implementation | |
383 | // of AliMUONDataInterface. | |
384 | if (clustersFromStore.GetEntriesFast() != clustersByChamber.GetEntriesFast()) | |
385 | { | |
386 | Error( "RawClustersOk", | |
387 | "The AliMUONDataInterface does not return all the clusters correctly" | |
388 | " through all its user interface methods. We got the following" | |
389 | " numbers of clusters: %d and %d", | |
390 | clustersFromStore.GetEntriesFast(), | |
391 | clustersByChamber.GetEntriesFast() | |
392 | ); | |
393 | return false; | |
394 | } | |
395 | for (Int_t i = 0; i < clustersFromStore.GetEntriesFast(); i++) | |
396 | { | |
397 | if (clustersFromStore[i]->Compare(clustersByChamber[i]) != 0) | |
398 | { | |
399 | Error( "RawClustersOk", | |
400 | "The AliMUONDataInterface does not return identical clusters" | |
401 | " through all its user interface methods. The incorrect" | |
402 | " cluster has index %d after sorting.", | |
403 | i | |
404 | ); | |
405 | clustersFromStore[i]->Print(); | |
406 | clustersByChamber[i]->Print(); | |
407 | return false; | |
408 | } | |
409 | } | |
410 | } | |
411 | return true; | |
6ca54c85 | 412 | } |
413 | ||
9b220edf | 414 | /** |
415 | * This method fills internal arrays with tracks returned by AliMUONDataInterface. | |
416 | * For each set of interface methods available in AliMUONDataInterface a TObjArray is | |
417 | * filled with copies of the raw clusters. These arrays are then compared to each | |
418 | * other. The arrays should contain the same information if everything is working | |
419 | * correctly with AliMUONDataInterface. If not then the difference is printed | |
420 | * together with an error message and kFALSE is returned. | |
421 | */ | |
422 | bool TracksOk() | |
6ca54c85 | 423 | { |
9b220edf | 424 | AliMUONDataInterface data; |
425 | for (Int_t event = 0; event < data.NumberOfEvents(); event++) | |
6ca54c85 | 426 | { |
9b220edf | 427 | TObjArray tracksFromStore; |
428 | tracksFromStore.SetOwner(kTRUE); | |
429 | AliMUONVTrackStore* store = data.TrackStore(event); | |
430 | TIter next(store->CreateIterator()); | |
431 | AliMUONTrack* track; | |
432 | while ( (track = static_cast<AliMUONTrack*>( next() )) != NULL ) | |
433 | { | |
434 | tracksFromStore.Add(track->Clone()); | |
435 | } | |
436 | ||
437 | TObjArray tracksByIndex; | |
438 | tracksByIndex.SetOwner(kTRUE); | |
439 | data.GetEvent(event); | |
440 | Int_t ntracks = data.NumberOfTracks(); | |
441 | for (Int_t i = 0; i < ntracks; i++) | |
442 | { | |
443 | AliMUONTrack* track = data.Track(i); | |
444 | tracksByIndex.Add(track->Clone()); | |
445 | } | |
446 | ||
447 | // Now check that all the lists of tracks contain the same results. | |
448 | // They must. If they do not then something is wrong with the implementation | |
449 | // of AliMUONDataInterface. | |
450 | if (tracksFromStore.GetEntriesFast() != tracksByIndex.GetEntriesFast()) | |
451 | { | |
452 | Error( "TracksOk", | |
453 | "The AliMUONDataInterface does not return all the tracks correctly" | |
454 | " through all its user interface methods. We got the following" | |
455 | " numbers of tracks: %d and %d", | |
456 | tracksFromStore.GetEntriesFast(), | |
457 | tracksByIndex.GetEntriesFast() | |
458 | ); | |
459 | return false; | |
460 | } | |
461 | for (Int_t i = 0; i < tracksFromStore.GetEntriesFast(); i++) | |
462 | { | |
463 | if (Compare(tracksFromStore[i], tracksByIndex[i]) != 0) | |
464 | { | |
465 | Error( "TracksOk", | |
466 | "The AliMUONDataInterface does not return identical tracks" | |
467 | " through all its user interface methods. The incorrect" | |
468 | " track has index %d.", | |
469 | i | |
470 | ); | |
471 | tracksFromStore[i]->Print(); | |
472 | tracksByIndex[i]->Print(); | |
473 | return false; | |
474 | } | |
475 | } | |
476 | } | |
477 | return true; | |
6ca54c85 | 478 | } |
479 | ||
9b220edf | 480 | /** |
481 | * This method fills internal arrays with local and regional triggers returned | |
482 | * by AliMUONDataInterface. For each set of interface methods available in | |
483 | * AliMUONDataInterface a TObjArray is created for local and another for regional | |
484 | * triggers. These arrays are filled with copies of the trigger objects. | |
485 | * The global trigger object is also copied out using the 2 different methods. | |
486 | * The arrays and objects are then compared to each other. The arrays and objects | |
487 | * should contain the same information if everything is working correctly with | |
488 | * AliMUONDataInterface. If not then the difference is printed together with an | |
489 | * error message and kFALSE is returned. | |
490 | */ | |
491 | bool TriggersOk() | |
6ca54c85 | 492 | { |
9b220edf | 493 | AliMUONDataInterface data; |
494 | for (Int_t event = 0; event < data.NumberOfEvents(); event++) | |
495 | { | |
496 | TObjArray localsFromStore, regionalsFromStore; | |
497 | localsFromStore.SetOwner(kTRUE); | |
498 | regionalsFromStore.SetOwner(kTRUE); | |
499 | AliMUONVTriggerStore* store = data.TriggerStore(event); | |
500 | AliMUONGlobalTrigger* globalFromStore = static_cast<AliMUONGlobalTrigger*>(store->Global()->Clone()); | |
501 | TIter nextLocal(store->CreateLocalIterator()); | |
502 | AliMUONLocalTrigger* localTrig; | |
503 | while ( (localTrig = static_cast<AliMUONLocalTrigger*>( nextLocal() )) != NULL ) | |
504 | { | |
505 | localsFromStore.Add(localTrig->Clone()); | |
506 | } | |
507 | TIter nextRegional(store->CreateRegionalIterator()); | |
508 | AliMUONRegionalTrigger* regionalTrig; | |
509 | while ( (regionalTrig = static_cast<AliMUONRegionalTrigger*>( nextRegional() )) != NULL ) | |
510 | { | |
511 | regionalsFromStore.Add(regionalTrig->Clone()); | |
512 | } | |
513 | ||
514 | TObjArray localsByIndex, regionalsByIndex; | |
515 | localsByIndex.SetOwner(kTRUE); | |
516 | regionalsByIndex.SetOwner(kTRUE); | |
517 | data.GetEvent(event); | |
518 | AliMUONGlobalTrigger* globalByMethod = static_cast<AliMUONGlobalTrigger*>(data.GlobalTrigger()->Clone()); | |
519 | Int_t nlocals = data.NumberOfLocalTriggers(); | |
520 | for (Int_t i = 0; i < nlocals; i++) | |
521 | { | |
522 | localTrig = data.LocalTrigger(i); | |
523 | localsByIndex.Add(localTrig->Clone()); | |
524 | } | |
525 | Int_t nregionals = data.NumberOfRegionalTriggers(); | |
526 | for (Int_t i = 0; i < nregionals; i++) | |
527 | { | |
528 | regionalTrig = data.RegionalTrigger(i); | |
529 | regionalsByIndex.Add(regionalTrig->Clone()); | |
530 | } | |
531 | ||
532 | // Now check that all the lists of local, regional and global triggers | |
533 | // contain the same results. | |
534 | // They must. If they do not then something is wrong with the implementation | |
535 | // of AliMUONDataInterface. | |
536 | if (Compare(globalFromStore, globalByMethod) != 0) | |
537 | { | |
538 | Error( "TriggersOk", | |
539 | "The AliMUONDataInterface does not return identical global" | |
540 | " triggers through all its user interface methods." | |
541 | ); | |
542 | globalFromStore->Print(); | |
543 | globalByMethod->Print(); | |
544 | return false; | |
545 | } | |
546 | delete globalFromStore; | |
547 | delete globalByMethod; | |
548 | if (localsFromStore.GetEntriesFast() != localsByIndex.GetEntriesFast()) | |
549 | { | |
550 | Error( "TriggersOk", | |
551 | "The AliMUONDataInterface does not return all the local triggers" | |
552 | " correctly through all its user interface methods. We got the" | |
553 | " following numbers of local triggers: %d and %d", | |
554 | localsFromStore.GetEntriesFast(), | |
555 | localsByIndex.GetEntriesFast() | |
556 | ); | |
557 | return false; | |
558 | } | |
559 | if (regionalsFromStore.GetEntriesFast() != regionalsByIndex.GetEntriesFast()) | |
560 | { | |
561 | Error( "TriggersOk", | |
562 | "The AliMUONDataInterface does not return all the regional triggers" | |
563 | " correctly through all its user interface methods. We got the" | |
564 | " following numbers of regional triggers: %d and %d", | |
565 | regionalsFromStore.GetEntriesFast(), | |
566 | regionalsByIndex.GetEntriesFast() | |
567 | ); | |
568 | return false; | |
569 | } | |
570 | for (Int_t i = 0; i < localsFromStore.GetEntriesFast(); i++) | |
571 | { | |
572 | if (Compare(localsFromStore[i], localsByIndex[i]) != 0) | |
573 | { | |
574 | Error( "TriggersOk", | |
575 | "The AliMUONDataInterface does not return identical local" | |
576 | " triggers through all its user interface methods. The" | |
577 | " incorrect local trigger has index %d.", | |
578 | i | |
579 | ); | |
580 | localsFromStore[i]->Print(); | |
581 | localsByIndex[i]->Print(); | |
582 | return false; | |
583 | } | |
584 | } | |
585 | for (Int_t i = 0; i < regionalsFromStore.GetEntriesFast(); i++) | |
586 | { | |
587 | if (Compare(regionalsFromStore[i], regionalsByIndex[i]) != 0) | |
588 | { | |
589 | Error( "TriggersOk", | |
590 | "The AliMUONDataInterface does not return identical regional" | |
591 | " triggers through all its user interface methods. The" | |
592 | " incorrect regional trigger has index %d.", | |
593 | i | |
594 | ); | |
595 | regionalsFromStore[i]->Print(); | |
596 | regionalsByIndex[i]->Print(); | |
597 | return false; | |
598 | } | |
599 | } | |
600 | } | |
601 | return true; | |
6ca54c85 | 602 | } |
603 | ||
9b220edf | 604 | /** |
605 | * This method fills internal arrays with trigger tracks returned by AliMUONDataInterface. | |
606 | * For each set of interface methods available in AliMUONDataInterface a TObjArray is | |
607 | * filled with copies of the trigger tracks. These arrays are then compared to each | |
608 | * other. The arrays should contain the same information if everything is working | |
609 | * correctly with AliMUONDataInterface. If not then the difference is printed | |
610 | * together with an error message and kFALSE is returned. | |
611 | */ | |
612 | bool TriggerTracksOk() | |
6ca54c85 | 613 | { |
9b220edf | 614 | AliMUONDataInterface data; |
615 | for (Int_t event = 0; event < data.NumberOfEvents(); event++) | |
6ca54c85 | 616 | { |
9b220edf | 617 | TObjArray tracksFromStore; |
618 | tracksFromStore.SetOwner(kTRUE); | |
619 | AliMUONVTriggerTrackStore* store = data.TriggerTrackStore(event); | |
620 | TIter next(store->CreateIterator()); | |
621 | AliMUONTriggerTrack* track; | |
622 | while ( (track = static_cast<AliMUONTriggerTrack*>( next() )) != NULL ) | |
623 | { | |
624 | tracksFromStore.Add(track->Clone()); | |
625 | } | |
626 | ||
627 | TObjArray tracksByIndex; | |
628 | tracksByIndex.SetOwner(kTRUE); | |
629 | data.GetEvent(event); | |
630 | Int_t ntracks = data.NumberOfTriggerTracks(); | |
631 | for (Int_t i = 0; i < ntracks; i++) | |
632 | { | |
633 | AliMUONTriggerTrack* track = data.TriggerTrack(i); | |
634 | tracksByIndex.Add(track->Clone()); | |
635 | } | |
636 | ||
637 | // Now check that all the lists of trigger tracks contain the same results. | |
638 | // They must. If they do not then something is wrong with the implementation | |
639 | // of AliMUONDataInterface. | |
640 | if (tracksFromStore.GetEntriesFast() != tracksByIndex.GetEntriesFast()) | |
641 | { | |
642 | Error( "TriggerTracksOk", | |
643 | "The AliMUONDataInterface does not return all the trigger tracks" | |
644 | " correctly through all its user interface methods. We got the" | |
645 | " following numbers of tracks: %d and %d", | |
646 | tracksFromStore.GetEntriesFast(), | |
647 | tracksByIndex.GetEntriesFast() | |
648 | ); | |
649 | return false; | |
650 | } | |
651 | for (Int_t i = 0; i < tracksFromStore.GetEntriesFast(); i++) | |
652 | { | |
653 | if (Compare(tracksFromStore[i], tracksByIndex[i]) != 0) | |
654 | { | |
655 | Error( "TriggerTracksOk", | |
656 | "The AliMUONDataInterface does not return identical trigger" | |
657 | " tracks through all its user interface methods. The" | |
658 | " incorrect track has index %d.", | |
659 | i | |
660 | ); | |
661 | tracksFromStore[i]->Print(); | |
662 | tracksByIndex[i]->Print(); | |
663 | return false; | |
664 | } | |
665 | } | |
666 | } | |
667 | return true; | |
668 | } | |
669 | ||
670 | /** | |
671 | * This method performs a check of the AliMUONDataInterface and AliMUONMCDataInterface | |
672 | * classes. Basically there are at least 2 ways to fetch data using these interfaces: | |
673 | * The expert way using the store objects returned by these interface classes or | |
674 | * the much slower but easier way of using the NumberOfxxx and Digit(...), | |
675 | * RawCluster(...), Track(...) etc. methods to fetch individual data objects. | |
676 | * The MUONCheckDI will check that all these various ways of fetching data results | |
677 | * in the same information being returned. If yes then kTRUE is returned and a | |
678 | * confirmation message is printed, if not then kFALSE is returned with the failure | |
679 | * reason printed to screen. | |
680 | */ | |
681 | bool MUONCheckDI() | |
682 | { | |
683 | // TODO: complete checking AliMUONMCDataInterface. | |
684 | //cout << "Checking simulated triggers..." << endl; | |
685 | //if (! SimTriggersOk()) return false; | |
686 | //cout << "Simulated triggers look OK." << endl; | |
687 | ||
688 | cout << "Checking reconstructed digits..." << endl; | |
689 | if (! RecDigitsOk()) return false; | |
690 | cout << "Reconstructed digits look OK." << endl; | |
691 | ||
692 | cout << "Checking raw clusters..." << endl; | |
693 | if (! RawClustersOk()) return false; | |
694 | cout << "Raw clusters look OK." << endl; | |
695 | ||
696 | cout << "Checking reconstructed tracks..." << endl; | |
697 | if (! TracksOk()) return false; | |
698 | cout << "Reconstructed tracks look OK." << endl; | |
699 | ||
700 | cout << "Checking reconstructed triggers..." << endl; | |
701 | if (! TriggersOk()) return false; | |
702 | cout << "Reconstructed triggers look OK." << endl; | |
703 | ||
704 | cout << "Checking reconstructed trigger tracks..." << endl; | |
705 | if (! TriggerTracksOk()) return false; | |
706 | cout << "Reconstructed trigger tracks look OK." << endl; | |
707 | ||
708 | return true; | |
6ca54c85 | 709 | } |