ec545cf220da80fa16acc4e1a541338f14711561
[u/mrichter/AliRoot.git] / HLT / MUON / src / AliRoot / ClusterSource.cxx
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Author: Artur Szostak
4 // Email:  artur@alice.phy.uct.ac.za | artursz@iafrica.com
5 //
6 ////////////////////////////////////////////////////////////////////////////////
7
8 #include "AliRoot/ClusterSource.hpp"
9 #include "AliRoot/Base.hpp"
10 #include "AliMUONConstants.h"
11 #include "AliMUONHit.h"
12 #include "AliMUONRawCluster.h"
13 #include "AliMUONDataInterface.h"
14 #ifndef __alpha
15 #include <math.h>
16 #else
17 #include <float.h>
18 #endif
19
20 ClassImp(AliMUONHLT::ClusterSource)
21 ClassImp(AliMUONHLT::ClusterSource::BlockData)
22 ClassImp(AliMUONHLT::ClusterSource::EventData)
23
24 namespace AliMUONHLT
25 {
26
27
28 ClusterSource::ClusterSource()
29         : TObject(), fEventList(ClusterSource::EventData::Class())
30 {
31         fAreaToUse = FromWholePlane;
32         fDataToUse = FromRawClusters;
33         fMaxBlockSize = 0xFFFFFFFF;
34         fFilename = "";
35         fFoldername = "";
36         ResetAllPointers();
37 }
38
39
40 ClusterSource::ClusterSource(AliMUONDataInterface* data)
41         : TObject(), fEventList(ClusterSource::EventData::Class())
42 {
43         fAreaToUse = FromWholePlane;
44         fDataToUse = FromRawClusters;
45         fMaxBlockSize = 0xFFFFFFFF;
46         fFilename = "";
47         fFoldername = "";
48         ResetAllPointers();
49         FillFrom(data);
50 }
51
52
53 ClusterSource::~ClusterSource()
54 {
55         fEventList.Clear("C");
56 }
57
58
59 void ClusterSource::FillFrom(AliMUONDataInterface* data)
60 {
61         DebugMsg(1, "FillFrom(AliMUONDataInterface*)");
62         
63         if (FileAndFolderOk(data))
64         {
65                 for (Int_t i = 0; i < data->NumberOfEvents(); i++)
66                 {
67                         AddEventFrom(data, i);
68                 }
69         }
70 }
71
72
73 void ClusterSource::FillFrom(AliMUONDataInterface* data, Int_t event)
74 {
75         DebugMsg(1, "FillFrom(AliMUONDataInterface*, Int_t)");
76         
77         if (FileAndFolderOk(data))
78                 AddEventFrom(data, event);
79 }
80
81
82 void ClusterSource::FillFrom(AliMUONDataInterface* data, Int_t event, Int_t chamber)
83 {
84         DebugMsg(1, "FillFrom(AliMUONDataInterface*, Int_t)");
85         
86         if (FileAndFolderOk(data))
87         {
88                 if ( data->GetEvent(event) )
89                 {
90                         AddEvent(event);
91                         AddChamberFrom(data, chamber);
92                 }
93         }
94 }
95
96
97 void ClusterSource::FillFrom(
98                 AliMUONDataInterface* data,
99                 Int_t event, Int_t chamber, Int_t cluster,
100                 Bool_t newblock
101         )
102 {
103         DebugMsg(1, "FillFrom(AliMUONDataInterface*, Int_t, Int_t, Int_t, Bool_t)");
104         
105         if (FileAndFolderOk(data))
106         {
107                 data->GetEvent(event);
108
109                 // Check if the current event corresponds to the event number we are
110                 // attempting to add to. If they do not or no event is selected then
111                 // try find the event or create a new one.
112                 if ( fCurrentEvent == NULL )
113                 {
114                         Bool_t found = GetEvent(event);
115                         if ( ! found) AddEvent(event);
116                 }
117                 else
118                 {
119                         if (fCurrentEvent->fEventNumber != event)
120                         {
121                                 Bool_t found = GetEvent(event);
122                                 if ( ! found) AddEvent(event);
123                         }
124                 }
125                 
126                 if ( fCurrentBlock != 0)
127                 {
128                         Assert( fCurrentEvent != NULL );
129                         
130                         if ( fCurrentBlock->fChamber != chamber)
131                         {
132                                 // Create a new block if the current blocks chamber number does
133                                 // not correspond to the specified chamber.
134                                 AddBlock(chamber);
135                         }
136                         else
137                         {
138                                 // If the newblock flag is set then force a new block.
139                                 if (newblock) AddBlock(chamber);
140                         }
141                 }
142                 else
143                         AddBlock(chamber);  // No block selected so we need to create a new block.
144
145                 AddClusterFrom(data, chamber, cluster);
146         }
147 }
148
149
150 void ClusterSource::Clear(Option_t* /*option*/)
151 {
152         fFilename = "";
153         fFoldername = "";
154         ResetAllPointers();
155         fEventList.Delete();
156 }
157
158
159 Bool_t ClusterSource::GetEvent(Int_t eventnumber) const
160 {
161         DebugMsg(1, "ClusterSource::GetEvent(" << eventnumber << ")" );
162         
163         // Try find the corresponding event in the list of events.
164         for (Int_t i = 0; i < fEventList.GetEntriesFast(); i++)
165         {
166                 EventData* current = (EventData*) fEventList[i];
167                 if (current->fEventNumber == eventnumber)
168                 {
169                         fEventIndex = i;
170                         fCurrentEvent = current;
171                         GetFirstBlock();
172                         DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
173                                 << " , fClusterIndex = " << fClusterIndex
174                         );
175                         return kTRUE;
176                 }
177         }
178         return kFALSE;
179 }
180
181
182 Bool_t ClusterSource::GetFirstEvent() const
183 {
184         DebugMsg(1, "ClusterSource::GetFirstEvent()");
185         if (fEventList.GetEntriesFast() > 0)
186         {
187                 fEventIndex = 0;
188                 fCurrentEvent = (EventData*) fEventList[0];
189                 GetFirstBlock();
190                 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
191                         << " , fClusterIndex = " << fClusterIndex
192                 );
193                 return kTRUE;
194         }
195         else
196         {
197                 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
198                         << " , fClusterIndex = " << fClusterIndex
199                 );
200                 return kFALSE;
201         }
202 }
203
204
205 Bool_t ClusterSource::MoreEvents() const
206 {
207         return 0 <= fEventIndex && fEventIndex < fEventList.GetEntriesFast();
208 }
209
210
211 Bool_t ClusterSource::GetNextEvent() const
212 {
213         DebugMsg(1, "ClusterSource::GetNextEvent()");
214         if (fEventIndex < fEventList.GetEntriesFast() - 1)
215         {
216                 fCurrentEvent = (EventData*) fEventList[ ++fEventIndex ];
217                 GetFirstBlock();
218                 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
219                         << " , fClusterIndex = " << fClusterIndex
220                 );
221                 return kTRUE;
222         }
223         else
224         {
225                 ResetAllPointers();
226                 return kFALSE;
227         }
228 }
229
230
231 Int_t ClusterSource::CurrentEvent() const
232 {
233         if (fCurrentEvent != NULL)
234                 return fCurrentEvent->fEventNumber;
235         else
236                 return -1;
237 }
238
239
240 Int_t ClusterSource::NumberOfBlocks() const
241 {
242         DebugMsg(1, "ClusterSource::NumberOfBlocks()");
243         if (fCurrentEvent == NULL)
244         {
245                 Error("NumberOfBlocks", "No event selected.");
246                 return -1;
247         }
248         else
249                 return fCurrentEvent->fBlocks.GetEntriesFast();
250 }
251
252
253 Bool_t ClusterSource::GetBlock(Int_t index) const
254 {
255         DebugMsg(1, "ClusterSource::GetBlock(" << index << ")");
256         
257         // Note NumberOfBlocks() also checks if the event was selected.
258         Int_t numberofblocks = NumberOfBlocks();
259         if (numberofblocks < 0) return kFALSE;
260
261         if ( 0 <= index && index < numberofblocks )
262         {
263                 fBlockIndex = index;
264                 fCurrentBlock = (BlockData*) fCurrentEvent->fBlocks[index];
265                 GetFirstCluster();
266                 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
267                         << " , fClusterIndex = " << fClusterIndex
268                 );
269                 return kTRUE;
270         }
271         else
272         {
273                 // The index is out of bounds so inform the user.
274                 if (numberofblocks > 0)
275                         Error(  "GetBlock",
276                                 "The block index (%d) is out of bounds. Valid range is [0, %d]",
277                                 index, numberofblocks - 1
278                         );
279                 else
280                         Error(  "GetBlock",
281                                 "The block index (%d) is out of bounds. No blocks found.",
282                                 index
283                         );
284                 return kFALSE;
285         }
286 }
287
288
289 Bool_t ClusterSource::GetFirstBlock() const
290 {
291         DebugMsg(1, "ClusterSource::GetFirstBlock()");
292         // Note: NumberOfBlocks() also checks if fCurrentEvent != NULL.
293         if (NumberOfBlocks() > 0)
294         {
295                 fBlockIndex = 0;
296                 fCurrentBlock = (BlockData*) fCurrentEvent->fBlocks[fBlockIndex];
297                 GetFirstCluster();
298                 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
299                         << " , fClusterIndex = " << fClusterIndex
300                 );
301                 return kTRUE;
302         }
303         else
304                 return kFALSE;
305 }
306
307
308 Bool_t ClusterSource::MoreBlocks() const
309 {
310         return 0 <= fBlockIndex && fBlockIndex < NumberOfBlocks();
311 }
312
313
314 Bool_t ClusterSource::GetNextBlock() const
315 {
316         DebugMsg(1, "ClusterSource::GetNextBlock()");
317
318         // Note: NumberOfBlocks() checks if fCurrentEvent != NULL. If it is then it returns -1
319         // and since fBlockIndex is always >= -1 the if statement must go to the else part.
320         if (fBlockIndex < NumberOfBlocks() - 1)
321         {
322                 fCurrentBlock = (BlockData*) fCurrentEvent->fBlocks[ ++fBlockIndex ];
323                 GetFirstCluster();
324                 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
325                         << " , fClusterIndex = " << fClusterIndex
326                 );
327                 return kTRUE;
328         }
329         else
330         {
331                 ResetBlockPointers();
332                 return kFALSE;
333         }
334 }
335
336
337 Int_t ClusterSource::Chamber() const
338 {
339         if (fCurrentBlock == NULL)
340         {
341                 Error("Chamber", "No block selected.");
342                 return -1;
343         }
344         else
345                 return fCurrentBlock->fChamber;
346 }
347
348
349 Int_t ClusterSource::NumberOfClusters() const
350 {
351         DebugMsg(1, "ClusterSource::NumberOfClusters()");
352         if (fCurrentBlock == NULL)
353         {
354                 Error("NumberOfClusters", "No block selected.");
355                 return -1;
356         }
357         else
358                 return fCurrentBlock->fClusters.GetEntriesFast();
359 }
360
361
362 const Point* ClusterSource::GetCluster(Int_t index) const
363 {
364         DebugMsg(1, "ClusterSource::GetCluster(" << index << ")");
365
366         // Note NumberOfClusters() also checks if the event and block was selected.
367         Int_t numberofclusters = NumberOfClusters();
368         if (numberofclusters < 0) return NULL;
369         
370         if ( 0 <= index && index < numberofclusters )
371         {
372                 fClusterIndex = index;
373                 fCurrentCluster = (Point*) fCurrentBlock->fClusters[index];
374                 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
375                         << " , fClusterIndex = " << fClusterIndex
376                 );
377                 return fCurrentCluster;
378         }
379         else
380         {
381                 // The index is out of bounds so inform the user.
382                 if (numberofclusters > 0)
383                         Error(  "GetCluster",
384                                 "The cluster index (%d) is out of bounds. Valid range is [0, %d]",
385                                 index, numberofclusters - 1
386                         );
387                 else
388                         Error(  "GetCluster",
389                                 "The cluster index (%d) is out of bounds. No clusters found.",
390                                 index
391                         );
392                 return NULL;
393         }
394 }
395
396
397 const Point* ClusterSource::GetFirstCluster() const
398 {
399         DebugMsg(1, "ClusterSource::GetFirstCluster()");
400         // Note: NumberOfClusters() also checks if fCurrentBlock != NULL.
401         if (NumberOfClusters() > 0)
402         {
403                 fClusterIndex = 0;
404                 fCurrentCluster = (Point*) fCurrentBlock->fClusters[0];
405                 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
406                         << " , fClusterIndex = " << fClusterIndex
407                 );
408                 return fCurrentCluster;
409         }
410         else
411                 return NULL;
412 }
413
414
415 Bool_t ClusterSource::MoreClusters() const
416 {
417         return 0 <= fClusterIndex && fClusterIndex < NumberOfClusters();
418 }
419
420
421 const Point* ClusterSource::GetNextCluster() const
422 {
423         DebugMsg(1, "ClusterSource::GetNextCluster()");
424         
425         // Note: NumberOfClusters() checks if fCurrentBlock != NULL. If it is then it returns -1
426         // and since fClusterIndex is always >= -1 the if statement must go to the else part.
427         if (fClusterIndex < NumberOfClusters() - 1)
428         {
429                 fCurrentCluster = (Point*) fCurrentBlock->fClusters[ ++fClusterIndex ];
430                 DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
431                         << " , fClusterIndex = " << fClusterIndex
432                 );
433                 return fCurrentCluster;
434         }
435         else
436         {
437                 ResetClusterPointers();
438                 return NULL;
439         }
440 }
441
442
443 Bool_t ClusterSource::FetchCluster(Float_t& x, Float_t& y) const
444 {
445         if (fCurrentCluster != NULL)
446         {
447                 x = fCurrentCluster->fX;
448                 y = fCurrentCluster->fY;
449                 return kTRUE;
450         }
451         else
452         {
453                 Error("FetchCluster", "No cluster point selected.");
454                 return kFALSE;
455         }
456 }
457
458
459 void ClusterSource::AddEvent(Int_t eventnumber)
460 {
461         DebugMsg(1, "ClusterSource::AddEvent(" << eventnumber << ")");
462         Assert( eventnumber >= 0 );
463
464         // Assume the eventnumber does not already exist in the event list.
465         fEventIndex = fEventList.GetEntriesFast();
466         new ( fEventList[fEventIndex] ) EventData(eventnumber);
467         fCurrentEvent = (EventData*) fEventList[fEventIndex];
468         
469         // Remember to reset the other pointers because the new event is empty.
470         ResetBlockPointers();
471         
472         DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
473                 << " , fClusterIndex = " << fClusterIndex
474         );
475 }
476
477
478 void ClusterSource::AddBlock(Int_t chamber)
479 {
480         DebugMsg(1, "ClusterSource::AddBlock()");
481         
482         if (fCurrentEvent == NULL)
483         {
484                 Error("AddBlock", "No event selected.");
485                 return;
486         }
487         
488         fBlockIndex = fCurrentEvent->fBlocks.GetEntriesFast();
489         new ( fCurrentEvent->fBlocks[fBlockIndex] ) BlockData(chamber);
490         fCurrentBlock = (BlockData*) fCurrentEvent->fBlocks[fBlockIndex];
491         
492         // Remember to reset the trigger pointer because the new block is empty.
493         ResetClusterPointers();
494
495         DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
496                 << " , fClusterIndex = " << fClusterIndex
497         );
498 }
499
500
501 void ClusterSource::AddPoint(Float_t x, Float_t y)
502 {
503         DebugMsg(1, "ClusterSource::AddPoint(" << x << ", " << y << ")");
504
505         if (fCurrentBlock == NULL)
506         {
507                 Error("AddPoint", "No block selected.");
508                 return;
509         }
510         
511         fClusterIndex = fCurrentBlock->fClusters.GetEntriesFast();
512         new ( fCurrentBlock->fClusters[fClusterIndex] ) Point(x, y);
513         fCurrentCluster = (Point*) fCurrentBlock->fClusters[fClusterIndex];
514         
515         DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
516                 << " , fClusterIndex = " << fClusterIndex
517         );
518 }
519
520
521 Bool_t ClusterSource::FileAndFolderOk(AliMUONDataInterface* data)
522 {
523         if (fFilename == "")
524         {
525                 // Nothing filled yet so set the file and folder names.
526                 fFilename = data->CurrentFile();
527                 fFoldername = data->CurrentFolder();
528                 return kTRUE;
529         }
530
531         if ( fFilename != data->CurrentFile() )
532         {
533                 Error(  "FileAndFolderOk",
534                         "The cluster source already contains data from file '%s', cannot add data from file '%s'",
535                         fFilename.Data(), data->CurrentFile().Data()
536                 );
537                 return kFALSE;
538         }
539         
540         if ( fFoldername != data->CurrentFolder() )
541         {
542                 Error(  "FileAndFolderOk",
543                         "The cluster source already contains data from folder '%s', cannot add data from folder '%s'",
544                         fFoldername.Data(), data->CurrentFolder().Data()
545                 );
546                 return kFALSE;
547         }
548         
549         return kTRUE;
550 }
551
552
553 void ClusterSource::AddEventFrom(AliMUONDataInterface* data, Int_t event)
554 {
555         if ( data->GetEvent(event) )
556         {
557                 AddEvent(event);
558                 for (Int_t chamber = 0; chamber < AliMUONConstants::NTrackingCh(); chamber++)
559                 {
560                         AddChamberFrom(data, chamber);
561                 }
562         }
563 }
564
565
566 void ClusterSource::AddChamberFrom(AliMUONDataInterface* data, Int_t chamber)
567 {
568         DebugMsg(1, "Entering AddChamberFrom");
569         
570         AddBlock(chamber);
571         UInt_t currentblocksize = 0;
572 #ifndef __alpha
573 #ifndef __sun
574         Float_t x = nanf(""), y = nanf("");
575 #else
576         Float_t x = 0, y = 0;
577 #endif
578 #else
579         Float_t x = FLT_QNAN, y = FLT_QNAN;
580 #endif
581         
582         switch (fDataToUse)
583         {
584         case FromHits:
585                 for (Int_t track = 0; track < data->NumberOfTracks(); track++)
586                 {
587                         // Find the hit that corresponds to the current chamber number.
588                         Int_t i;
589                         for (i = 0; i < data->NumberOfHits(track); i++)
590                         {
591                                 AliMUONHit* h = data->Hit(track, i);
592                                 // Note AliMUONHit::Chamber() returns a value in the range 1..14
593                                 if (h->Chamber() == chamber + 1)
594                                 {
595                                         x = h->X();
596                                         y = h->Y();
597                                         break;
598                                 }
599                         }
600
601                         // Continue to the next track if we could not find a hit
602                         // on the current track and chamber.
603                         if (i >= data->NumberOfHits(track))
604                         {
605                                 Warning("AddChamberFrom", "Could not find hit on chamber: %d , track: %d , event: %d", 
606                                         chamber, track, data->CurrentEvent()
607                                 );
608                                 continue;
609                         }
610
611                         if (InFillRegion(x, y))
612                         {
613                                 AddPoint(x, y);
614
615                                 // Create a new block if we reached the maximum block size.
616                                 if ( ++currentblocksize == fMaxBlockSize )
617                                 {
618                                         AddBlock(chamber);
619                                         currentblocksize = 0;
620                                 }
621                         }
622                 }
623                 break;
624
625         case FromRawClusters:
626                 for (Int_t i = 0; i < data->NumberOfRawClusters(chamber); i++)
627                 {
628                         AliMUONRawCluster* rc = data->RawCluster(chamber, i);
629                         x = rc->GetX(0);
630                         y = rc->GetY(0);
631
632                         if (InFillRegion(x, y))
633                         {
634                                 AddPoint(x, y);
635
636                                 // Create a new block if we reached the maximum block size.
637                                 if ( ++currentblocksize == fMaxBlockSize )
638                                 {
639                                         AddBlock(chamber);
640                                         currentblocksize = 0;
641                                 }
642                         }
643                 }
644                 break;
645
646         default:
647                 Error("AddChamberFrom", "fDataToUse is not set to a valid value.");
648         }
649         
650         DebugMsg(1, "Leaving AddChamberFrom");
651 }
652
653
654 void ClusterSource::AddClusterFrom(
655                 AliMUONDataInterface* data, Int_t chamber, Int_t cluster
656         )
657 {
658         DebugMsg(1, "Entering AddClusterFrom");
659 #ifndef __alpha
660 #ifndef __sun   
661         Float_t x = nanf(""), y = nanf("");
662 #else
663         Float_t x = 0, y = 0;
664 #endif
665 #else
666         Float_t x = FLT_QNAN, y = FLT_QNAN;
667 #endif
668
669         switch (fDataToUse)
670         {
671         case FromHits:
672                 {
673                 Int_t i;
674                 // Note: cluster is now treated as the track number.
675                 for (i = 0; i < data->NumberOfHits(cluster); i++)
676                 {
677                         AliMUONHit* h = data->Hit(cluster, i);
678                         // Note AliMUONHit::Chamber() returns a value in the range 1..14
679                         if (h->Chamber() == chamber + 1)
680                         {
681                                 x = h->X();
682                                 y = h->Y();
683                                 break;
684                         }
685                 }
686
687                 if (i >= data->NumberOfHits(cluster))
688                 {
689                         // Could not find a hit on the specified chamber so just return.
690                         Warning("AddClusterFrom", "Could not find hit on chamber: %d , track: %d , event: %d", 
691                                 chamber, cluster, data->CurrentEvent()
692                         );
693                         DebugMsg(1, "Leaving AddClusterFrom");
694                         return;
695                 }
696                 }
697                 break;
698
699         case FromRawClusters:
700                 {
701                 AliMUONRawCluster* rc = data->RawCluster(chamber, cluster);
702                 x = rc->GetX(0);
703                 y = rc->GetY(0);
704                 }
705                 break;
706
707         default:
708                 Error("AddClusterFrom", "fDataToUse is not set to a valid value.");
709                 return;
710         }
711         
712         AddPoint(x, y);
713         
714         DebugMsg(1, "Leaving AddClusterFrom");
715 }
716
717
718 Bool_t ClusterSource::InFillRegion(Float_t x, Float_t /*y*/)
719 {
720         switch (fAreaToUse)
721         {
722         case FromWholePlane:     return kTRUE;
723         case FromLeftHalfPlane:  return x <= 0;
724         case FromRightHalfPlane: return x > 0;
725
726         default:
727                 Error("InFillRegion", "fAreaToUse is not set to a valid value.");
728                 return kFALSE;
729         }
730 }
731
732
733 void ClusterSource::ResetAllPointers() const
734 {
735         fEventIndex = -1;
736         fCurrentEvent = NULL;
737         fBlockIndex = -1;
738         fCurrentBlock = NULL;
739         fClusterIndex = -1;
740         fCurrentCluster = NULL;
741         DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
742                 << " , fClusterIndex = " << fClusterIndex
743         );
744 }
745
746
747 void ClusterSource::ResetBlockPointers() const
748 {
749         fBlockIndex = -1;
750         fCurrentBlock = NULL;
751         fClusterIndex = -1;
752         fCurrentCluster = NULL;
753         DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
754                 << " , fClusterIndex = " << fClusterIndex
755         );
756 }
757
758
759 void ClusterSource::ResetClusterPointers() const
760 {
761         fClusterIndex = -1;
762         fCurrentCluster = NULL;
763         DebugMsg(2, "\tfEventIndex = " << fEventIndex << " , fBlockIndex = " << fBlockIndex
764                 << " , fClusterIndex = " << fClusterIndex
765         );
766 }
767
768
769 ClusterSource::BlockData::BlockData() : fClusters(Point::Class())
770 {
771         fChamber = -1;
772 }
773
774 ClusterSource::BlockData::BlockData(Int_t chamber) : fClusters(Point::Class())
775 {
776         fChamber = chamber;
777 }
778
779 ClusterSource::BlockData::~BlockData()
780 {
781         fClusters.Clear("C");
782 }
783
784 ClusterSource::EventData::EventData() : fBlocks(ClusterSource::BlockData::Class())
785 {
786         fEventNumber = -1;
787 }
788
789 ClusterSource::EventData::EventData(Int_t eventnumber)
790         : fBlocks(ClusterSource::BlockData::Class())
791 {
792         fEventNumber = eventnumber;
793
794         // If the following is not set then we do not write the fBlocks properly.
795         fBlocks.BypassStreamer(kFALSE);
796 }
797
798 ClusterSource::EventData::~EventData()
799 {
800         fBlocks.Clear("C");
801 }
802
803
804 } // AliMUONHLT