]>
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__) |
6ca54c85 | 27 | #include "AliMUONHit.h" |
9b220edf | 28 | #include "AliMUONVDigit.h" |
2060b217 | 29 | #include "AliMUONVCluster.h" |
9b220edf | 30 | #include "AliMUONLocalTrigger.h" |
31 | #include "AliMUONRegionalTrigger.h" | |
32 | #include "AliMUONGlobalTrigger.h" | |
9b220edf | 33 | #include "AliMUONMCDataInterface.h" |
6ca54c85 | 34 | #include "AliMUONDataInterface.h" |
22fbde16 | 35 | #include "AliMUONVHitStore.h" |
9b220edf | 36 | #include "AliMUONVDigitStore.h" |
37 | #include "AliMUONVClusterStore.h" | |
9b220edf | 38 | #include "AliMUONVTriggerStore.h" |
9b220edf | 39 | #include "AliMpConstants.h" |
40 | #include "AliMpDEManager.h" | |
22fbde16 | 41 | |
42 | #include "AliCDBManager.h" | |
43 | ||
44 | #include <Rtypes.h> | |
45 | #include <Riostream.h> | |
46 | #include <TObjArray.h> | |
47 | #include <TIterator.h> | |
48 | #include <TMatrixD.h> | |
49 | ||
9b220edf | 50 | #include <cstdlib> |
22fbde16 | 51 | |
6ca54c85 | 52 | #endif |
53 | ||
54 | ||
9b220edf | 55 | /** |
56 | * This routine implements a the comparison functionality which is missing for | |
57 | * classes like AliMUONTrack and the various AliMUONxxxTrigger classes. | |
58 | * A result of -1 is returned if a < b, 0 if a == b and +1 if a > b. | |
59 | */ | |
60 | Int_t Compare(const TObject* a, const TObject* b) | |
6ca54c85 | 61 | { |
9b220edf | 62 | int result = -999; |
61fed964 | 63 | if (a->IsA() == AliMUONLocalTrigger::Class() && b->IsA() == AliMUONLocalTrigger::Class()) |
9b220edf | 64 | { |
65 | result = memcmp(a, b, sizeof(AliMUONLocalTrigger)); | |
66 | } | |
67 | else if (a->IsA() == AliMUONRegionalTrigger::Class() && b->IsA() == AliMUONRegionalTrigger::Class()) | |
68 | { | |
22fbde16 | 69 | const AliMUONRegionalTrigger* ra = static_cast<const AliMUONRegionalTrigger*>(a); |
70 | const AliMUONRegionalTrigger* rb = static_cast<const AliMUONRegionalTrigger*>(b); | |
71 | if (ra->GetId() < rb->GetId()) return -1; | |
72 | if (ra->GetId() > rb->GetId()) return 1; | |
73 | if (ra->GetLocalOutput(0) < rb->GetLocalOutput(0)) return -1; | |
74 | if (ra->GetLocalOutput(0) > rb->GetLocalOutput(0)) return 1; | |
75 | if (ra->GetLocalOutput(1) < rb->GetLocalOutput(1)) return -1; | |
76 | if (ra->GetLocalOutput(1) > rb->GetLocalOutput(1)) return 1; | |
77 | if (ra->GetLocalMask() < rb->GetLocalMask()) return -1; | |
78 | if (ra->GetLocalMask() > rb->GetLocalMask()) return 1; | |
79 | if (ra->GetOutput() < rb->GetOutput()) return -1; | |
80 | if (ra->GetOutput() > rb->GetOutput()) return 1; | |
81 | return 0; | |
9b220edf | 82 | } |
83 | else if (a->IsA() == AliMUONGlobalTrigger::Class() && b->IsA() == AliMUONGlobalTrigger::Class()) | |
84 | { | |
85 | result = memcmp(a, b, sizeof(AliMUONGlobalTrigger)); | |
86 | } | |
9b220edf | 87 | else |
6ca54c85 | 88 | { |
9b220edf | 89 | result = memcmp(a, b, sizeof(TObject)); |
6ca54c85 | 90 | } |
9b220edf | 91 | |
92 | if (result < 0) return -1; | |
93 | if (result > 0) return 1; | |
94 | return 0; | |
6ca54c85 | 95 | } |
96 | ||
9b220edf | 97 | /** |
98 | * This method fills internal arrays with local and regional triggers returned | |
99 | * by AliMUONMCDataInterface. For each set of interface methods available in | |
100 | * AliMUONMCDataInterface a TObjArray is created for local and another for regional | |
101 | * triggers. These arrays are filled with copies of the trigger objects. | |
102 | * The global trigger object is also copied out using the 2 different methods. | |
103 | * The arrays and objects are then compared to each other. The arrays and objects | |
104 | * should contain the same information if everything is working correctly with | |
105 | * AliMUONMCDataInterface. If not then the difference is printed together with an | |
22fbde16 | 106 | * error message and false is returned. |
9b220edf | 107 | */ |
108 | bool SimTriggersOk() | |
6ca54c85 | 109 | { |
22fbde16 | 110 | AliMUONMCDataInterface data("generated/galice.root"); |
9b220edf | 111 | for (Int_t event = 0; event < data.NumberOfEvents(); event++) |
112 | { | |
113 | TObjArray localsFromStore, regionalsFromStore; | |
114 | localsFromStore.SetOwner(kTRUE); | |
115 | regionalsFromStore.SetOwner(kTRUE); | |
116 | AliMUONVTriggerStore* store = data.TriggerStore(event); | |
22fbde16 | 117 | if (store == NULL) return false; |
9b220edf | 118 | AliMUONGlobalTrigger* globalFromStore = static_cast<AliMUONGlobalTrigger*>(store->Global()->Clone()); |
119 | TIter nextLocal(store->CreateLocalIterator()); | |
120 | AliMUONLocalTrigger* localTrig; | |
121 | while ( (localTrig = static_cast<AliMUONLocalTrigger*>( nextLocal() )) != NULL ) | |
122 | { | |
123 | localsFromStore.Add(localTrig->Clone()); | |
124 | } | |
125 | TIter nextRegional(store->CreateRegionalIterator()); | |
126 | AliMUONRegionalTrigger* regionalTrig; | |
127 | while ( (regionalTrig = static_cast<AliMUONRegionalTrigger*>( nextRegional() )) != NULL ) | |
128 | { | |
129 | regionalsFromStore.Add(regionalTrig->Clone()); | |
130 | } | |
131 | ||
132 | TObjArray localsByIndex, regionalsByIndex; | |
133 | localsByIndex.SetOwner(kTRUE); | |
134 | regionalsByIndex.SetOwner(kTRUE); | |
135 | data.GetEvent(event); | |
136 | AliMUONGlobalTrigger* globalByMethod = static_cast<AliMUONGlobalTrigger*>(data.GlobalTrigger()->Clone()); | |
137 | Int_t nlocals = data.NumberOfLocalTriggers(); | |
138 | for (Int_t i = 0; i < nlocals; i++) | |
139 | { | |
140 | localTrig = data.LocalTrigger(i); | |
141 | localsByIndex.Add(localTrig->Clone()); | |
142 | } | |
143 | Int_t nregionals = data.NumberOfRegionalTriggers(); | |
144 | for (Int_t i = 0; i < nregionals; i++) | |
145 | { | |
146 | regionalTrig = data.RegionalTrigger(i); | |
147 | regionalsByIndex.Add(regionalTrig->Clone()); | |
148 | } | |
149 | ||
150 | // Now check that all the lists of local, regional and global triggers | |
151 | // contain the same results. | |
152 | // They must. If they do not then something is wrong with the implementation | |
153 | // of AliMUONMCDataInterface. | |
154 | if (Compare(globalFromStore, globalByMethod) != 0) | |
155 | { | |
156 | Error( "SimTriggersOk", | |
157 | "The AliMUONMCDataInterface does not return identical global" | |
158 | " triggers through all its user interface methods." | |
159 | ); | |
160 | globalFromStore->Print(); | |
161 | globalByMethod->Print(); | |
162 | return false; | |
163 | } | |
164 | delete globalFromStore; | |
165 | delete globalByMethod; | |
166 | if (localsFromStore.GetEntriesFast() != localsByIndex.GetEntriesFast()) | |
167 | { | |
168 | Error( "SimTriggersOk", | |
169 | "The AliMUONMCDataInterface does not return all the local triggers" | |
170 | " correctly through all its user interface methods. We got the" | |
171 | " following numbers of local triggers: %d and %d", | |
172 | localsFromStore.GetEntriesFast(), | |
173 | localsByIndex.GetEntriesFast() | |
174 | ); | |
175 | return false; | |
176 | } | |
177 | if (regionalsFromStore.GetEntriesFast() != regionalsByIndex.GetEntriesFast()) | |
178 | { | |
179 | Error( "SimTriggersOk", | |
180 | "The AliMUONMCDataInterface does not return all the regional triggers" | |
181 | " correctly through all its user interface methods. We got the" | |
182 | " following numbers of regional triggers: %d and %d", | |
183 | regionalsFromStore.GetEntriesFast(), | |
184 | regionalsByIndex.GetEntriesFast() | |
185 | ); | |
186 | return false; | |
187 | } | |
188 | for (Int_t i = 0; i < localsFromStore.GetEntriesFast(); i++) | |
189 | { | |
190 | if (Compare(localsFromStore[i], localsByIndex[i]) != 0) | |
191 | { | |
192 | Error( "SimTriggersOk", | |
193 | "The AliMUONMCDataInterface does not return identical local" | |
194 | " triggers through all its user interface methods. The" | |
195 | " incorrect local trigger has index %d.", | |
196 | i | |
197 | ); | |
198 | localsFromStore[i]->Print(); | |
199 | localsByIndex[i]->Print(); | |
200 | return false; | |
201 | } | |
202 | } | |
203 | for (Int_t i = 0; i < regionalsFromStore.GetEntriesFast(); i++) | |
204 | { | |
205 | if (Compare(regionalsFromStore[i], regionalsByIndex[i]) != 0) | |
206 | { | |
207 | Error( "SimTriggersOk", | |
208 | "The AliMUONMCDataInterface does not return identical regional" | |
209 | " triggers through all its user interface methods. The" | |
210 | " incorrect regional trigger has index %d.", | |
211 | i | |
212 | ); | |
213 | regionalsFromStore[i]->Print(); | |
214 | regionalsByIndex[i]->Print(); | |
215 | return false; | |
216 | } | |
22fbde16 | 217 | regionalsFromStore[i]->Print(); |
218 | regionalsByIndex[i]->Print(); | |
219 | } | |
220 | } | |
221 | return true; | |
222 | } | |
223 | ||
224 | /** | |
225 | * This method fills internal arrays with s-digits returned by the AliMUONMCDataInterface. | |
226 | * For each set of interface methods available a TObjArray is filled with copies of | |
227 | * the s-digits. These arrays are sorted and then compared to each other. The arrays | |
228 | * should contain the same s-digit information if everything is working correctly with | |
229 | * AliMUONMCDataInterface. If not then the difference is printed together with an | |
230 | * error message and false is returned. | |
231 | */ | |
232 | bool SimSDigitsOk() | |
233 | { | |
234 | AliMUONMCDataInterface data("generated/galice.root"); | |
235 | for (Int_t event = 0; event < data.NumberOfEvents(); event++) | |
236 | { | |
237 | TObjArray digitsFromStore; | |
238 | digitsFromStore.SetOwner(kTRUE); | |
239 | AliMUONVDigitStore* store = data.SDigitStore(event); | |
240 | if (store == NULL) return false; | |
241 | TIter next(store->CreateIterator()); | |
242 | AliMUONVDigit* digit; | |
243 | while ( (digit = static_cast<AliMUONVDigit*>( next() )) != NULL ) | |
244 | { | |
245 | digitsFromStore.Add(digit->Clone()); | |
246 | } | |
247 | digitsFromStore.Sort(); | |
248 | ||
249 | TObjArray digitsByDetElem; | |
250 | digitsByDetElem.SetOwner(kTRUE); | |
251 | data.GetEvent(event); | |
252 | for (Int_t detElem = 0; detElem < 1500; detElem++) | |
253 | { | |
254 | if (! AliMpDEManager::IsValidDetElemId(detElem)) continue; | |
255 | Int_t ndigits = data.NumberOfSDigits(detElem); | |
256 | for (Int_t i = 0; i < ndigits; i++) | |
257 | { | |
258 | AliMUONVDigit* digit = data.SDigit(detElem, i); | |
259 | digitsByDetElem.Add(digit->Clone()); | |
260 | } | |
261 | } | |
262 | digitsByDetElem.Sort(); | |
263 | ||
264 | TObjArray digitsByChamber; | |
265 | digitsByChamber.SetOwner(kTRUE); | |
266 | data.GetEvent(event); | |
267 | for (Int_t chamber = 0; chamber < AliMpConstants::NofChambers(); chamber++) | |
268 | for (Int_t cathode = 0; cathode < 2; cathode++) | |
269 | { | |
270 | Int_t ndigits = data.NumberOfSDigits(chamber, cathode); | |
271 | for (Int_t i = 0; i < ndigits; i++) | |
272 | { | |
273 | AliMUONVDigit* digit = data.SDigit(chamber, cathode, i); | |
274 | digitsByChamber.Add(digit->Clone()); | |
275 | } | |
276 | } | |
277 | digitsByChamber.Sort(); | |
278 | ||
279 | // Now check that all the lists of s-digits contain the same results. | |
280 | // They must. If they do not then something is wrong with the implementation | |
281 | // of AliMUONMCDataInterface. | |
282 | if (digitsFromStore.GetEntriesFast() != digitsByDetElem.GetEntriesFast() | |
283 | || digitsFromStore.GetEntriesFast() != digitsByChamber.GetEntriesFast()) | |
284 | { | |
285 | Error( "SimSDigitsOk", | |
286 | "The AliMUONMCDataInterface does not return all the s-digits correctly" | |
287 | " through all its user interface methods. We got the following" | |
288 | " numbers of s-digits: %d, %d and %d", | |
289 | digitsFromStore.GetEntriesFast(), | |
290 | digitsByDetElem.GetEntriesFast(), | |
291 | digitsByChamber.GetEntriesFast() | |
292 | ); | |
293 | return false; | |
294 | } | |
295 | for (Int_t i = 0; i < digitsFromStore.GetEntriesFast(); i++) | |
296 | { | |
297 | if (digitsFromStore[i]->Compare(digitsByDetElem[i]) != 0 | |
298 | || digitsFromStore[i]->Compare(digitsByChamber[i]) != 0) | |
299 | { | |
300 | Error( "SimSDigitsOk", | |
301 | "The AliMUONMCDataInterface does not return identical s-digits" | |
302 | " through all its user interface methods. The incorrect" | |
303 | " s-digit has index %d after sorting.", | |
304 | i | |
305 | ); | |
306 | digitsFromStore[i]->Print(); | |
307 | digitsByChamber[i]->Print(); | |
308 | digitsByDetElem[i]->Print(); | |
309 | return false; | |
310 | } | |
311 | } | |
312 | } | |
313 | return true; | |
314 | } | |
315 | ||
316 | /** | |
317 | * This method fills internal arrays with digits returned by the AliMUONMCDataInterface. | |
318 | * For each set of interface methods available a TObjArray is filled with copies of | |
319 | * the digits. These arrays are sorted and then compared to each other. The arrays | |
320 | * should contain the same digit information if everything is working correctly with | |
321 | * AliMUONMCDataInterface. If not then the difference is printed together with an | |
322 | * error message and false is returned. | |
323 | */ | |
324 | bool SimDigitsOk() | |
325 | { | |
326 | AliMUONMCDataInterface data("generated/galice.root"); | |
327 | for (Int_t event = 0; event < data.NumberOfEvents(); event++) | |
328 | { | |
329 | TObjArray digitsFromStore; | |
330 | digitsFromStore.SetOwner(kTRUE); | |
331 | AliMUONVDigitStore* store = data.DigitStore(event); | |
332 | if (store == NULL) return false; | |
333 | TIter next(store->CreateIterator()); | |
334 | AliMUONVDigit* digit; | |
335 | while ( (digit = static_cast<AliMUONVDigit*>( next() )) != NULL ) | |
336 | { | |
337 | digitsFromStore.Add(digit->Clone()); | |
338 | } | |
339 | digitsFromStore.Sort(); | |
340 | ||
341 | TObjArray digitsByDetElem; | |
342 | digitsByDetElem.SetOwner(kTRUE); | |
343 | data.GetEvent(event); | |
344 | for (Int_t detElem = 0; detElem < 1500; detElem++) | |
345 | { | |
346 | if (! AliMpDEManager::IsValidDetElemId(detElem)) continue; | |
347 | Int_t ndigits = data.NumberOfDigits(detElem); | |
348 | for (Int_t i = 0; i < ndigits; i++) | |
349 | { | |
350 | AliMUONVDigit* digit = data.Digit(detElem, i); | |
351 | digitsByDetElem.Add(digit->Clone()); | |
352 | } | |
353 | } | |
354 | digitsByDetElem.Sort(); | |
355 | ||
356 | TObjArray digitsByChamber; | |
357 | digitsByChamber.SetOwner(kTRUE); | |
358 | data.GetEvent(event); | |
359 | for (Int_t chamber = 0; chamber < AliMpConstants::NofChambers(); chamber++) | |
360 | for (Int_t cathode = 0; cathode < 2; cathode++) | |
361 | { | |
362 | Int_t ndigits = data.NumberOfDigits(chamber, cathode); | |
363 | for (Int_t i = 0; i < ndigits; i++) | |
364 | { | |
365 | AliMUONVDigit* digit = data.Digit(chamber, cathode, i); | |
366 | digitsByChamber.Add(digit->Clone()); | |
367 | } | |
368 | } | |
369 | digitsByChamber.Sort(); | |
370 | ||
371 | // Now check that all the lists of digits contain the same results. | |
372 | // They must. If they do not then something is wrong with the implementation | |
373 | // of AliMUONMCDataInterface. | |
374 | if (digitsFromStore.GetEntriesFast() != digitsByDetElem.GetEntriesFast() | |
375 | || digitsFromStore.GetEntriesFast() != digitsByChamber.GetEntriesFast()) | |
376 | { | |
377 | Error( "SimDigitsOk", | |
378 | "The AliMUONMCDataInterface does not return all the digits correctly" | |
379 | " through all its user interface methods. We got the following" | |
380 | " numbers of digits: %d, %d and %d", | |
381 | digitsFromStore.GetEntriesFast(), | |
382 | digitsByDetElem.GetEntriesFast(), | |
383 | digitsByChamber.GetEntriesFast() | |
384 | ); | |
385 | return false; | |
386 | } | |
387 | for (Int_t i = 0; i < digitsFromStore.GetEntriesFast(); i++) | |
388 | { | |
389 | if (digitsFromStore[i]->Compare(digitsByDetElem[i]) != 0 | |
390 | || digitsFromStore[i]->Compare(digitsByChamber[i]) != 0) | |
391 | { | |
392 | Error( "SimDigitsOk", | |
393 | "The AliMUONMCDataInterface does not return identical digits" | |
394 | " through all its user interface methods. The incorrect" | |
395 | " digit has index %d after sorting.", | |
396 | i | |
397 | ); | |
398 | digitsFromStore[i]->Print(); | |
399 | digitsByChamber[i]->Print(); | |
400 | digitsByDetElem[i]->Print(); | |
401 | return false; | |
402 | } | |
403 | } | |
404 | } | |
405 | return true; | |
406 | } | |
407 | ||
408 | /** | |
409 | * This method fills internal arrays with hits returned by the AliMUONMCDataInterface. | |
410 | * For each set of interface methods available a TObjArray is filled with copies of | |
411 | * the hits. These arrays are then compared to each other. The arrays should contain | |
412 | * the same hit information if everything is working correctly with AliMUONMCDataInterface. | |
413 | * If not then the difference is printed together with an error message and false is returned. | |
414 | */ | |
415 | bool SimHitsOk() | |
416 | { | |
417 | AliMUONMCDataInterface data("generated/galice.root"); | |
418 | for (Int_t event = 0; event < data.NumberOfEvents(); event++) | |
419 | { | |
420 | if (data.NumberOfTracks(event) != data.NumberOfTracks()) | |
421 | { | |
422 | Error( "SimHitsOk", | |
423 | "The AliMUONMCDataInterface does not return the same number of tracks" | |
424 | " through all its user interface methods. We got the following" | |
425 | " numbers of tracks: %d and %d", | |
426 | data.NumberOfTracks(event), | |
427 | data.NumberOfTracks() | |
428 | ); | |
429 | return false; | |
430 | } | |
431 | ||
432 | for (Int_t track = 0; track < data.NumberOfTracks(); track++) | |
433 | { | |
434 | TObjArray hitsFromStore; | |
435 | hitsFromStore.SetOwner(kTRUE); | |
436 | AliMUONVHitStore* store = data.HitStore(event, track); | |
437 | if (store == NULL) return false; | |
438 | TIter next(store->CreateIterator()); | |
439 | AliMUONHit* hit; | |
440 | while ( (hit = static_cast<AliMUONHit*>( next() )) != NULL ) | |
441 | { | |
442 | hitsFromStore.Add(hit->Clone()); | |
443 | } | |
444 | //hitsFromStore.Sort(); // Unfortunately hits do not implement the Compare method. | |
445 | ||
446 | TObjArray hitsByMethod; | |
447 | hitsByMethod.SetOwner(kTRUE); | |
448 | data.GetEvent(event); | |
449 | for (Int_t i = 0; i < data.NumberOfHits(track); i++) | |
450 | { | |
451 | AliMUONHit* hit = data.Hit(track, i); | |
452 | hitsByMethod.Add(hit->Clone()); | |
453 | } | |
454 | //hitsByMethod.Sort(); // Unfortunately hits do not implement the Compare method. | |
455 | ||
456 | // Now check that both lists of hits contain the same results. | |
457 | // They must. If they do not then something is wrong with the implementation | |
458 | // of AliMUONMCDataInterface. | |
459 | if (hitsFromStore.GetEntriesFast() != hitsByMethod.GetEntriesFast()) | |
460 | { | |
461 | Error( "SimHitsOk", | |
462 | "The AliMUONMCDataInterface does not return all the hits correctly" | |
463 | " through all its user interface methods. We got the following" | |
464 | " numbers of hits: %d and %d", | |
465 | hitsFromStore.GetEntriesFast(), | |
466 | hitsByMethod.GetEntriesFast() | |
467 | ); | |
468 | return false; | |
469 | } | |
470 | for (Int_t i = 0; i < hitsFromStore.GetEntriesFast(); i++) | |
471 | { | |
472 | if (Compare(hitsFromStore[i], hitsByMethod[i]) != 0) | |
473 | { | |
474 | Error( "SimHitsOk", | |
475 | "The AliMUONMCDataInterface does not return identical hits" | |
476 | " through all its user interface methods. The incorrect" | |
477 | " hit has index %d after sorting, for track %d.", | |
478 | i, track | |
479 | ); | |
480 | hitsFromStore[i]->Print(); | |
481 | hitsByMethod[i]->Print(); | |
482 | return false; | |
483 | } | |
484 | } | |
9b220edf | 485 | } |
486 | } | |
487 | return true; | |
6ca54c85 | 488 | } |
489 | ||
9b220edf | 490 | /** |
491 | * This method fills internal arrays with digits returned by the AliMUONDataInterface. | |
492 | * For each set of interface methods available a TObjArray is filled with copies of | |
493 | * the digits. These arrays are sorted and then compared to each other. The arrays | |
494 | * should contain the same digit information if everything is working correctly with | |
495 | * AliMUONDataInterface. If not then the difference is printed together with an | |
22fbde16 | 496 | * error message and false is returned. |
9b220edf | 497 | */ |
498 | bool RecDigitsOk() | |
499 | { | |
500 | AliMUONDataInterface data; | |
501 | for (Int_t event = 0; event < data.NumberOfEvents(); event++) | |
502 | { | |
503 | TObjArray digitsFromStore; | |
504 | digitsFromStore.SetOwner(kTRUE); | |
505 | AliMUONVDigitStore* store = data.DigitStore(event); | |
22fbde16 | 506 | if (store == NULL) return false; |
9b220edf | 507 | TIter next(store->CreateIterator()); |
508 | AliMUONVDigit* digit; | |
509 | while ( (digit = static_cast<AliMUONVDigit*>( next() )) != NULL ) | |
510 | { | |
511 | digitsFromStore.Add(digit->Clone()); | |
512 | } | |
513 | digitsFromStore.Sort(); | |
514 | ||
515 | TObjArray digitsByDetElem; | |
516 | digitsByDetElem.SetOwner(kTRUE); | |
517 | data.GetEvent(event); | |
518 | for (Int_t detElem = 0; detElem < 1500; detElem++) | |
519 | { | |
520 | if (! AliMpDEManager::IsValidDetElemId(detElem)) continue; | |
521 | Int_t ndigits = data.NumberOfDigits(detElem); | |
522 | for (Int_t i = 0; i < ndigits; i++) | |
523 | { | |
524 | AliMUONVDigit* digit = data.Digit(detElem, i); | |
525 | digitsByDetElem.Add(digit->Clone()); | |
526 | } | |
527 | } | |
528 | digitsByDetElem.Sort(); | |
529 | ||
530 | TObjArray digitsByChamber; | |
531 | digitsByChamber.SetOwner(kTRUE); | |
532 | data.GetEvent(event); | |
533 | for (Int_t chamber = 0; chamber < AliMpConstants::NofChambers(); chamber++) | |
534 | for (Int_t cathode = 0; cathode < 2; cathode++) | |
535 | { | |
536 | Int_t ndigits = data.NumberOfDigits(chamber, cathode); | |
537 | for (Int_t i = 0; i < ndigits; i++) | |
538 | { | |
539 | AliMUONVDigit* digit = data.Digit(chamber, cathode, i); | |
540 | digitsByChamber.Add(digit->Clone()); | |
541 | } | |
542 | } | |
543 | digitsByChamber.Sort(); | |
544 | ||
545 | // Now check that all the lists of digits contain the same results. | |
546 | // They must. If they do not then something is wrong with the implementation | |
547 | // of AliMUONDataInterface. | |
548 | if (digitsFromStore.GetEntriesFast() != digitsByDetElem.GetEntriesFast() | |
549 | || digitsFromStore.GetEntriesFast() != digitsByChamber.GetEntriesFast()) | |
550 | { | |
551 | Error( "RecDigitsOk", | |
552 | "The AliMUONDataInterface does not return all the digits correctly" | |
553 | " through all its user interface methods. We got the following" | |
554 | " numbers of digits: %d, %d and %d", | |
555 | digitsFromStore.GetEntriesFast(), | |
556 | digitsByDetElem.GetEntriesFast(), | |
557 | digitsByChamber.GetEntriesFast() | |
558 | ); | |
559 | return false; | |
560 | } | |
561 | for (Int_t i = 0; i < digitsFromStore.GetEntriesFast(); i++) | |
562 | { | |
563 | if (digitsFromStore[i]->Compare(digitsByDetElem[i]) != 0 | |
564 | || digitsFromStore[i]->Compare(digitsByChamber[i]) != 0) | |
565 | { | |
566 | Error( "RecDigitsOk", | |
567 | "The AliMUONDataInterface does not return identical digits" | |
568 | " through all its user interface methods. The incorrect" | |
569 | " digit has index %d after sorting.", | |
570 | i | |
571 | ); | |
572 | digitsFromStore[i]->Print(); | |
573 | digitsByChamber[i]->Print(); | |
574 | digitsByDetElem[i]->Print(); | |
575 | return false; | |
576 | } | |
577 | } | |
578 | } | |
579 | return true; | |
580 | } | |
6ca54c85 | 581 | |
9b220edf | 582 | /** |
583 | * This method fills internal arrays with raw clusters returned by AliMUONDataInterface. | |
584 | * For each set of interface methods available in AliMUONDataInterface a TObjArray is | |
585 | * filled with copies of the raw clusters. These arrays are sorted and then compared | |
586 | * to each other. The arrays should contain the same information if everything is | |
587 | * working correctly with AliMUONDataInterface. If not then the difference is printed | |
22fbde16 | 588 | * together with an error message and false is returned. |
9b220edf | 589 | */ |
590 | bool RawClustersOk() | |
6ca54c85 | 591 | { |
9b220edf | 592 | AliMUONDataInterface data; |
593 | for (Int_t event = 0; event < data.NumberOfEvents(); event++) | |
6ca54c85 | 594 | { |
9b220edf | 595 | TObjArray clustersFromStore; |
596 | clustersFromStore.SetOwner(kTRUE); | |
597 | AliMUONVClusterStore* store = data.ClusterStore(event); | |
22fbde16 | 598 | if (store == NULL) return false; |
9b220edf | 599 | TIter next(store->CreateIterator()); |
2060b217 | 600 | AliMUONVCluster* cluster; |
601 | while ( (cluster = static_cast<AliMUONVCluster*>( next() )) != NULL ) | |
9b220edf | 602 | { |
603 | clustersFromStore.Add(cluster->Clone()); | |
604 | } | |
605 | clustersFromStore.Sort(); | |
606 | ||
607 | TObjArray clustersByChamber; | |
608 | clustersByChamber.SetOwner(kTRUE); | |
609 | data.GetEvent(event); | |
61fed964 | 610 | for (Int_t chamber = 0; chamber < AliMpConstants::NofTrackingChambers(); chamber++) |
9b220edf | 611 | { |
612 | Int_t nclusters = data.NumberOfRawClusters(chamber); | |
613 | for (Int_t i = 0; i < nclusters; i++) | |
614 | { | |
2060b217 | 615 | AliMUONVCluster* cluster = data.RawCluster(chamber, i); |
9b220edf | 616 | clustersByChamber.Add(cluster->Clone()); |
617 | } | |
618 | } | |
619 | clustersByChamber.Sort(); | |
620 | ||
621 | // Now check that all the lists of clusters contain the same results. | |
622 | // They must. If they do not then something is wrong with the implementation | |
623 | // of AliMUONDataInterface. | |
624 | if (clustersFromStore.GetEntriesFast() != clustersByChamber.GetEntriesFast()) | |
625 | { | |
626 | Error( "RawClustersOk", | |
627 | "The AliMUONDataInterface does not return all the clusters correctly" | |
628 | " through all its user interface methods. We got the following" | |
629 | " numbers of clusters: %d and %d", | |
630 | clustersFromStore.GetEntriesFast(), | |
631 | clustersByChamber.GetEntriesFast() | |
632 | ); | |
633 | return false; | |
634 | } | |
635 | for (Int_t i = 0; i < clustersFromStore.GetEntriesFast(); i++) | |
636 | { | |
637 | if (clustersFromStore[i]->Compare(clustersByChamber[i]) != 0) | |
638 | { | |
639 | Error( "RawClustersOk", | |
640 | "The AliMUONDataInterface does not return identical clusters" | |
641 | " through all its user interface methods. The incorrect" | |
642 | " cluster has index %d after sorting.", | |
643 | i | |
644 | ); | |
645 | clustersFromStore[i]->Print(); | |
646 | clustersByChamber[i]->Print(); | |
647 | return false; | |
648 | } | |
649 | } | |
650 | } | |
651 | return true; | |
6ca54c85 | 652 | } |
653 | ||
9b220edf | 654 | /** |
655 | * This method fills internal arrays with local and regional triggers returned | |
656 | * by AliMUONDataInterface. For each set of interface methods available in | |
657 | * AliMUONDataInterface a TObjArray is created for local and another for regional | |
658 | * triggers. These arrays are filled with copies of the trigger objects. | |
659 | * The global trigger object is also copied out using the 2 different methods. | |
660 | * The arrays and objects are then compared to each other. The arrays and objects | |
661 | * should contain the same information if everything is working correctly with | |
662 | * AliMUONDataInterface. If not then the difference is printed together with an | |
22fbde16 | 663 | * error message and false is returned. |
9b220edf | 664 | */ |
665 | bool TriggersOk() | |
6ca54c85 | 666 | { |
9b220edf | 667 | AliMUONDataInterface data; |
668 | for (Int_t event = 0; event < data.NumberOfEvents(); event++) | |
669 | { | |
670 | TObjArray localsFromStore, regionalsFromStore; | |
671 | localsFromStore.SetOwner(kTRUE); | |
672 | regionalsFromStore.SetOwner(kTRUE); | |
673 | AliMUONVTriggerStore* store = data.TriggerStore(event); | |
22fbde16 | 674 | if (store == NULL) return false; |
9b220edf | 675 | AliMUONGlobalTrigger* globalFromStore = static_cast<AliMUONGlobalTrigger*>(store->Global()->Clone()); |
676 | TIter nextLocal(store->CreateLocalIterator()); | |
677 | AliMUONLocalTrigger* localTrig; | |
678 | while ( (localTrig = static_cast<AliMUONLocalTrigger*>( nextLocal() )) != NULL ) | |
679 | { | |
680 | localsFromStore.Add(localTrig->Clone()); | |
681 | } | |
682 | TIter nextRegional(store->CreateRegionalIterator()); | |
683 | AliMUONRegionalTrigger* regionalTrig; | |
684 | while ( (regionalTrig = static_cast<AliMUONRegionalTrigger*>( nextRegional() )) != NULL ) | |
685 | { | |
686 | regionalsFromStore.Add(regionalTrig->Clone()); | |
687 | } | |
688 | ||
689 | TObjArray localsByIndex, regionalsByIndex; | |
690 | localsByIndex.SetOwner(kTRUE); | |
691 | regionalsByIndex.SetOwner(kTRUE); | |
692 | data.GetEvent(event); | |
693 | AliMUONGlobalTrigger* globalByMethod = static_cast<AliMUONGlobalTrigger*>(data.GlobalTrigger()->Clone()); | |
694 | Int_t nlocals = data.NumberOfLocalTriggers(); | |
695 | for (Int_t i = 0; i < nlocals; i++) | |
696 | { | |
697 | localTrig = data.LocalTrigger(i); | |
698 | localsByIndex.Add(localTrig->Clone()); | |
699 | } | |
700 | Int_t nregionals = data.NumberOfRegionalTriggers(); | |
701 | for (Int_t i = 0; i < nregionals; i++) | |
702 | { | |
703 | regionalTrig = data.RegionalTrigger(i); | |
704 | regionalsByIndex.Add(regionalTrig->Clone()); | |
705 | } | |
706 | ||
707 | // Now check that all the lists of local, regional and global triggers | |
708 | // contain the same results. | |
709 | // They must. If they do not then something is wrong with the implementation | |
710 | // of AliMUONDataInterface. | |
711 | if (Compare(globalFromStore, globalByMethod) != 0) | |
712 | { | |
713 | Error( "TriggersOk", | |
714 | "The AliMUONDataInterface does not return identical global" | |
715 | " triggers through all its user interface methods." | |
716 | ); | |
717 | globalFromStore->Print(); | |
718 | globalByMethod->Print(); | |
719 | return false; | |
720 | } | |
721 | delete globalFromStore; | |
722 | delete globalByMethod; | |
723 | if (localsFromStore.GetEntriesFast() != localsByIndex.GetEntriesFast()) | |
724 | { | |
725 | Error( "TriggersOk", | |
726 | "The AliMUONDataInterface does not return all the local triggers" | |
727 | " correctly through all its user interface methods. We got the" | |
728 | " following numbers of local triggers: %d and %d", | |
729 | localsFromStore.GetEntriesFast(), | |
730 | localsByIndex.GetEntriesFast() | |
731 | ); | |
732 | return false; | |
733 | } | |
734 | if (regionalsFromStore.GetEntriesFast() != regionalsByIndex.GetEntriesFast()) | |
735 | { | |
736 | Error( "TriggersOk", | |
737 | "The AliMUONDataInterface does not return all the regional triggers" | |
738 | " correctly through all its user interface methods. We got the" | |
739 | " following numbers of regional triggers: %d and %d", | |
740 | regionalsFromStore.GetEntriesFast(), | |
741 | regionalsByIndex.GetEntriesFast() | |
742 | ); | |
743 | return false; | |
744 | } | |
745 | for (Int_t i = 0; i < localsFromStore.GetEntriesFast(); i++) | |
746 | { | |
747 | if (Compare(localsFromStore[i], localsByIndex[i]) != 0) | |
748 | { | |
749 | Error( "TriggersOk", | |
750 | "The AliMUONDataInterface does not return identical local" | |
751 | " triggers through all its user interface methods. The" | |
752 | " incorrect local trigger has index %d.", | |
753 | i | |
754 | ); | |
755 | localsFromStore[i]->Print(); | |
756 | localsByIndex[i]->Print(); | |
757 | return false; | |
758 | } | |
759 | } | |
760 | for (Int_t i = 0; i < regionalsFromStore.GetEntriesFast(); i++) | |
761 | { | |
762 | if (Compare(regionalsFromStore[i], regionalsByIndex[i]) != 0) | |
763 | { | |
764 | Error( "TriggersOk", | |
765 | "The AliMUONDataInterface does not return identical regional" | |
766 | " triggers through all its user interface methods. The" | |
767 | " incorrect regional trigger has index %d.", | |
768 | i | |
769 | ); | |
770 | regionalsFromStore[i]->Print(); | |
771 | regionalsByIndex[i]->Print(); | |
772 | return false; | |
773 | } | |
774 | } | |
775 | } | |
776 | return true; | |
6ca54c85 | 777 | } |
778 | ||
9b220edf | 779 | /** |
780 | * This method performs a check of the AliMUONDataInterface and AliMUONMCDataInterface | |
781 | * classes. Basically there are at least 2 ways to fetch data using these interfaces: | |
782 | * The expert way using the store objects returned by these interface classes or | |
783 | * the much slower but easier way of using the NumberOfxxx and Digit(...), | |
784 | * RawCluster(...), Track(...) etc. methods to fetch individual data objects. | |
785 | * The MUONCheckDI will check that all these various ways of fetching data results | |
786 | * in the same information being returned. If yes then kTRUE is returned and a | |
787 | * confirmation message is printed, if not then kFALSE is returned with the failure | |
788 | * reason printed to screen. | |
789 | */ | |
22fbde16 | 790 | bool MUONCheckDI(bool checkSim = true, bool checkRec = true) |
9b220edf | 791 | { |
22fbde16 | 792 | AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT"); |
793 | ||
794 | // Note: we do not bother checking the AliMUONMCDataInterface::Particle, | |
795 | // AliMUONMCDataInterface::Stack and AliMUONMCDataInterface::TrackRefs methods | |
796 | // because they are trivial enough to validate from a quick inspecition of | |
797 | // the source code. | |
9b220edf | 798 | |
22fbde16 | 799 | if (checkSim) |
800 | { | |
801 | cout << "Checking simulated hits..." << endl; | |
802 | if (! SimHitsOk()) return false; | |
803 | cout << "Simulated hits look OK." << endl; | |
804 | ||
805 | cout << "Checking simulated s-digits..." << endl; | |
806 | if (! SimSDigitsOk()) return false; | |
807 | cout << "Simulated s-digits look OK." << endl; | |
808 | ||
809 | cout << "Checking simulated digits..." << endl; | |
810 | if (! SimDigitsOk()) return false; | |
811 | cout << "Simulated digits look OK." << endl; | |
812 | ||
813 | cout << "Checking simulated triggers..." << endl; | |
814 | if (! SimTriggersOk()) return false; | |
815 | cout << "Simulated triggers look OK." << endl; | |
816 | } | |
9b220edf | 817 | |
22fbde16 | 818 | if (checkRec) |
819 | { | |
820 | cout << "Checking reconstructed digits..." << endl; | |
821 | if (! RecDigitsOk()) return false; | |
822 | cout << "Reconstructed digits look OK." << endl; | |
823 | ||
824 | cout << "Checking raw clusters..." << endl; | |
825 | if (! RawClustersOk()) return false; | |
826 | cout << "Raw clusters look OK." << endl; | |
827 | ||
828 | cout << "Checking reconstructed triggers..." << endl; | |
829 | if (! TriggersOk()) return false; | |
830 | cout << "Reconstructed triggers look OK." << endl; | |
831 | } | |
9b220edf | 832 | |
9b220edf | 833 | return true; |
6ca54c85 | 834 | } |