BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
MucChain.cxx
Go to the documentation of this file.
1//------------------------------------------------------------------------------|
2// [File ]: MucChain.cxx |
3// [Brief ]: Source file of class MucChain for electronics mapping |
4// [Author]: Xie Yuguang, <ygxie@mail.ihep.ac.cn> |
5// [Date ]: Jun 7, 2006 |
6// [Log ]: See ChangLog |
7//------------------------------------------------------------------------------|
8
9#include <iostream>
10#include <vector>
11
12using namespace std;
13
15
16// Constructor
17MucChain ::MucChain( int id, std::string name, int module, int socket, int fecOrder ) {
18 // cout << "MucChain:: Create chain : " << endl;
19 // cout << "ID: " << id << "\tModule: " << module << "\tSocket: " << socket << "\tFecOrder: "
20 // << fecOrder << endl;
21 m_ID = id;
22 m_Name = name;
23 m_Module = module;
24 m_Socket = socket;
25 m_FecOrder = fecOrder;
26
27 Mapping();
28}
29
30// Destructor
31MucChain ::~MucChain() {
32 // cout << "MucChain:: Destructor()." <<endl;
33 delete[] m_FirstStripID;
34 delete[] m_FecLayerID;
35 delete[] m_StripOrder;
36
37 m_FecVect.clear();
38}
39
40//----------------------- Set properties methods for public---------------
41void MucChain ::ReMap( string name, int module, int socket ) {
42 m_Name = name;
43 m_Module = module;
44 m_Socket = socket;
45
46 MucChain::Mapping();
47}
48
49void MucChain ::SetFecOrder( int fecOrder ) {
50 m_FecOrder = fecOrder;
51 MucChain::InitFecVect();
52}
53
54// All FECs
55void MucChain ::SetStripOrder( int stripOrder ) {
56 // cout << "MucChain:: SetStripOrder( int )." << endl;
57 int order;
58 if ( stripOrder == 0 ) order = DEFAULT_STRIP_ORDER;
59 else order = stripOrder;
60
61 for ( int i = 0; i < m_FecTotal; i++ ) m_StripOrder[i] = order;
62}
63
64void MucChain ::SetStripOrder( int fecID, int stripOrder ) {
65 // Decode FecVect member number by fecID
66 int i = m_FecOrder * ( fecID - ( ( 1 - m_FecOrder ) / 2 ) * ( m_FecTotal - 1 ) );
67 m_FecVect[i].SetStripOrder( stripOrder );
68}
69
70void MucChain ::ArrayInvert( int* array, int number ) {
71 int temp;
72 for ( int i = 0; i < number / 2; i++ )
73 {
74 temp = array[i];
75 array[i] = array[number - 1 - i];
76 array[number - 1 - i] = temp;
77 }
78}
79
80//------------------------ set properties methods for private---------------
81void MucChain ::Mapping() {
82 InitPart();
83 InitSegment();
84 InitFecTotal();
85 InitFecPerLayer();
86 InitFecLayerID();
87 InitFirstStripID();
88 InitStripOrder();
89 InitFecVect();
90}
91
92void MucChain ::InitPart() {
93 // cout << "MucChain:: InitPart()." <<endl;
94 if ( m_Name[0] == 'B' ) m_Part = BRID;
95 else if ( m_Name[1] == 'E' ) m_Part = EEID;
96 else m_Part = WEID;
97}
98
99void MucChain ::InitSegment() {
100 // cout << "MucChain:: InitSegment()." <<endl;
101 if ( m_Part == BRID )
102 {
103 switch ( m_Name[2] )
104 {
105 case '1': m_Segment = 2; break;
106 case '2': m_Segment = 1; break;
107 case '3': m_Segment = 0; break;
108 case '4': m_Segment = 7; break;
109 case '5': m_Segment = 6; break;
110 case '6': m_Segment = 5; break;
111 case '7': m_Segment = 4; break;
112 case '8': m_Segment = 3; break;
113 default:;
114 }
115 }
116 else if ( m_Part == EEID )
117 {
118 switch ( m_Name[2] )
119 {
120 case '1': m_Segment = 0; break;
121 case '2': m_Segment = 3; break;
122 case '3': m_Segment = 2; break;
123 case '4': m_Segment = 1; break;
124 }
125 }
126 else
127 {
128 switch ( m_Name[2] )
129 {
130 case '1': m_Segment = 1; break;
131 case '2': m_Segment = 2; break;
132 case '3': m_Segment = 3; break;
133 case '4': m_Segment = 0; break;
134 }
135 }
136}
137
138void MucChain ::InitFecTotal() {
139 // cout << "MucChain:: InitFecTotal()." <<endl;
140 if ( m_Part == BRID ) // Barrel
141 {
142 if ( m_Name[1] == 'O' )
143 { // Odd layer chain
144 m_FecTotal = FEC_NUM - 1; // 15 FECs
145 }
146 else // Even layer chain
147 {
148 if ( m_Segment == BRTOP && m_Name[1] == 'E' )
149 { // Top segment
150 m_FecTotal = FEC_NUM; // 16 FECs
151 }
152 else
153 { // Not top segment
154 m_FecTotal = FEC_NUM - 4; // 12 FECs
155 }
156 }
157 }
158 else
159 { // Endcap
160 m_FecTotal = FEC_NUM; // 16 FECs
161 }
162}
163
164void MucChain ::InitFecPerLayer() {
165 // cout << "MucChain:: InitFecPerLayer()." <<endl;
166 if ( m_FecTotal != 0 )
167 {
168 if ( m_FecTotal == FEC_NUM ) m_FecPerLayer = 4;
169 else m_FecPerLayer = 3;
170 }
171 else m_FecPerLayer = 0;
172}
173
174void MucChain ::InitFecLayerID() {
175 // cout << "MucChain:: InitLayer()." <<endl;
176 // Init array
177 for ( int i = 0; i < FEC_NUM; i++ ) m_FecLayerID[i] = 0;
178
179 // Set FEC layer id according to default order
180 if ( m_Part == BRID ) // Barral chains
181 {
182 if ( m_Name[1] == 'O' ) // Odd layer chain, layer id: 0, 2, 4, 6, 8
183 {
184 for ( int i = 0; i < m_FecTotal; i++ ) { m_FecLayerID[i] = ( i / m_FecPerLayer ) * 2; }
185 }
186 else // Even layer chain, layer id: 1, 3, 5, 7
187 {
188 for ( int i = 0; i < m_FecTotal; i++ )
189 { m_FecLayerID[i] = ( i / m_FecPerLayer ) * 2 + 1; }
190 }
191 }
192 else // Endcap chains
193 {
194 if ( m_Name[3] == 'F' ) // First chain, layer id: 0, 1, 2, 3
195 {
196 for ( int i = 0; i < m_FecTotal; i++ ) { m_FecLayerID[i] = 3 - ( i / m_FecPerLayer ); }
197 }
198 else // Second chain, layer id: 4, 5, 6, 7
199 {
200 for ( int i = 0; i < m_FecTotal; i++ ) { m_FecLayerID[i] = 7 - ( i / m_FecPerLayer ); }
201 }
202 }
203
204 // If inverting order
205 if ( m_FecOrder == -1 ) MucChain::ArrayInvert( &m_FecLayerID[0], m_FecTotal );
206}
207
208void MucChain ::InitFirstStripID() {
209 // cout << "MucChain:: InitFirstStripID()." <<endl;
210 // Init array
211 for ( int i = 0; i < FEC_NUM; i++ ) m_FirstStripID[i] = 0;
212
213 // Set first strip ID according to default fecOrder
214 if ( m_Part == BRID ) // Barrel chains
215 {
216 if ( m_Name[1] == 'E' ) // East end, only even number layer chain, layer id: 1, 3, 5, 7
217 {
218 // Section number is defined by m_FecTotal/m_FecPerLayer
219 // Some sections of chain inverting default firstStripID sequence
220
221 if ( m_Segment == BRTOP )
222 { // BRTOP segment is exceptive, FirstStripID sequence is 64,96,80,48
223 for ( int i = 0; i < m_FecTotal; i++ )
224 m_FirstStripID[i] = FIRST_STRID_SQC_BETOP[i % m_FecPerLayer];
225 }
226 else switch ( m_Segment )
227 {
228 case 0:; // Segment 0, 1, 5, section 0, 2: (+), 1, 3: (-)
229 case 1:;
230 case 5:
231 for ( int i = 0; i < m_FecTotal; i++ )
232 m_FirstStripID[i] = FIRST_STRID_SQC_BEA[i % m_FecPerLayer];
233 break;
234 default: // Other segments
235 for ( int i = 0; i < m_FecTotal; i++ )
236 m_FirstStripID[i] = FIRST_STRID_SQC_BEB[i % m_FecPerLayer];
237 }
238 }
239 else if ( m_Name[1] == 'W' ) // West end, even number layer chain, layer id: 1, 3, 5, 7
240 {
241 switch ( m_Segment )
242 {
243 case 0:; // Segment 0, 1, 2, 5
244 case 1:;
245 case 2:;
246 case 5:
247 for ( int i = 0; i < m_FecTotal; i++ )
248 m_FirstStripID[i] = FIRST_STRID_SQC_BWA[i % m_FecPerLayer];
249 break;
250 default: // Other segments
251 for ( int i = 0; i < m_FecTotal; i++ )
252 m_FirstStripID[i] = FIRST_STRID_SQC_BWB[i % m_FecPerLayer];
253 }
254 }
255 else // West end, odd number layer chain, layer id: 0, 2, 4, 6
256 {
257 switch ( m_Segment )
258 {
259 case 0:; // Segment 0, 1, 2, 5
260 case 1:;
261 case 2:;
262 case 5:
263 for ( int i = 0; i < m_FecTotal; i++ )
264 m_FirstStripID[i] = FIRST_STRID_SQC_BWB[i % m_FecPerLayer];
265 break;
266 default: // Other segments
267 for ( int i = 0; i < m_FecTotal; i++ )
268 m_FirstStripID[i] = FIRST_STRID_SQC_BWA[i % m_FecPerLayer];
269 }
270 }
271
272 // for all chains in Barrel, section 0, 2, 4: (+), 1, 3: (-), inverting 1, 3;
273 for ( int j = 1; j < m_FecTotal / m_FecPerLayer; j += 2 )
274 MucChain::ArrayInvert( &m_FirstStripID[j * m_FecPerLayer], m_FecPerLayer );
275 } // End barrel chains
276 else
277 { // Endcap chains
278 // Set default firstStripID order(+), no inverting
279 for ( int i = 0; i < m_FecTotal; i++ )
280 m_FirstStripID[i] = FIRST_STRID_SQC_EC[i % m_FecPerLayer];
281 }
282
283 // If fecOrder inverting
284 if ( m_FecOrder == -1 ) MucChain::ArrayInvert( m_FirstStripID, m_FecTotal );
285}
286
287unsigned int MucChain ::EncodeVmeRecord( int module, int socket, int fecID,
288 unsigned short data ) {
289 // cout << "MucChain:: EncodeVmeRecord()." <<endl;
290 unsigned int record = ( ( module << MODULE_BIT ) | ( socket << SOCKET_BIT ) | fecID );
291 return ( ( record << LENGTH ) | data );
292}
293
294// All FECs
295void MucChain ::InitStripOrder() {
296 // cout << "MucChain:: InitStripOrder()." << endl;
297 for ( int i = 0; i < m_FecTotal; i++ )
298 {
299 if ( m_Part == BRID ) // Barrel
300 {
301 m_StripOrder[i] = -1;
302 /*
303 if( m_Name[1] == 'E' ) // East end, only even number layer chain, layer id: 1, 3, 5, 7
304 {
305 // Section number is defined by m_FecTotal/m_FecPerLayer
306 // Some sections of chain inverting default strip order
307
308 if(m_Segment==BRTOP) { //Strip order is +1, -1, +1, -1
309 for(int i=0; i<m_FecTotal; i++)
310 m_StripOrder[i] = STRORDER_BETOP[i%m_FecPerLayer ];
311 }
312 else switch(m_Segment)
313 {
314 case 0: ; // Segment 0, 1, 5, section 0, 2: (--+), 1, 3: (+--)
315 case 1: ;
316 case 5:
317 for(int i=0; i<m_FecTotal; i++)
318 m_StripOrder[i] = STRORDER_BEA[i%m_FecPerLayer ];
319 break;
320 default: // Other segments
321 for(int i=0; i<m_FecTotal; i++)
322 m_StripOrder[i] = STRORDER_BEB[i%m_FecPerLayer ];
323 }
324 }
325 else if( m_Name[1] == 'W' ) // West end, even number layer chain, layer id: 1, 3, 5, 7
326 {
327 switch(m_Segment)
328 {
329 case 0: ; // Segment 0, 1, 2, 5, --+
330 case 1: ;
331 case 2: ;
332 case 5:
333 for(int i=0; i<m_FecTotal; i++)
334 m_StripOrder[i] = STRORDER_BEA[i%m_FecPerLayer ];
335 break;
336 default : // Other segments, +--
337 for(int i=0; i<m_FecTotal; i++)
338 m_StripOrder[i] = STRORDER_BEB[i%m_FecPerLayer ];
339 }
340 }
341 else { // West end, odd number layer chain, layer id: 0, 2, 4, 6
342 for(int i=0; i<m_FecTotal; i++)
343 m_StripOrder[i] = STRORDER_BWO[ i%m_FecPerLayer ];
344 }
345
346 // for all chains in Barrel, section 0, 2, 4: (+), 1, 3: (-), inverting 1, 3;
347 for(int j=1; j<m_FecTotal/m_FecPerLayer; j+=2)
348 MucChain::ArrayInvert( &m_StripOrder[j*m_FecPerLayer], m_FecPerLayer );
349 */
350 } // End Barrel
351 else if ( ( m_Part == EEID && ( m_Segment == 0 || m_Segment == 2 ) ) ||
352 ( m_Part == WEID && ( m_Segment == 1 || m_Segment == 3 ) ) )
353 m_StripOrder[i] = STRORDER_ECA[m_FecLayerID[i]];
354 else m_StripOrder[i] = STRORDER_ECB[m_FecLayerID[i]];
355
356 } // End FecTotal
357}
358
359void MucChain ::InitFecVect() {
360 // cout << "MucChain:: InitFecVect()." << endl;
361
362 unsigned short data = 0;
363 int part = m_Part;
364 int segment = m_Segment;
365
366 int id;
367 int layer;
368 int firstStripID;
369 int stripOrder;
370 string chainName;
371 unsigned int vmeRecord;
372
373 for ( int i = 0; i < m_FecTotal; i++ )
374 {
375 // Encode FEC id by FecVect member number
376 id = ( ( 1 - m_FecOrder ) / 2 ) * ( m_FecTotal - 1 ) + ( m_FecOrder * i );
377
378 layer = m_FecLayerID[id];
379 firstStripID = m_FirstStripID[id];
380 stripOrder = m_StripOrder[id];
381 chainName = MucChain::m_Name;
382 vmeRecord = EncodeVmeRecord( m_Module, m_Socket, id, data );
383 // cout << "FEC:\t" << id << "\t" << (vmeRecord>>LENGTH) << endl;
384
385 MucFec aFec( id, stripOrder, part, segment, layer, firstStripID, vmeRecord, chainName );
386 m_FecVect.push_back( aFec );
387 }
388}
389
390// END
TTree * data
const int STRORDER_ECA[E_LAY_NUM]
Definition MucChain.h:38
const int STRORDER_ECB[E_LAY_NUM]
Definition MucChain.h:41
const int FIRST_STRID_SQC_BEA[3]
Definition MucChain.h:28
const int FIRST_STRID_SQC_BEB[3]
Definition MucChain.h:30
const int FIRST_STRID_SQC_BWA[3]
Definition MucChain.h:32
const int FIRST_STRID_SQC_BWB[3]
Definition MucChain.h:35
const int FIRST_STRID_SQC_EC[4]
Definition MucChain.h:25
const int FIRST_STRID_SQC_BETOP[4]
Definition MucChain.h:26
void ArrayInvert(int *array, int number)
Definition MucChain.cxx:70