86eb78733f8f3665237047fd776cc325a86c2902
[u/mrichter/AliRoot.git] / PHOS / PHOSrec / AliPHOSTRURawReader.cxx
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 /*
19  * Class for reading TRU data from a bunch from a raw datastream.
20  * Author: Henrik Qvigstad <henrik.qvigstad@cern.ch>
21  * Author: Jussi Viinikainen <jussi.viinikainen@cern.ch> (adaptation to Run2 format)
22  */
23
24 #include "AliPHOSTRURawReader.h"
25
26 #include "AliCaloRawStreamV3.h"
27
28 ClassImp(AliPHOSTRURawReader)
29
30
31 //________________________________________________________________
32 AliPHOSTRURawReader::AliPHOSTRURawReader()
33 : TObject(),
34 fSignals(),
35 fFlags(),
36 fFlags2x2(),
37 fActive(false),
38 fHasSignal(false),
39 fActiveTime(),
40 fHasSignalTime(),
41 fUse4x4Flags(false)
42 {
43   // default constructor
44   
45   // fSignals Initialization:
46   for(Int_t row = 0; row < fgkN2x2XPrTRURow; ++row) {
47     for(Int_t branch = 0; branch < fgkN2x2ZPrBranch; ++branch) {
48       for(Int_t timeBin = 0; timeBin < fgkNTimeBins; ++timeBin) {
49         fSignals[row][branch][timeBin] = fgkDefaultSignalValue;
50         fFlags2x2[row][branch][timeBin] = kFALSE;
51       }
52     }
53   }
54   
55   // fFlags Initialization
56   for(Int_t row = 0; row < fgkN4x4XPrTRURow; ++row){
57     for(Int_t branch = 0; branch < fgkN4x4ZPrBranch; ++branch){
58       for(Int_t timeBin = 0; timeBin < fgkNTimeBins; ++timeBin){
59         fFlags[row][branch][timeBin] = kFALSE;
60       }
61     }
62   }
63   
64   // fActiveTime Initialization
65   for(Int_t timeBin = 0; timeBin < fgkNTimeBins; ++timeBin){
66     fActiveTime[timeBin] = kFALSE;
67     fHasSignalTime[timeBin] = kFALSE;
68   }
69 }
70
71
72 //________________________________________________________________
73 AliPHOSTRURawReader::~AliPHOSTRURawReader()
74 {
75   // destructor
76 }
77
78 //________________________________________________________________
79 void AliPHOSTRURawReader::ReadFromStream(AliCaloRawStreamV3* rawStream)
80 {
81   // reads the trigger signal amplitudes and trigger flags from the rawStream
82   
83   const UShort_t * const signal = rawStream->GetSignals(); // stream of 10-bit words, buffered as 16-bit words
84   const Int_t signalLength = rawStream->GetBunchLength();  // The length of the signal in time steps
85   const Int_t channelIndex = rawStream->GetColumn();  // For some reason the index of the readout channel is given by GetColumn function
86   
87   fActive = kTRUE; // Set the TRU active
88   
89   /* Channels in TRU:
90    *
91    * There are 112 readout channels and 12 channels reserved for production flags
92    * The channels are indexed as follows:
93    *
94    *  Channels 0-111: channel data readout
95    *  Channels 112-123: production flags
96    */
97   
98   Int_t timeBin = rawStream->GetStartTimeBin(); // Find the time bin of the first time step
99   
100   if(channelIndex < fgkNReadoutChannels){  // Channel data
101     
102     /* Channel data:
103      *
104      * The channel data is read one channel at a time
105      * The x and z indices corresponding to the channel are calculated from the channel index
106      */
107     
108     fHasSignal = kTRUE;
109     const Int_t xBin = 7 - channelIndex % 8;  // x index in TRU internal 2x2 coordinate system
110     const Int_t zBin = 13 - channelIndex / 8; // z index in TRU internal 2x2 coordinate system
111     
112     // Loop over all the time steps in the signal
113     for(Int_t i = 0; i < signalLength; i++){
114       fSignals[xBin][zBin][timeBin] = signal[i];
115       fActiveTime[timeBin] = kTRUE;
116       fHasSignalTime[timeBin] = kTRUE;
117       timeBin--; // The time bins come in reverse order from raw data
118     }
119   } else { // Production flags
120
121     /* Production flags:
122      *
123      * Production flags are supplied in channels 112 - 123
124      * Each of the channels is 10 bit wide
125      * The bits inside the channel (indexing starting from the first bit of channel 112) is as follows:
126      *
127      *  Bits 0-111: Trigger flags for corresponding channel index
128      *              If using 4x4 algorithm, only 91 first bits are used of these
129      *  Bit 112: Marker for 4x4 algorithm (1 active, 0 not active)
130      *  Bit 113: Marker for 2x2 algorithm (1 active, 0 not active)
131      *  Bit 114: Global L0 OR of all patches in the TRU
132      */
133     
134     Int_t channel, xBin, zBin;
135     for(Int_t i = 0; i < signalLength; i++){
136       fActiveTime[timeBin] = kTRUE;
137       
138       // If bit 112 is 1, we are considering 4x4 algorithm
139       if(channelIndex == fgkFinalProductionChannel){
140         if( (signal[i] & ( 1 << 2 )) > 0 ){ // Check the bit number 112
141           fUse4x4Flags = kTRUE;
142         }
143       }
144       
145       // Assign the bits in the words to corresponding channels
146       for(Int_t bitIndex = 0; bitIndex < fgkWordLength; bitIndex++){
147         
148         /* Find the correct channel number assuming that
149          * channelIndex 112 = bits 0-9 corresponding trigger flags in channels 0-9
150          * channelIndex 113 = bits 10-19 corresponding trigger flags in channels 10-19
151          * and so on
152          */
153         channel = (channelIndex - fgkNReadoutChannels) * fgkWordLength + bitIndex;
154         
155         /*
156          * Note: flags corresponding to 2x2 sums and 4x4 sums need to be filled
157          *       in different loops since the internal xz coordinates are different
158          *       for 2x2 case and 4x4 case. We do not know which data we are filling
159          *       at the time we do the filling. This information comes only in the 
160           *      channel 123 in bit 112.
161          */
162         
163         if(channel < fgkNReadoutChannels){ // Fill histogram for 2x2 trigger flags
164           xBin = 7 - channel % 8;  // x index in TRU internal 2x2 coordinate system
165           zBin = 13 - channel / 8; // z index in TRU internal 2x2 coordinate system
166           
167           // check if the bit bitIndex is 1
168           if( (signal[i] & ( 1 << bitIndex )) > 0 ){
169             fFlags2x2[xBin][zBin][timeBin] = kTRUE;
170           }
171         }
172         
173         if(channel < fgkN4x4TriggerFlags){ // Fill histogram for 4x4 trigger flags
174           xBin = 6 - channel % 7;  // x index in TRU internal 4x4 coordinate system
175           zBin = 12 - channel / 7; // z index in TRU internal 4x4 coordinate system
176           
177           // check if the bit bitIndex is 1
178           if( (signal[i] & ( 1 << bitIndex )) > 0 ){
179             fFlags[xBin][zBin][timeBin] = kTRUE;
180           }
181         }
182       } // Bits in one word
183       timeBin--; // The time bins come in reverse order from raw data
184     } // Length of signal
185   } // Production flags
186   
187 }
188
189
190 //________________________________________________________________
191 void AliPHOSTRURawReader::Reset()
192 {
193   // Reset to default values
194   
195   if( ! fActive )
196     return;
197   
198   for(Int_t timeBin = 0; timeBin < fgkNTimeBins; ++timeBin) { // loop timeBins
199     if( fActiveTime[timeBin] ) {
200       for(Int_t xIdx = 0; xIdx < fgkN2x2XPrTRURow; ++xIdx) { // loop 2x2
201         for(Int_t zIdx = 0; zIdx < fgkN2x2ZPrBranch; ++zIdx) {
202           fSignals[xIdx][zIdx][timeBin] = fgkDefaultSignalValue;
203           fFlags2x2[xIdx][zIdx][timeBin] = kFALSE;
204         } // zIdx
205       } // xIdx
206       for(Int_t xIdx = 0; xIdx < fgkN4x4XPrTRURow; ++xIdx) { // loop 4x4
207         for(Int_t zIdx = 0; zIdx < fgkN4x4ZPrBranch; ++zIdx) {
208           fFlags[xIdx][zIdx][timeBin] = false;
209         } // zIdx
210       } // xIdx
211     }// end if fActiveTime
212     fActiveTime[timeBin] = false;
213     fHasSignalTime[timeBin] = false;
214   } // timeBin
215   
216   fActive = false;
217   fHasSignal = false;
218 }
219
220 //___________________________________________________________________
221 Bool_t AliPHOSTRURawReader::GetTriggerFlag(Int_t xIdx, Int_t zIdx, Int_t timeBin) const {
222   // Getter for trigger flags
223   if(fUse4x4Flags){
224     return fFlags[xIdx][zIdx][timeBin];
225   }
226   return fFlags2x2[xIdx][zIdx][timeBin];
227 }