ATLAS Offline Software
Loading...
Searching...
No Matches
Trigger/TrigT1/TrigT1RPChardware/src/Matrix.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <array>
8#include <cmath>
9#include <fstream>
10#include <iostream>
11
13
14using namespace std;
15
16//----------------------------------------------------------------------------//
17// number of thresholds
18const ubit16 Matrix::s_nthres = 3;
19// number of channels in side=0 and side=1;
20const ubit16 Matrix::s_nchan[2] = {32, 64};
21// Bunch Crossing period, ns
22const float Matrix::s_BCtime = 25.0;
23// Number of DLL cycles
25// DLL period, ns
26const float Matrix::s_DLLtime = s_BCtime / (float)s_NDLLCYC;
27// ReadOut offset in DLL steps
29// number of channel in a group for the timing setting
32// number of bits for a CMAword word
33const sbit16 Matrix::s_wordlen = 32;
34//----------------------------------------------------------------------------//
35namespace {
42 constexpr std::array<ubit16, 2> inds(ubit16 channel) {
43 // static cast back to ubit16 because arithmetic operators implicitly cast to int (don't accept smaller types)
44 return {static_cast<ubit16>(channel / Matrix::s_wordlen), static_cast<ubit16>(channel % Matrix::s_wordlen)};
45 }
46 constexpr ubit16 bitstatus(const CMAword *p, ubit16 channel) {
47 CMAword j{1};
48 std::array<ubit16, 2> id = inds(channel);
49 return *(p + id[0]) & j << id[1] ? 1 : 0;
50 }
51} // namespace
52//----------------------------------------------------------------------------//
53Matrix::Matrix(int run, int event, CMAword debug, int subsys, int proj, int sect, int padadd, int lowhig, int add[2], int locadd, int NOBXS, int BCZERO) :
54 BaseObject(Hardware, "Matrix") {
55 ubit16 df = 0; // debug flag address
56 m_run = run;
57 m_event = event;
58 //
59 // debug flags first
60 //
62
63 if (m_matrixDebug & 1 << df) {
64 cout << "=============================================" << endl
65 << "Constructor of Matrix called with parameters:" << endl
66 << subsys << " " << proj << " " << sect << " " << lowhig << " " << add[0] << add[1] << endl
67 << "=============================================" << endl;
68 }
69 m_thisBC = 0; // temporary initialization
70
71 m_BCzero = BCZERO;
72 m_Nbunch = NOBXS;
74 // m_BCzero=(m_nclock/s_NDLLCYC)/2; // default initialization of m_BCzero
75 // user setting by setBCzero
76
77 //
78 //
79 // BCzero
80 // |
81 // |
82 // |
83 // V
84 // BCID=-2 BCID=-1 .BCID= 0 BCID=+1 BCID=+2
85 // .
86 // .
87 // ********+********+********+********+********
88 // 01234567 01234567 01234567 01234567 01234567
89 //
90 //
91 // Matrix attributes
92 //
93 m_subsystem = subsys;
94 m_projection = proj;
95 m_sector = sect;
96 m_pad = padadd;
97 m_lowhigh = lowhig;
98 //
99 m_address[0] = add[0];
100 m_address[1] = add[1];
101 m_localadd = locadd;
102 //
103 // initialize some variables
104 //
105 initDat();
106 //
107 // initialize the RPC data structure
108 //
110 //
111 // initialize the CMAword registers
112 //
114 //
115 // initialize the Configuration pointers
116 //
117 initPointers();
118 //
119 // set default CM parameters configuration
120 //
122}
123//-----------------------------------------------------------------------//
125 ubit16 df = 1;
127 if (m_matrixDebug & 1 << df) { cout << "Distructor of Matrix executed " << endl; }
128} // end-of-Matrix::~Matrix()
129//-----------------------------------------------------------------------//
131 ubit16 i;
132 // ubit16 df=1;
133 rpcdata *rpcpnt, *rpcpntnext;
134 //
135 // delete the dynamic memory allocated by the Matrix object
136 //
137 for (i = 0; i < 2; i++) {
138 rpcpnt = m_datarpc[i];
139 while (rpcpnt) {
140 rpcpntnext = rpcpnt->next;
141 delete rpcpnt;
142 rpcpnt = rpcpntnext;
143 } // end-of-while(rpcpnt)
144 } // end-of-for(i
145 // if(rpcpnt) delete rpcpnt;
146 //
147 // set DEFAULT parameters for the Coincidence Matrix
148 //
150 //
151} // end-of-Matrix::deleteRPCdata
152//-----------------------------------------------------------------------//
154 //
155 // initialize some variables
156 //
157 initDat();
158 //
159 // delete dynamic memory used for RPC data
160 //
162 //
163 // initialize the CMAword registers
164 //
166 //
167} // end-of-Matrix::reset
168//-----------------------------------------------------------------------//
170
171 // helper to set arrays to zero (only use with integer arrays!)
172 auto zero = [](auto& arr) { memset( arr, 0, sizeof(arr) ); };
173 zero( rodat );
174 zero( m_input );
175 zero( m_prepr );
176 zero( m_mjori );
177 zero( m_trigger );
178 zero( m_trigg );
180 zero( overlapRO );
181 zero( highestthRO );
182 zero( m_k_pattern );
183 zero( k_readout );
185 zero( m_highestth );
186 zero( m_overlap );
187} // end-of-Matrix::initRegisters
188//-----------------------------------------------------------------------//
190 //
191 // initialize the rpcdata structure
192 //
193 for (ubit16 i = 0; i < 2; i++) { m_datarpc[i] = 0; } // end-of-for(i
194} // end-of-Matrix::initRPCpointers
195//-----------------------------------------------------------------------//
197 //
198 // initialize the Configuration pointers
199 //
200 m_chdly = 0; // pointer to channel delays
201 m_width = 0; // pointer to pulse widths
202 m_locDi = 0; // pointer to local Coincidence Direction
203 m_kRead = 0; // pointer to threshold pattern for readout
204 m_roads = 0; // pointer to the road Matrix settings
205 m_major = 0; // pointer to the majority
206 m_overl = 0; // pointer to the overlapping channel list
207 m_geome = 0; // pointer to "geometry"
208} // end-of-Matrix::initPointers
209//-----------------------------------------------------------------------//
211 // put the current BC at the center of the buffer
212 m_BCID = -1;
213} // end-of-Matrix::initDat
214//-----------------------------------------------------------------------//
216 ubit16 df = 0; // debug flag address as for constructor
217 ubit16 i, j, k, l;
218 //
219 // set DEFAULT parameters for the Coincidence Matrix
220 //
221 //
222
223 //
224 // Coincidence Windows for the the three thresholds
225 //
226 for (i = 0; i < s_nthres; i++) {
227 for (j = 0; j < s_nchan[0]; j++) {
228 m_trigRoad[i][j][0] = 0x00000000;
229 m_trigRoad[i][j][1] = 0x00000000;
230 } // end-of-for(j
231 } // end-of-for(i
232 //
233 // Majority setting
234 //
235 m_majorities[0] = 2; // majority values for threshold address 0
236 m_majorities[1] = 2; // majority values for threshold address 1
237 m_majorities[2] = 2; // majority values for threshold address 2
238 //
239 // threshold to be used for coincidence of the lowpt trigger with the
240 // external RPC doublet
241 //
242 m_lowtohigh = s_nthres - 1;
243 //
244 // threshold to be used to provide the trigger data in the readout;
245 // important for the correct functioning of the LVL2 (muFast)
246 //
247 m_toreadout = 0; // threshold of the pattern to be sent to the readout
248 //
249 // address of the threshold to be considered in overlap (dimuon counting)
250 //
251 m_overlapthres = 0;
252 //
253 // address of the configuration for the local coincidence
254 //
255 m_localDirec[0] = 7; // majority Direction
256 m_localDirec[1] = 7; // majority Direction
257 //
258 // default for m_matOverlap
259 //
260 for (i = 0; i < 2; i++) { m_matOverlap[i] = 0; }
261 //
262 // default for the signal delay, deadtime and pulse width arrays
263 //
264 for (i = 0; i < 2; i++) { // side
265 for (j = 0; j < 2; j++) { // layer
266 for (k = 0; k < (s_nchan[1] / s_timeGroupB); k++) { // group
267 m_pulseWidth[i][j][k] = 8;
268 } // end-of-for(k
269 for (k = 0; k < (s_nchan[1] / s_timeGroupA); k++) { // group
270 m_channDelay[i][j][k] = 0;
271 } // end-of-for(k
272 for (k = 0; k < (s_nchan[1] / s_timeGroupB); k++) { // group
273 m_channDeadT[i][j][k] = 0;
274 } // end-of-for(k
275 } // end-of-for(j
276 } // end-of-for(i
277 //
278 // Masking to 0 and masking to 1
279 //
280 for (i = 0; i < 2; i++) { // side
281 for (j = 0; j < 2; j++) { // layer (or "1/2"=0, "2/2"=1 in case of m_channMask1)
282 for (k = 0; k < s_nchan[1]; k++) { m_channMask0[i][j][k] = 0; } // end-of-for(k
283 for (l = 0; l < s_nthres; l++) {
284 m_channMask1[l][i][j][0] = 0;
285 m_channMask1[l][i][j][1] = 0;
286 } // end-of-for(l=0
287 m_channReadOutMask[i][j][0] = 0;
288 m_channReadOutMask[i][j][1] = 0;
289 } // end-of-for(j
290 } // end-of-for(i
291 //
292 // default for trigger dead time
293 //
294 for (k = 0; k < (s_nchan[0] / s_timeGroupB); k++) { // group
295 m_trigDeadTime[k] = 8;
296 } // end-of-for(
297 //
298 // initialize m_BunchPhase and m_BunchOffset
299 //
300 m_BunchPhase = 0; // use this setting for standard ATLAS simulation;
301 // m_BunchPhase=-1; // use this setting with comparison with the HARDWARE;
302 // value fixed with VHDL comparison 1-7 august 2004.
303 // use with setBCzero(0);
304 m_BunchOffset = 0; // test with hardware; use with setBCzero(0);
305 //
306 // default for m_diagonal
307 //
308 for (i = 0; i < s_nchan[0]; i++) { m_diagonal[i] = 0; }
309
310 if (m_matrixDebug & 1 << df) {
311 cout << "====================================================================" << endl
312 << "Matrix::setDefaultConfiguration: "
313 << "Default settings have been loaded." << std::endl
314 << "===================================================================" << endl;
316 }
317} // end-of-Matrix::setDefaultConfiguration
318//-----------------------------------------------------------------------//
320 ubit16 i, j, k;
321 //
322 // Coincidence Windows for the the three thresholds
323 //
324 cout << "=================================" << std::endl
325 << "Matrix::dispDefaultConfiguration:" << std::endl
326 << "=================================" << std::endl;
327 cout << "--------------------------------" << std::endl << "+ Coincidence Windows: " << std::endl;
328 for (i = 0; i < s_nthres; i++) {
329 cout << " + Threshold address:" << i << std::endl;
330 for (j = 0; j < s_nchan[0]; j++) {
331 cout << " -Channel address:" << j << " Window 63-32 " << std::hex << m_trigRoad[i][j][1] << " Window 31-00 "
332 << m_trigRoad[i][j][0] << std::dec << std::endl;
333 } // end-of-for(j
334 } // end-of-for(i
335 //
336 // Majority setting
337 //
338 cout << "--------------------------------" << std::endl
339 << "+ Majority addresses: " << std::endl
340 << "--------------------------------" << std::endl;
341 for (i = 0; i < s_nthres; i++) { cout << " - threshold address " << i << " value " << m_majorities[i] << std::endl; }
342 //
343 // threshold to be used for coincidence of the lowpt trigger with the
344 // external RPC doublet
345 //
346 cout << "--------------------------------" << std::endl
347 << "+ Threshold address low-to-high: " << m_lowtohigh << std::endl
348 << "+ Threshold address low-to-readout: " << m_toreadout << std::endl
349 << "+ Threshold address for overlap: " << m_overlapthres << std::endl;
350 //
351 // address of the configuration for the local coincidence
352 //
353 cout << "--------------------------------" << std::endl
354 << "+ Local coincidence setting: " << std::endl
355 << " -Pivot Plane: " << m_localDirec[0] << std::endl
356 << " -Coincidence Plane: " << m_localDirec[1] << std::endl;
357 //
358 // Overlap default masking
359 //
360 cout << "--------------------------------" << std::endl
361 << "+ Overlap mask setting: " << std::endl
362 << " -`right' address " << m_matOverlap[0] << std::endl
363 << " -`left ' address " << m_matOverlap[1] << std::endl;
364 //
365 // default for the signal delay, deadtime and pulse width arrays
366 //
367 cout << "-----------------------------------------------" << std::endl
368 << "+ Channel pulse-width, delay and deadtime : " << std::endl;
369 for (i = 0; i < 2; i++) { // side
370 if (!i) {
371 cout << " +Pivot Plane " << std::endl;
372 } else {
373 cout << " +Coincidence Plane " << std::endl;
374 }
375 for (j = 0; j < 2; j++) { // layer
376 cout << " +Layer " << j << std::endl;
377 for (k = 0; k < (s_nchan[i] / s_timeGroupB); k++) { // group
378 cout << " -group " << k << " pulsewidth " << m_pulseWidth[i][j][k] << std::endl;
379 } // end-of-for(k
380 for (k = 0; k < (s_nchan[i] / s_timeGroupA); k++) { // group
381 cout << " -group " << k << " delay " << m_channDelay[i][j][k] << std::endl;
382 } // end-of-for(k
383 for (k = 0; k < (s_nchan[i] / s_timeGroupB); k++) { // group
384 cout << " -group " << k << " deadtime " << m_channDeadT[i][j][k] << std::endl;
385 } // end-of-for(k
386 } // end-of-for(j
387 } // end-of-for(i
388 //
389 // Masking to 0
390 //
391 cout << "-----------------------------------------------" << std::endl << "+ Map of the masked-to-0 channels : " << std::endl;
392 for (i = 0; i < 2; i++) { // side
393 if (!i) {
394 cout << " +Pivot Plane " << std::endl;
395 } else {
396 cout << " +Coincidence Plane " << std::endl;
397 }
398 for (j = 0; j < 2; j++) { // layer
399 cout << " +Layer " << j << std::endl;
400 for (k = 0; k < s_nchan[1]; k++) {
401 if (m_channMask0[i][j][k]) { cout << " -channel " << k << std::endl; } // end-of-if
402 } // end-of-for(k
403 } // end-of-for(j
404 } // end-of-for(i
405 //
406 // default for trigger dead time
407 //
408 cout << "-----------------------------------------------" << std::endl << "+ Trigger Dead Time " << std::endl;
409 for (k = 0; k < (s_nchan[0] / s_timeGroupB); k++) { // group
410 cout << " -group " << k << " Trigger DeadTime " << m_trigDeadTime[k] << std::endl;
411 } // end-of-for(
412 //
413 // Simulation relevant parameters (used to align with the hardware)
414 //
415 cout << "-----------------------------------------------" << std::endl
416 << "+ Simulation parameters to align with the hardware (not used in CM)" << std::endl;
417 //
418 // m_BunchPhase and m_BunchOffset
419 //
420 cout << "+BunchPhase " << m_BunchPhase << std::endl
421 << " BunchPhase = 0 : to be used for standard ATLAS LVL1 simulation" << std::endl
422 << " BunchPhase = -1 : to be used to compare with the hardware; " << std::endl
423 << " this value fixed with VHDL comparison 1-7 august 2004." << std::endl
424 << "+BunchOffset " << m_BunchOffset << std::endl
425 << " BunchOffset = 0 : to test with hardware; use this setting with setBCzero(0)." << std::endl;
426 //
427 // the end
428 //
429 cout << "======================================" << std::endl
430 << "Matrix::dispDefaultConfiguration: Done" << std::endl
431 << "======================================" << std::endl;
432} // end-of-Matrix::dispDefaultConfiguration
433//-----------------------------------------------------------------------//
434void Matrix::putData(int sidemat, int layer, int stripaddress, float time) {
435 //
436 sbit16 BCID; // BC time bin (from 0)
437 ubit16 DLLID; // DLL time bin (from 0)
438 ubit16 df = 2; // debug flag address
439 rpcdata *rpcpntnew;
440 if (m_matrixDebug & 1 << df) { cout << "Matrix:putData: putting data on Matrix" << endl; }
441 //
442 BCID = (int)(time / s_BCtime);
443 if (time < 0.0) BCID--; // to cope with negative times
444 //
445 // the next line determines the DLL clock bin associated
446 // to the given time. For historical reasons, a +1 offset has
447 // been used so far:
448 // DLLID= (int)((time-(float)BCID*s_BCtime)/s_DLLtime)+1;
449 // It should be now removed. Aleandro, 11 November 2008.
450 //
451 DLLID = (int)((time - (float)BCID * s_BCtime) / s_DLLtime);
452 if (DLLID == s_NDLLCYC) {
453 BCID++;
454 DLLID = 0;
455 } // end-of-if(DLLID
456 //
457 // put this digi in the dynamic store
458 //
459 // coverity change
460 // rpcpntnew = new rpcdata;
461 //
462 // check the stripaddress is consistent with the Matrix dimension
463 //
464 if (BCID >= m_Nbunch) return;
465
466 if (stripaddress >= 0 && stripaddress < s_nchan[sidemat]) {
467 // coverity change
468 rpcpntnew = new rpcdata;
469
470 rpcpntnew->layer = layer;
471 rpcpntnew->stripadd = stripaddress;
472 rpcpntnew->time = time;
473 rpcpntnew->BC = BCID;
474 rpcpntnew->DLL = DLLID;
475 rpcpntnew->masked = 0;
476 rpcpntnew->maskto1 = 0;
477 rpcpntnew->deadtime = 0;
478 rpcpntnew->delay = 0;
479 rpcpntnew->mark = 0;
480 rpcpntnew->next = m_datarpc[sidemat];
481 //
482 // put this element as first in the queue
483 //
484 m_datarpc[sidemat] = rpcpntnew;
485
486 } else {
487 throw std::out_of_range("Matrix::putData failure: channel addressed is " + std::to_string(stripaddress) + " for matrix side " +
488 std::to_string(sidemat));
489 } // end-of-if
490} // end-of-putData
491//----------------------------------------------------------------------//
492void Matrix::putPatt(const Matrix *p) {
493 //
494 // input: p pointer of the low-pt Matrix belonging to the
495 // high-pt one
496 //
497 CMAword k;
498 ubit16 i, j;
499 ubit16 df = 3; // debug flag address
500 if (m_matrixDebug & 1 << df) { cout << " method putPatt called; p is " << p << endl; }
501 //
502 //
503 // for(i=0; i<2; i++) { // loop on the two majorities
504 // for(j=0; j<m_nclock; j++) { // loop on the clock bins
505 // for(k=0; k<2; k++) { // loop on buffer words
506 // for(n=0; n<s_nthres; n++) { // loop on the "s_nthres" registers
507 // m_mjori[n][0][i][j][k] = p->m_k_pattern[j];
508 // }//end-of-for(n
509 // }//end-of-for(k
510 // }//end-of-for(j
511 // }//end-of-for(i
512 //
513 //
514 float time = 0.0;
515 k = 1;
516
517 // cout<<" RITARDI-1 "<<endl;
518 // for(int iside=0;iside<=1;iside++){
519 // for(int ilayer=0;ilayer<=1;ilayer++){
520 // for(ubit16 k=0; k<(s_nchan[iside]/s_timeGroupA); k++) {
521 // cout<<" side="<<iside<<" layer="<<ilayer<<" group="<<k
522 // <<" delay="<<m_channDelay[iside][ilayer][k]<<endl;
523 // }
524 // }
525 // }//end-of-for(ubit16 k
526
527 for (i = 0; i < s_nchan[0]; i++) {
528 for (j = 0; j < m_nclock; j++) {
529 if (p->m_k_pattern[j] & k) {
530 time = ((float)j + 0.5) * s_DLLtime + (float)m_thisBC * s_BCtime - (float)(m_BCzero)*s_BCtime;
531 putData(0, 0, i, time);
532 } // end-of-if(p->m_k_pattern
533 } // end-of-for(j
534 k = k << 1;
535 } // end-of-for(i
536 //
537 if (m_matrixDebug & 1 << df) { cout << " copy_pivot; input matrix address " << p << endl; } // end-of-if(m_matrixDebug&1<<df)
538} // end-of-method putPatt
539//----------------------------------------------------------------------//
540void Matrix::setRunEvent(int runNum, int eventNum) {
541 m_run = runNum;
542 m_event = eventNum;
543} // end-of-Matrix::setRunEvent
544//----------------------------------------------------------------------//
546 //
547 // set the BunchCrossing=0 to the "offset" array address in memory
548 //
549 if (offset <= m_Nbunch - 1)
550 m_BCzero = offset;
551 else
552 m_BCzero = m_Nbunch - 1;
553} // end-of-setBCzero
554//----------------------------------------------------------------------//
556 for (ubit16 iside = 0; iside < 2; iside++) {
557 for (ubit16 ilayer = 0; ilayer < 2; ilayer++) {
558 for (ubit16 k = 0; k < (s_nchan[iside] / s_timeGroupB); k++) { setDeadTime(iside, ilayer, k, deadt); } // end-of-for(ubit16 k
559 } // end-of-for(ubit16 ilayer
560 } // end-of-for(ubit16 iside
561} // end-of-setDeadTime
562//----------------------------------------------------------------------//
563void Matrix::setDeadTime(ubit16 iside, ubit16 ilayer, ubit16 deadt) {
564 for (ubit16 k = 0; k < (s_nchan[iside] / s_timeGroupB); k++) { setDeadTime(iside, ilayer, k, deadt); } // end-of-for(ubit16 k
565} // end-of-setDeadTime
566//----------------------------------------------------------------------//
567void Matrix::setDeadTime(ubit16 iside, ubit16 ilayer, ubit16 igroup, ubit16 deadt) {
568 if (iside < 2 && ilayer < 2 && igroup < (s_nchan[1] / s_timeGroupB)) {
569 m_channDeadT[iside][ilayer][igroup] = deadt;
570 if (iside == 0 && igroup > 3) {
571 throw std::out_of_range(
572 "Matrix::setDeadTime: problems with side and group addresses: "
573 "side=" +
574 std::to_string(iside) + " layer=" + std::to_string(ilayer) + " group=" + std::to_string(igroup));
575 } // end-of-if
576 } else {
577 throw std::out_of_range(
578 "Matrix::setDeadTime: problems in adressing pulseWidth: "
579 "side=" +
580 std::to_string(iside) + " layer=" + std::to_string(ilayer) + " group=" + std::to_string(igroup));
581 } // end-of-if
582} // end-of-setDeadTime
583//----------------------------------------------------------------------//
585 if (iside > 1 || ilayer > 1) {
586 throw std::out_of_range(
587 "Matrix::setDelay: problems with side and layer addresses: "
588 "side=" +
589 std::to_string(iside) + " layer=" + std::to_string(ilayer));
590 } else {
591 for (ubit16 k = 0; k < (s_nchan[iside] / s_timeGroupA); k++) { setDelay(iside, ilayer, k, delay); } // end-of-for(ubit16 k
592 }
593} // end-of-setDelay
594//----------------------------------------------------------------------//
595void Matrix::setDelay(ubit16 iside, ubit16 ilayer, ubit16 igroup, ubit16 delay) {
596 if (iside < 2 && ilayer < 2 && igroup < (s_nchan[1] / s_timeGroupA)) {
597 m_channDelay[iside][ilayer][igroup] = delay;
598 if (iside == 0 && igroup > 3) {
599 throw std::out_of_range(
600 "Matrix::setDelay: problems with side and group addresses:"
601 "side=" +
602 std::to_string(iside) + " layer=" + std::to_string(ilayer) + " group=" + std::to_string(igroup));
603 } // end-of-if
604 } else {
605 throw std::out_of_range(
606 "Matrix::setDelay: problems in adressing pulseWidth:"
607 "side=" +
608 std::to_string(iside) + " layer=" + std::to_string(ilayer) + " group=" + std::to_string(igroup));
609 } // end-of-if
610} // end-of-setDelay
611//----------------------------------------------------------------------//
613 for (ubit16 iside = 0; iside < 2; iside++) {
614 for (ubit16 ilayer = 0; ilayer < 2; ilayer++) {
615 for (ubit16 k = 0; k < (s_nchan[iside] / s_timeGroupB); k++) { setPulseWidth(iside, ilayer, k, length); } // end-of-for(ubit16
616 // k
617 } // end-of-for(ubit16 ilayer
618 } // end-of-for(ubit16 iside
619} // end-of-setPulseWidth
620//----------------------------------------------------------------------//
622 for (ubit16 k = 0; k < (s_nchan[iside] / s_timeGroupB); k++) { setPulseWidth(iside, ilayer, k, length); } // end-of-for(ubit16 k
623} // end-of-setPulseWidth
624//----------------------------------------------------------------------//
626 if (iside < 2 && ilayer < 2 && igroup < s_nchan[1] / s_timeGroupB) {
627 m_pulseWidth[iside][ilayer][igroup] = length;
628 if (iside == 0 && igroup > 3) {
629 throw std::out_of_range(
630 "Matrix::setDelay: problems with side and group addresses:"
631 "side=" +
632 std::to_string(iside) + " layer=" + std::to_string(ilayer) + " group=" + std::to_string(igroup));
633 } // end-of-if
634 } else {
635 throw std::out_of_range(
636 "Matrix::setDelay: problems in adressing pulseWidth:"
637 "side=" +
638 std::to_string(iside) + " layer=" + std::to_string(ilayer) + " group=" + std::to_string(igroup));
639 } // end-of-if
640} // end-of-setPulseWidth
641//----------------------------------------------------------------------//
642void Matrix::setMask0(ubit16 iside, ubit16 ilayer, ubit16 ichannel) {
643 if (iside > 1 || ilayer > 1 || ichannel > (s_nchan[iside] - 1)) {
644 throw std::out_of_range(
645 "Matrix::setMask0: problems with side/layer/channel addresses: "
646 "side=" +
647 std::to_string(iside) + " layer=" + std::to_string(ilayer) + " channel=" + std::to_string(ichannel));
648 } else {
649 m_channMask0[iside][ilayer][ichannel] = 1;
650 }
651} // end-of-setMask0
652//----------------------------------------------------------------------//
653void Matrix::setMask1(ubit16 ithreshold, ubit16 iside, ubit16 imajority, ubit16 ichannel) {
654 if (ithreshold > 2 || iside > 1 || imajority > 1 || ichannel > (s_nchan[iside] - 1)) {
655 throw std::out_of_range(
656 "Matrix::setMask1: problems with side/layer/channel addresses: "
657 "threshold= " +
658 std::to_string(ithreshold) + " side=" + std::to_string(iside) + " majority=" + std::to_string(imajority) +
659 " channel=" + std::to_string(ichannel));
660 } else {
661 set_to_1(&m_channMask1[ithreshold][iside][imajority][0], ichannel);
662 }
663} // end-of-setMask1
664//----------------------------------------------------------------------//
665void Matrix::setMask1(ubit16 ithreshold, ubit16 iside, ubit16 imajority) {
666 for (int ichannel = 0; ichannel < s_nchan[iside]; ichannel++) { setMask1(ithreshold, iside, imajority, ichannel); }
667} // end-of-setMask1
668//----------------------------------------------------------------------//
669void Matrix::setMask1(ubit16 ithreshold, ubit16 iside) {
670 for (int imajority = 0; imajority < 2; imajority++) { setMask1(ithreshold, iside, imajority); }
671} // end-of-setMask1
672//----------------------------------------------------------------------//
673void Matrix::setMaskReadOut(ubit16 iside, ubit16 ilayer, ubit16 ichannel) {
674 if (iside > 1 || ilayer > 1 || ichannel > (s_nchan[iside] - 1)) {
675 throw std::out_of_range(
676 "Matrix::setMaskReadout: problems with side/layer/channel addresses: "
677 "side=" +
678 std::to_string(iside) + " layer=" + std::to_string(ilayer) + " channel=" + std::to_string(ichannel));
679 } else {
680 set_to_1(&m_channReadOutMask[iside][ilayer][0], ichannel);
681 }
682} // end-of-setMaskReadOut
683//----------------------------------------------------------------------//
684void Matrix::setMaskReadOut(ubit16 iside, ubit16 ilayer, ubit16 ichannel, ubit16 nchannels) {
685 for (ubit16 i = ichannel; i < (ichannel + nchannels - 1); i++) { setMaskReadOut(iside, ilayer, ichannel, i); }
686} // end-of-setMaskReadOut
687//----------------------------------------------------------------------//
688void Matrix::setConfig(int *l, ubit16 *p, int *k, CMAword *r, int *m, CMAword *o, sbit32 *g) {
689 //
690 // input: l pointer to local coincidence direction
691 // p pointer to pulse width
692 // k pointer to threshold for k-readout pattern
693 // r pointer to the three Matrix roads;
694 // m pointer to the three majorities;
695 // o pointer to the overlapping channel list;
696 // g pointer to "geometry"
697 //
698 ubit16 i, j, jg;
699 ubit16 addGroupMax = 0;
700 // ubit16 df=4; // debug flag address
702 m_locDi = l; // local coincidence direction //
703 m_width = p; // pulse width //
704 m_chdly = 0; // delay //
705 m_kRead = k; // k-readout address //
706 m_roads = r; // programmed coincidence window address //
707 m_major = m; // programmed majority address //
708 m_overl = o; // programmed overlap flag address //
709 m_geome = g; // pre-calculated geometry //
711 for (i = 0; i < 2; i++) { setLocalDirection(i, *(m_locDi + i)); }
712 // set Pulse Widths
713 for (i = 0; i < 2; i++) { // side
714 addGroupMax = s_nchan[0] / s_timeGroupB;
715 if (i) addGroupMax = s_nchan[1] / s_timeGroupB;
716 for (j = 0; j < 2; j++) { // layer
717 for (jg = 0; jg < addGroupMax; jg++) { // group
718 // setPulseWidth(i,j,jg,*(m_width+jg+8*j+16*i));
719 // setDelay (i,j,jg,*(m_chdly+jg+8*j+16*i));
720 } // end-of-for(jg
721 } // end-of-for(j
722 } // end-of-for(i
723 // set address of threshold to be readout
725 // set majority levels
726 for (i = 0; i < s_nthres; i++) { setMajority(i, *(m_major + i)); }
727 // set coincidence roads for the s_nthres thresholds
728 for (i = 0; i < s_nthres; i++) {
729 for (j = 0; j < s_nchan[0]; j++) {
730 setRoad(i, j, 0, *(m_roads + s_nchan[0] * 2 * i + 2 * j + 0));
731 setRoad(i, j, 1, *(m_roads + s_nchan[0] * 2 * i + 2 * j + 1));
732 } // end-of-for(j
733 } // end-of-for(i
734 // set the overlap registers
735 for (i = 0; i < 2; i++) { setMatOverlap(i, *(m_overl + i)); }
736 for (i = 0; i < s_nchan[0]; i++) { setDiagonal(i, *(m_geome + i)); }
737} // end-of-Matrix::setConfig
738//----------------------------------------------------------------------//
740 if (add > 1) {
741 throw std::out_of_range("Matrix::setLocalDirection : add=" + std::to_string(add) + " not valid");
742 } else {
743 m_localDirec[add] = content;
744 } // end-of-if;
745} // end-of-Matrix::setLocalDirection
746//----------------------------------------------------------------------//
747void Matrix::setKReadOut(int content) {
748 if (content < 0 || content >> 2) {
749 throw std::out_of_range("Matrix::setKReadout : threshold address = " + std::to_string(content) + " not valid");
750 } else {
751 m_toreadout = content;
752 } // end-of-if
753} // end-of-Matrix::setKReadOut
754//----------------------------------------------------------------------//
755void Matrix::setOverlaThres(int content) {
756 if (content >= 0 && content < s_nthres) {
757 m_overlapthres = content;
758 } else {
759 m_overlapthres = 0;
760 }
761} // end-of-setOverlapThres
762//----------------------------------------------------------------------//
764 if (igroup < 4) {
765 m_trigDeadTime[igroup] = deadt;
766 } else {
767 throw std::out_of_range("Matrix::setTrigDeadTime : igroup= " + std::to_string(igroup) + " not valid");
768 }
769} // end-of-setTrigDeadTime
770//----------------------------------------------------------------------//
772 for (ubit16 k = 0; k < (s_nchan[0] / s_timeGroupB); k++) { setTrigDeadTime(k, deadt); } // end-of-for(ubit16 k
773} // end-of-setTrigDeadTime
774//----------------------------------------------------------------------//
775void Matrix::setMajority(ubit16 add, int content) {
776 if (add >= s_nthres) {
777 throw std::out_of_range("Matrix::setMajority : add=" + std::to_string(add) + " not valid");
778 } else {
779 m_majorities[add] = content;
780 } // end-of-if
781} // end-of-Matrix::setMajority
782//----------------------------------------------------------------------//
783void Matrix::setRoad(ubit16 addThres, ubit16 addChn, ubit16 add64, CMAword content) {
784 if (addThres >= s_nthres || addChn > s_nchan[0] || add64 > 1) {
785 throw std::out_of_range("Matrix::setRoad : addThres= " + std::to_string(addThres) + " addChn= " + std::to_string(addChn) +
786 " add64= " + std::to_string(add64) + " not valid");
787 } else {
788 m_trigRoad[addThres][addChn][add64] = content;
789 } // end-of-if
790} // end-of-Matrix::setRoad
791//----------------------------------------------------------------------//
792void Matrix::setRoad(ubit16 addThres, ubit16 addChn, char road[17]) {
793 if (addThres >= s_nthres || addChn > s_nchan[0]) {
794 throw std::out_of_range("Matrix::setRoad : addThres= " + std::to_string(addThres) + " addChn= " + std::to_string(addChn));
795 } else {
796 CMAword the32[2] = {0, 0};
797 ubit16 outflag = char2int(road, the32);
798 if (outflag) {
799 throw std::runtime_error("Matrix::setRoad; outflag from char2int is positive: " + std::to_string(outflag));
800 m_trigRoad[addThres][addChn][0] = 0;
801 m_trigRoad[addThres][addChn][1] = 0;
802 } else {
803 m_trigRoad[addThres][addChn][0] = the32[0];
804 m_trigRoad[addThres][addChn][1] = the32[1];
805 }
806 } // end-of-if
807} // end-of-Matrix::setRoad
808//----------------------------------------------------------------------//
810 if (add > 1) {
811 throw std::out_of_range("Matrix::setMatOverlap : add= " + std::to_string(add) + " not valid");
812 } else {
813 m_matOverlap[add] = content;
814 }
815} // end-of-Matrix::setMatOverlap
816//----------------------------------------------------------------------//
818 if (add > s_nchan[0]) {
819 throw std::out_of_range("Matrix::setDiagonal : add= " + std::to_string(add) + " not valid");
820 } else {
821 m_diagonal[add] = content;
822 } // end-of-if
823} // end-of-Matrix::setDiagonal
824//----------------------------------------------------------------------//
826 CMAword output = 0;
827 if (add > 1) {
828 throw std::out_of_range("Matrix::getMatOverlap : add= " + std::to_string(add) + " not valid");
829 } else {
830 output = m_matOverlap[add];
831 }
832 return output;
833} // end-of-Matrix::getMatOverlap
834//----------------------------------------------------------------------//
835CMAword Matrix::getRoad(ubit16 addThres, ubit16 addChn, ubit16 add64) const {
836 CMAword output = 0;
837 if (addThres >= s_nthres || addChn > s_nchan[0] || add64 > 1) {
838 throw std::out_of_range("Matrix::getRoad : addThres= " + std::to_string(addThres) + " addChn= " + std::to_string(addChn) +
839 " add64= " + std::to_string(add64) + " not valid");
840 } else {
841 output = m_trigRoad[addThres][addChn][add64];
842 } // end-of-if
843 return output;
844} // end-of-Matrix::getRoad
845//----------------------------------------------------------------------//
847 int output = 0;
848 if (add >= s_nthres) {
849 throw std::out_of_range("Matrix::getMajority : add= " + std::to_string(add) + " not valid");
850 } else {
851 output = m_majorities[add];
852 } // end-of-if
853 return output;
854} // end-of-Matrix::getMajority
855//----------------------------------------------------------------------//
857 // returns coincidence flag: 0 if there is no trigger for all thresholds
858 // 1 if there is at least one threshold with trigger
859 // 2 if the lowtohigh threshold (or higher) is m_trigg
860 //
861 // execute this active CM
862 //
863 ubit16 df = 4; // debug flag address
864 if (m_matrixDebug & 1 << df) {
865 cout << "====================" << endl
866 << "| |" << endl
867 << "| Matrix::execute |" << endl
868 << "| --------------- |" << endl
869 << "| |" << endl
870 << "====================" << endl;
872 } // end-of-if(m_matrixDebug&1<<df)
873 //
874 // 0) programmed windows (s_nthres) and time calibration constants for this
875 // matrix
876 if (m_matrixDebug & 1 << df) wind();
877 // 1) store deadtime in dyn. structure; deadtime is applied by "applyDeadTime"
879 // 2) masking;
880 masking();
881 // 3) delay
882 delay();
883 // 5) fill the CMA
884 load();
885 // 6) apply deadtime response to Input signals
886 deadTime();
888 // 7) preprocessing
889 prepro();
890 // 8) coincidence;
891 coincide();
892 //
893 makeOut();
894
895 // Code to be activated for testing the VHDL simulation.
896 // makeOutPattern ();
897 //
898} // end-of-method execute;
899//----------------------------------------------------------------------//
901 ubit16 df = 5;
902 rpcdata *rpchit;
903 if (m_matrixDebug & 1 << df) {
904 cout << "--------------------------" << endl << "| Matrix::storeDeadtime |" << endl << "--------------------------" << endl;
905 } // end-of-if(m_matrixDebug&1<<df)
906 for (ubit16 i = 0; i < 2; i++) {
907 rpchit = m_datarpc[i];
908 while (rpchit) {
909 rpchit->deadtime = m_channDeadT[i][rpchit->layer][rpchit->stripadd / s_timeGroupB];
910 rpchit = rpchit->next;
911 } // end-of-while(rpchit
912 } // end-of-for(ubit16 i
913} // end-of-Matrix::storeDeadtime
914//----------------------------------------------------------------------//
916 ubit16 df = 6;
917 rpcdata *rpchit;
918 if (m_matrixDebug & 1 << df) {
919 cout << "--------------------" << endl << "| Matrix::masking |" << endl << "--------------------" << endl;
920 } // end-of-if(m_matrixDebug&1<<df)
921 for (ubit16 i = 0; i < 2; i++) {
922 rpchit = m_datarpc[i];
923 while (rpchit) {
924 rpchit->masked = m_channMask0[i][rpchit->layer][rpchit->stripadd];
925 rpchit = rpchit->next;
926 } // end-of-while(rpchit
927 } // end-of-for(ubit16 i
928} // end-of-Matrix::masking
929//----------------------------------------------------------------------//
931 ubit16 df = 7;
932 rpcdata *rpchit;
933 if (m_matrixDebug & 1 << df) {
934 cout << "--------------------" << endl << "| Matrix::delay |" << endl << "--------------------" << endl;
935 } // end-of-if(m_matrixDebug&1<<df)
936 for (ubit16 i = 0; i < 2; i++) {
937 rpchit = m_datarpc[i];
938 while (rpchit) {
939 rpchit->delay = m_channDelay[i][rpchit->layer][rpchit->stripadd / s_timeGroupA];
940 rpchit = rpchit->next;
941 } // end-of-while(rpchit
942 } // end-of-for(ubit16 i
943} // end-of-Matrix::delay
944//----------------------------------------------------------------------//
946 ubit16 df = 8;
947 sbit32 abs_time, timeadd;
948 rpcdata *rpcpnt;
949 //
950 if (m_matrixDebug & 1 << df) {
951 cout << "--------------------" << endl << "| Matrix::load |" << endl << "--------------------" << endl;
952 } // end-of-if(m_matrixDebug&1<<df)
953 //
954 for (ubit16 i = 0; i < 2; i++) { // "i" is the CMA side address
955 rpcpnt = m_datarpc[i];
956 while (rpcpnt) {
957 if (m_matrixDebug & 1 << df) {
958 cout << " Layer= " << rpcpnt->layer << " stripadd= " << rpcpnt->stripadd << " time= " << rpcpnt->time
959 << " mask= " << rpcpnt->masked << " BC= " << rpcpnt->BC << " DLL= " << rpcpnt->DLL << " delay= " << rpcpnt->delay
960 << endl;
961 } // end-of-if(m_matrixDebug&1<<df)
962 abs_time = s_NDLLCYC * rpcpnt->BC + rpcpnt->DLL + rpcpnt->delay;
963
964 timeadd = abs_time - s_NDLLCYC * m_thisBC // synchronize the data to m_thisBC
965 + s_NDLLCYC * m_BCzero; // put m_thisBC at the center of the buffer
966
967 if (m_matrixDebug & 1 << df) { cout << " abs_time= " << abs_time << " timeadd= " << timeadd << endl; }
968
969 //
970 // store this digit if it is within time window and not masked
971 //
972 if (timeadd >= 0 && timeadd < m_nclock && !rpcpnt->masked) {
973 if (m_matrixDebug & 1 << df) {
974 cout << " setting input with side " << i << " " << rpcpnt->layer << " " << timeadd << " 0"
975 << " for channel " << rpcpnt->stripadd << " timeadd " << timeadd << endl;
976 } // end-of-if(m_matrixDebug&1<<df)
977 set_to_1(&m_input[i][rpcpnt->layer][timeadd][0], rpcpnt->stripadd);
978 } // end-of-if(timeadd
979 //
980 rpcpnt = rpcpnt->next;
981 //
982 } // end-of-while(rpcpnt)
983 } // end-of-for(i
984} // end-of-Matrix::load()
985//------------------------------------------------------------------------//
987 //
988 // copy input to rodat
989 //
990 for (ubit16 i = 0; i < 2; i++) { // side address
991 for (ubit16 j = 0; j < 2; j++) { // layer address
992 for (ubit16 k = 0; k < m_nclock; k++) { // clock bins
993 for (ubit16 l = 0; l < 2; l++) { // the two words to make 64 bits
994 rodat[i][j][k][l] = m_input[i][j][k][l] & ~m_channReadOutMask[i][j][l];
995 } // end-of-for(l
996 } // end-of-for(k
997 } // end-of-for(j
998 } // end-of-for(i
999} // end-of-copyDataToReadOut
1000//------------------------------------------------------------------------//
1002 ubit16 df = 9;
1003 if (m_matrixDebug & 1 << df) {
1004 cout << "-------------------------" << endl << "| matrix: preprocessing |" << endl << "-------------------------" << endl;
1005 } // end-of-if(m_matrixDebug&1<<df)
1006 //
1007 // 1) pulse width
1008 pulse_width();
1009 // 2) declustering
1010 declus();
1011 // 3) majority
1012 majori();
1013 // 4) mask to 1
1014 maskTo1();
1015} // end-of-method prepro
1016//------------------------------------------------------------------------//
1018 //
1019 // input none
1020 //
1021 // returns trigger flag
1022 //
1023 //
1024 sbit16 BCaddress = 0;
1025 //
1026 ubit16 df = 10;
1027 ubit16 i, j, l, m;
1028 ubit16 thres, chan, nconf, conf[4][2];
1029 for (i = 0; i < 4; i++) {
1030 for (j = 0; j < 2; j++) { conf[i][j] = 0; }
1031 }
1032 //
1033 if (m_matrixDebug & 1 << df) {
1034 cout << "--------------------" << endl << "| matrix: coincide |" << endl << "--------------------" << endl;
1035 } // end-of-if(m_matrixDebug&1<<df)
1036 //
1037 // nconf gives the number of possible configurations compatible with
1038 // the required majority;
1039 // conf[i][j] gives the two indices "j" for the side-x (pivot) and side-y
1040 // array respectively correspondent to the configurtion number "i"
1041 //
1042 if (m_matrixDebug & 1 << df) {
1043 cout << " Matrix::coincidence; lowhigh= " << m_lowhigh << endl
1044 << " Matrix::coincidence; majority array ="
1045 << " " << m_majorities[0] << " " << m_majorities[1] << " " << m_majorities[2] << endl;
1046 } // end-of-if(m_matrixDebug&1<<df)
1047 //
1048 for (i = 0; i < m_nclock; i++) { // loop on clock cycles
1049 for (thres = 0; thres < s_nthres; thres++) { // loop on the three possible thresholds
1050 // thresholds address increases with
1051 // increasing pT
1052 nconf = config(thres, &conf[0][0]); // number of config. for this threshold
1053 //
1054 // if(m_matrixDebug&1<<df) {
1055 // cout<<"nconf="<<nconf<<" conf="<<endl;
1056 // for(int ii=0;ii<4;ii++){ cout<<" "<<conf[ii][0]<<endl;}
1057 // cout<<endl;
1058 // for(int ii=0;ii<4;ii++){ cout<<" "<<conf[ii][1]<<endl;}
1059 // cout<<endl;
1060 //}//end-of-if(m_matrixDebug&1<<df)
1061
1062 for (l = 0; l < nconf; l++) { // loop on all config. for this threshold
1063 for (j = 0; j < s_nchan[0]; j++) { // loop on all side-x channels
1064 //
1065 // coincidence evaluation:
1066 // for the given configuration "l" and the given channel "j" in the
1067 // pivot plane, the coincidence requires
1068 // a) the required majority "m_mjori[thres][0][conf[l][0]][i][0]"
1069 // for channel "j"
1070 // b) the required majority "m_mjori[thres][1][conf[l][0]][i][0,1]"
1071 // in coincidence with the programmed road in "*(m_roads+2*j)" and
1072 // "*(m_roads+2*j+1)
1073 //
1074 // if( bitstatus(&m_mjori[thres][0][conf[l][0]][i][0],j)
1075 // *( m_mjori[thres][1][conf[l][1]][i][0]&(*(m_roads+32*2*thres+2*j+0))
1076 // | m_mjori[thres][1][conf[l][1]][i][1]&(*(m_roads+32*2*thres+2*j+1)))){
1077
1078 if (bitstatus(&m_mjori[thres][0][conf[l][0]][i][0], j) &&
1079 ((m_mjori[thres][1][conf[l][1]][i][0] & m_trigRoad[thres][j][0]) |
1080 (m_mjori[thres][1][conf[l][1]][i][1] & m_trigRoad[thres][j][1]))) {
1081 if (m_matrixDebug & 1 << df) {
1082 cout << "coincidence!!!"
1083 << " clock=" << i << " xchan=" << j << endl;
1084 } // end-of-if(m_matrixDebug
1085
1086 set_to_1(&m_trigg[thres][i], j);
1087 BCaddress = ((i + m_BunchPhase) / s_NDLLCYC) + m_BunchOffset;
1088 if (BCaddress >= 0 && BCaddress < m_Nbunch)
1089 m_trigger[thres][BCaddress] = 1; // set "m_trigger" to 1 for this threshold...
1090 // ...and this Bunch Crossing
1091
1092 } // end-of-if(bitstatus...
1093 } // end-of-for(j
1094 } // end-of-for(l
1095 //
1096 // for(m=0;m<2;m++) { // loop on left-right sides to evaluate overlap
1097 // if(!m_triggerOverlapRO[i][m])
1098 // m_triggerOverlapRO[i][m] = (m_trigg[thres][i] & m_matOverlap[m]);
1099 // if(!m_triggerOverlap[i/s_NDLLCYC][m])
1100 // m_triggerOverlap[i/s_NDLLCYC][m] = (m_trigg[thres][i] & m_matOverlap[m]);
1101 // }//end-of-for(m
1102 } // end-of-for(thres
1103 } // end-of-for(i
1104
1105 if (CMAVERSION == 2004) {
1106 //
1107 // build the rise pulse for "m_trigg" (320 MHz trigger output) signals
1108 //
1109 CMAword previousTime = 0;
1110 for (chan = 0; chan < s_nchan[0]; chan++) {
1111 for (thres = 0; thres < s_nthres; thres++) { // loop on the three possible thresholds
1112 for (i = m_nclock - 1; i > 0; i--) { // loop on clock cycles
1113 previousTime = bitstatus(&m_trigg[thres][i - 1], chan);
1114 if (bitstatus(&m_trigg[thres][i], chan) && previousTime) { set_to_0(&m_trigg[thres][i], chan); } // end-of-if(bitstatus
1115 } // end-of-for(i
1116 } // end-of-for(thres
1117 } // end-of-for(chan
1118 } // end-of-if(CMAVERSION
1119 // - - - - - - - - - - -
1120
1121 for (chan = 0; chan < s_nchan[0]; chan++) {
1122 for (thres = 0; thres < s_nthres; thres++) { // loop on the three possible thresholds
1123 for (i = m_nclock - 1; i > 0; i--) { // loop on clock cycles
1124 if (bitstatus(&m_trigg[thres][i], chan)) {
1125 for (ubit16 idead = 1; idead < m_trigDeadTime[chan / s_timeGroupB]; idead++) {
1126 set_to_0(&m_trigg[thres][i + idead], chan);
1127 } // end-of-for(
1128 } // end-of-bitstatus
1129 } // end-of-for(i
1130 } // end-of-for(thres
1131 } // end-of-for(chan
1132
1133 if (CMAVERSION == 2004) {
1134 //
1135 // ...now determine the correspondent "m_trigger" (40 MHz trigger output)
1136 //
1137 for (thres = 0; thres < s_nthres; thres++) { // loop on the three possible thresholds
1138 // reset trigger
1139 for (j = 0; j < m_Nbunch; j++) { m_trigger[thres][j] = 0; } // end-of-for(j
1140 // compute new "m_trigger"
1141 for (i = 0; i < m_nclock; i++) { // loop on clock cycles
1142 BCaddress = ((i + m_BunchPhase) / s_NDLLCYC) + m_BunchOffset;
1143 if (BCaddress >= 0 && BCaddress < m_Nbunch) {
1144 if (m_trigg[thres][i]) m_trigger[thres][BCaddress] = 1;
1145 } // emd-of-if(BCadd
1146 } // end-of-for(i
1147 } // end-of-for(thres
1148 } // end-of-if(CMAVERSION
1149 // - - - - - - - - - - -
1150 //
1151 // find triggers in overlap regions
1152 //
1153 // for(thres=0; thres<s_nthres; thres++){ // loop on the three possible thresholds
1154 thres = m_overlapthres;
1155 for (i = 0; i < m_nclock; i++) { // loop on clock cycles
1156 if (m_trigg[thres][i]) {
1157 for (m = 0; m < 2; m++) { // loop on left-right sides to evaluate overlap
1158 if (!m_triggerOverlapRO[i][m]) { m_triggerOverlapRO[i][m] = (m_trigg[thres][i] & m_matOverlap[m]); }
1159 BCaddress = ((i + m_BunchPhase) / s_NDLLCYC) + m_BunchOffset;
1160 if (BCaddress >= 0 && BCaddress < m_Nbunch) {
1161 if (!m_triggerOverlap[BCaddress][m]) m_triggerOverlap[BCaddress][m] = (m_trigg[thres][i] & m_matOverlap[m]);
1162 } // end-of-if(BCaddress
1163 } // end-of-for(m
1164
1165 } // end-of-for(m_trigg
1166 } // end-of-for(i
1167 //}//end-of-for(thres
1168 //
1169 // normalize m_triggerOverlapRO
1170 //
1171 for (i = 0; i < m_nclock; i++) { // loop on clock cycles
1172 for (m = 0; m < 2; m++) { // normalize to 1 overlap flags
1173 m_triggerOverlapRO[i][m] = m_triggerOverlapRO[i][m] ? 1 : 0;
1174 } // end-of-for(m
1175 } // end-of-for(i
1176 //
1177 // normalize m_triggerOverlap
1178 //
1179 for (i = 0; i < m_Nbunch; i++) { // loop on bunches
1180 for (m = 0; m < 2; m++) { // normalize to 1 overlap flags
1181 m_triggerOverlap[i][m] = m_triggerOverlap[i][m] ? 1 : 0;
1182 } // end-of-for(m
1183 } // end-of-for(i
1184} // end-of-Matrix::coincide
1185//------------------------------------------------------------------------//
1187 ubit16 df = 11;
1188 if (m_matrixDebug & 1 << df) {
1189 cout << "---------------------" << endl << "| Matrix::mask_to_1 |" << endl << "---------------------" << endl;
1190 } // end-of-if(m_matrixDebug&1<<df)
1191
1192 ubit16 i, j, k, l, m;
1193 for (m = 0; m < s_nthres; m++) { // thresholds
1194 for (i = 0; i < 2; i++) { // side address
1195 for (j = 0; j < 2; j++) { // majority address
1196 for (l = 0; l < s_nchan[i]; l++) { // channel
1197 if (bitstatus(&m_channMask1[m][i][j][0], l)) {
1198 for (k = 0; k < m_nclock; k++) { // clock bins
1199 set_to_1(&m_mjori[m][i][j][k][0], l);
1200 } // end-of-for(k
1201 } // end-of-if(m_channMask1
1202 } // end-of-for(l
1203 } // end-of-for(j
1204 } // end-of-for(i
1205 } // end-of-for(m
1206
1207} // end-of-Matrix::mask_to_1
1208//------------------------------------------------------------------------//
1210 ubit16 i, j, k, l;
1212 //
1213 for (i = 0; i < 2; i++) { // loop on both matrix sides
1214 for (j = 0; j < 2; j++) { // loop on both trigger layers
1215 for (k = 0; k < s_nchan[i]; k++) { // loop on all channels
1216 //
1217 // set to 1 the bins in "temp" where signals are "on" for the first time
1218 //
1219 for (l = 0; l < (m_nclock - 1); l++) { // loop on clock bins
1220 ((!bitstatus(&m_input[i][j][l][0], k)) && bitstatus(&m_input[i][j][l + 1][0], k)) ? temp[l + 1] = 1 : temp[l + 1] = 0;
1221 } // end-of-for(l
1222 temp[0] = bitstatus(&m_input[i][j][0][0], k);
1223 //
1224 // transfer to "input" the signals in "temp" far enough each other in time
1225 //
1226 sbit16 lastUp = -1;
1227 for (l = 0; l < m_nclock; l++) { // loop on clock bins
1228 //
1229 if (!temp[l]) {
1230 set_to_0(&m_input[i][j][l][0], k);
1231 } else {
1232 //
1233 if ((lastUp < 0) || (l - lastUp) >= m_channDeadT[i][j][k / s_timeGroupB]) {
1234 lastUp = l;
1235 set_to_1(&m_input[i][j][l][0], k);
1236 } else {
1237 set_to_0(&m_input[i][j][l][0], k);
1238 } // end-of-if
1239 } // end-of-if
1240 //
1241 } // end-of-for(l
1242 } // end-of-for(k
1243 } // end-of-for(j
1244 } // end-of-for(i
1245} // end-of-Matrix::deadTime
1246//------------------------------------------------------------------------//
1248 ubit16 df = 12;
1249 ubit16 i, j, l, m;
1250 sbit16 k;
1251 if (m_matrixDebug & 1 << df) {
1252 cout << "-----------------------" << endl << "| Matrix::pulse_width |" << endl << "-----------------------" << endl;
1253 } // end-of-if(m_matrixDebug&1<<df)
1254 //
1255 for (i = 0; i < 2; i++) { // loop on the two Matrix sides
1256 for (j = 0; j < 2; j++) { // loop on both layers
1257 for (l = 0; l < s_nchan[i]; l++) { // loop on all channels
1258 for (k = m_nclock - 1; k >= 0; k--) { // loop on the m_nclock cycles backwards
1259 if (bitstatus(&m_input[i][j][k][0], l)) {
1260 // loop on all time bins to be set to 1
1261 for (m = k + 1; m < k + m_pulseWidth[i][j][l / s_timeGroupB]; m++) {
1262 if (m < m_nclock) {
1263 set_to_1(&m_input[i][j][m][0], l);
1264 } else {
1265 break;
1266 } // end-of-if(m
1267 } // end-of-for(m
1268 } // end-of-if(bitstatus
1269 } // end-of-for(k
1270 } // end-of-for(l
1271 } // end-of-for(j
1272 } // end-of-for(i
1273 //
1274} // end-of-Matrix::pulse_width
1275//------------------------------------------------------------------------//
1277 //
1278 // input none
1279 // returns nothing
1280 //
1281 // Fills the majority registers the 1/2 and 2/2 majority logic
1282 //
1283 // Dynamic scanning of "on" channels has not to be done
1284 // in this first part of the method
1285 //
1286 ubit16 i, j, k, l, n;
1287 ubit16 df = 13; // debug flag address
1288 CMAword buffi[2], buffo[2];
1289 if (m_matrixDebug & 1 << df) {
1290 cout << "-------------------" << endl << "| Matrix::majori |" << endl << "-------------------" << endl;
1291 } // end-of-if(m_matrixDebug&1<<df)
1292 //
1293 // the loop on the CMA sides has to be made as follows:
1294 // 1) side=0 and side=1 as long as the lowpt Matrix is concerned;
1295 // 2) side=1 only as long as the highpt Matrix is concerned.
1296 // To do this, loop from lowhigh address.
1297 //
1298 for (n = 0; n < s_nthres; n++) { // the s_nthres thresholds
1299 for (i = 0; i < 2; i++) { // the two Matrix sides
1300 for (j = 0; j < m_nclock; j++) { // the clock cycles
1301 for (k = 0; k < 2; k++) { // the two words to make 64 bits
1302 // copy layer with address 0,1 to buffi; initialize buffoutput
1303 buffi[k] = m_prepr[n][i][1][j][k];
1304 buffo[k] = 0;
1305 }
1306 shift(&buffi[0], &buffo[0], i);
1307 for (k = 0; k < 2; k++) { // the two words
1308 // 1/2 majority
1309 m_mjori[n][i][0][j][k] = m_prepr[n][i][0][j][k] | m_prepr[n][i][1][j][k];
1310 // 2/2 majority
1311 m_mjori[n][i][1][j][k] = m_prepr[n][i][0][j][k] & buffo[k];
1312 } // end-of-for(k
1313 //
1314 // complete preprocessing...
1315 //
1316 for (l = 0; l < s_nchan[i]; l++) { // loop in the number of channel for this side
1317 if (bitstatus(&m_mjori[n][i][1][j][0], l)) {
1318 if ((l > 0) && (!bitstatus(&m_mjori[n][i][1][j][0], l - 1))) set_to_0(&m_mjori[n][i][0][j][0], l - 1);
1319 if ((l < s_nchan[i] - 1) && (!bitstatus(&m_mjori[n][i][1][j][0], l + 1))) set_to_0(&m_mjori[n][i][0][j][0], l + 1);
1320 } // end-of-if(
1321 } // end-of-for(l
1322 // preprocessing completed
1323 } // end-of-for(j
1324 } // end-of-for(i
1325 } // end-of-for(n
1326} // end-of-method majori
1327//------------------------------------------------------------------------//
1328void Matrix::shift(CMAword *buffi, CMAword *buffo, ubit16 i) const {
1329 //
1330 ubit16 k;
1331 switch (m_localDirec[i]) {
1332 case 1: // n(layer0)-->n(layer1)
1333 for (k = 0; k < 2; k++) { *(buffo + k) = *(buffi + k); }
1334 break;
1335 case 2: // n(0)-->n-1(1)
1336 for (k = 0; k < 2; k++) { *(buffo + k) = *(buffi + k) << 1; }
1337 *(buffo + 1) = (*(buffi + 0) & 0x80000000) ? (*(buffo + 1) | 0x1) : (*(buffo + 1) | 0);
1338 break;
1339 case 3: // case 2 plus case 1
1340 for (k = 0; k < 2; k++) { *(buffo + k) = *(buffi + k) | (*(buffi + k) << 1); }
1341 *(buffo + 1) = (*(buffi + 0) & 0x80000000) ? (*(buffo + 1) | 0x1) : (*(buffo + 1) | 0);
1342 break;
1343 case 4: // n(0)-->n+1(1)
1344 for (k = 0; k < 2; k++) { *(buffo + k) = *(buffi + k) >> 1; }
1345 *(buffo + 0) = (*(buffi + 1) & 0x1) ? (*(buffo + 0) | 0x80000000) : (*(buffo + 0) | 0);
1346 break;
1347 case 5: // case 4 plus case 1
1348 for (k = 0; k < 2; k++) { *(buffo + k) = *(buffi + k) | (*(buffi + k) >> 1); }
1349 *(buffo + 0) = (*(buffi + 1) & 0x1) ? (*(buffo + 0) | 0x80000000) : (*(buffo + 0) | 0);
1350 break;
1351 case 6: // case 4 plus case 2
1352 for (k = 0; k < 2; k++) { *(buffo + k) = (*(buffi + k) >> 1) | (*(buffi + k) << 1); }
1353 *(buffo + 0) = (*(buffi + 1) & 0x1) ? (*(buffo + 0) | 0x80000000) : (*(buffo + 0) | 0);
1354 *(buffo + 1) = (*(buffi + 0) & 0x80000000) ? (*(buffo + 1) | 0x1) : (*(buffo + 1) | 0);
1355 break;
1356 case 7: // case 4 plus case 2 pluse case 1
1357 for (k = 0; k < 2; k++) { *(buffo + k) = *(buffi + k) | (*(buffi + k) >> 1) | (*(buffi + k) << 1); }
1358 *(buffo + 0) = (*(buffi + 1) & 0x1) ? (*(buffo + 0) | 0x80000000) : (*(buffo + 0) | 0);
1359 *(buffo + 1) = (*(buffi + 0) & 0x80000000) ? (*(buffo + 1) | 0x1) : (*(buffo + 1) | 0);
1360 break;
1361 default:
1362 cout << " Matrix::shift -- m_localDirec[" << i << "]=" << m_localDirec[i] << " not expected; m_localDirec forced to be 1 "
1363 << endl;
1364 for (k = 0; k < 2; k++) { *(buffo + k) = *(buffi + k); }
1365 }
1366 //
1367 // correct patter in *(buffo+1) in case side of Matrix (="i" in this method)
1368 // is = 1
1369 //
1370 if (!i) *(buffo + 1) = 0;
1371 //
1372} // end-of-Matrix::shift(buff0, buffi, buffo)
1373//------------------------------------------------------------------------//
1375 //
1376 // Dynamic scanning of "on" channels has not to be done
1377 // in this first part of the method
1378 //
1379 ubit16 df = 14;
1380 ubit16 nup, first, i, j, k, l;
1381 first = 0;
1382 if (m_matrixDebug & 1 << df) {
1383 cout << "------------------------" << endl << "| matrix: declustering |" << endl << "------------------------" << endl;
1384 } // end-of-if(m_matrixDebug&1<<df)
1385 //
1386 // loop on m_input data
1387 //
1388 for (i = 0; i < 2; i++) { // loop on the two sides
1389 for (j = 0; j < 2; j++) { // loop on the two layers
1390 for (k = 0; k < m_nclock; k++) { // loop on the time bins
1391 nup = 0; // counter of consecutive "on" channels
1392 for (l = 0; l < s_nchan[i]; l++) { // loop on the Matrix channels
1393 if (bitstatus(&m_input[i][j][k][0], l)) {
1394 nup++;
1395 if (nup == 1) first = l;
1396 } // end-of-if(bitstatus
1397 if (!bitstatus(&m_input[i][j][k][0], l) || (l == (s_nchan[i] - 1))) {
1398 if (nup) {
1399 reduce(i, j, k, 0, nup, first);
1400 nup = 0;
1401 } // end-of-if(nup
1402 } // end-of-if(bitstatus
1403 } // end-of-for(l
1404 } // end-of-for(k
1405 } // end-of-for(j
1406 } // end-of-for(i
1407} // end-of-method declustering
1408//------------------------------------------------------------------------//
1409void Matrix::reduce(ubit16 ia, ubit16 ja, ubit16 ka, ubit16 la, ubit16 nup, ubit16 first) {
1410 //
1411 // input ia, ja, ka, la indices of the Matrix data
1412 // nup cluster size = number of consecutive channels on
1413 // first address of the first channel on in the cluster (from 0)
1414 // returns nothing
1415 //
1416 // It copies into m_prepr the channels from input selected by the
1417 // declustering logic.
1418 //
1419 //
1420 ubit16 ncop, i, j, na;
1421 ubit16 df = 15;
1422 ncop = 0;
1423 j = 0;
1424 if (m_matrixDebug & 1 << df) {
1425 cout << " --------------------" << endl
1426 << " | Matrix::reduce |" << endl
1427 << " --------------------" << endl
1428 << " nup= " << nup << " first " << first << endl;
1429 } // end-of-if(m_matrixDebug&1<<df)
1430 //
1431 // analyse nup value and apply the cluster reduction according to it.
1432 // j is the first channel of the cluster retained after declustering;
1433 // ncop is the cluster size after declustering
1434 //
1435 if (nup <= 2) {
1436 j = first;
1437 ncop = nup;
1438 } else if (nup == 3) {
1439 j = first + 1;
1440 ncop = 1;
1441 } else if (nup == 4) {
1442 j = first + 1;
1443 ncop = 2;
1444 } else if (nup > 4) {
1445 j = first + 2;
1446 ncop = nup - 4;
1447 } // end-of-if
1448 if (m_matrixDebug & 1 << df) { cout << " j= " << j << " ncop= " << ncop << endl; } // end-of-if(m_matrixDebug&1<<df)
1449 //
1450 // copy the reduced cluster into the "s_nthres" m_prepr registers
1451 //
1452 for (na = 0; na < s_nthres; na++) {
1453 for (i = j; i < j + ncop; i++) { // loop on each element of the reduced cluster
1454 set_to_1(&m_prepr[na][ia][ja][ka][la], i);
1455 } // end-of-for(i
1456 } // end-of-for(na
1457} // end-of-reduce
1458//------------------------------------------------------------------------//
1460 ubit16 i, j, k;
1461 //
1462 // fill k-pattern
1463 //
1464 for (j = 0; j < m_nclock; j++) { // loop on the clock bins
1466 k_readout[j] = m_trigg[m_toreadout][j];
1467 } // end-of-for(j
1468 //
1469 // find the highest satisfied threshold;
1470 // identify Bunch Crossing and put it in BCID.
1471 //
1472 for (j = 0; j < m_Nbunch; j++) {
1473 for (i = 0; i < s_nthres; i++) {
1474 if (m_trigger[i][j]) {
1475 m_highestth[j] = i + 1; // put threshold address+1 (correct threshold value)
1476 if (m_BCID < 0)
1477 m_BCID = j // local Bunch Crossing IDentifier
1478 + m_thisBC; // re-syncronize to absolute BCID
1479 // - m_BCzero; // remove offset used
1480 } // end-of-if(m_trigger
1481 } // end-of-for(i
1482 } // end-of-for(j
1483 //
1484 // Trigger in Overlapping channels is reported in m_triggerOverlap
1485 //
1486 for (j = 0; j < m_Nbunch; j++) { m_overlap[j] = m_triggerOverlap[j][0] + 2 * m_triggerOverlap[j][1]; } // end-of-for(j
1487 //
1488 // find the highest satisfied threshold for ReadOut pourposes;
1489 //
1490 for (j = 0; j < m_nclock; j++) { // loop on the clock bins
1491 for (i = 0; i < s_nthres; i++) { // loop on thresholds
1492 for (k = 0; k < s_nchan[0]; k++) { // loop on channels (pivot side)
1493 if (m_trigg[i][j] & (1 << k)) highestthRO[j] = i + 1;
1494 } // end-of-for(k
1495 } // end-of-for(i
1496 } // end-of-for(j
1497 //
1498 //
1499 // Trigger in Overlapping channels is reported in m_triggerOverlapRO
1500 //
1501 for (j = 0; j < m_nclock; j++) { overlapRO[j] = m_triggerOverlapRO[j][0] + 2 * m_triggerOverlapRO[j][1]; } // end-of-for(j
1502 //
1503} // end-of-Matrix::makeOut
1504//------------------------------------------------------------------------//
1506 //
1507 int df = 16;
1508 const ubit16 maxchan = 100;
1509 const ubit16 maxtimes = 1000;
1510 ubit16 i, j, l;
1511 ubit16 IJ[maxtimes][4] = {{0}};
1512 ubit16 channels[maxtimes][4][maxchan] = {{{0}}};
1513 float times[maxtimes] = {0};
1514 char plane[4][3];
1515 const float timeOffsetHit = 114.675;
1516 //
1517 rpcdata *rpcpnt;
1518 float timemin;
1519 //
1520 strcpy(plane[0], "I0");
1521 strcpy(plane[1], "I1");
1522 strcpy(plane[2], "J0");
1523 strcpy(plane[3], "J1");
1524 if (m_matrixDebug & 1 << df) {
1525 cout << "-------------------------------" << endl
1526 << "| Matrix::makeTestPattern |" << endl
1527 << "-------------------------------" << endl;
1528 } // end-of-if(m_matrixDebug&1<<df)
1529 //
1530 int ntimes = 0;
1531 ubit16 completed = 0;
1532 //
1533 // first reset the marker flags
1534 //
1535 for (i = 0; i < 2; i++) {
1536 rpcpnt = m_datarpc[i];
1537 while (rpcpnt) {
1538 rpcpnt->mark = 0;
1539 rpcpnt = rpcpnt->next;
1540 } // end-of-while(rpcpnt
1541 } // end-of-for(i
1542 //
1543 while (!completed) {
1544 completed = 1;
1545 timemin = 999999999.;
1546 for (i = 0; i < 2; i++) { // "i" is the CMA side address
1547 rpcpnt = m_datarpc[i];
1548 while (rpcpnt) {
1549 if (rpcpnt->time < timemin && !rpcpnt->mark) {
1550 timemin = rpcpnt->time;
1551 completed = 0;
1552 } // end-of-if(rpcnt
1553 rpcpnt = rpcpnt->next;
1554 } // end-of-while(rpcpnt)
1555 } // end-of-for(i
1556 if (!completed) {
1557 if (ntimes < maxtimes) ntimes += 1;
1558 times[ntimes - 1] = timemin;
1559 for (i = 0; i < 2; i++) { // "i" is the CMA side address
1560 rpcpnt = m_datarpc[i];
1561 while (rpcpnt) {
1562 if (rpcpnt->time == timemin) {
1563 rpcpnt->mark = 1;
1564 if (IJ[ntimes - 1][rpcpnt->layer + 2 * i] < maxchan) { IJ[ntimes - 1][rpcpnt->layer + 2 * i] += 1; }
1565 channels[ntimes - 1][rpcpnt->layer + 2 * i][IJ[ntimes - 1][rpcpnt->layer + 2 * i] - 1] = rpcpnt->stripadd;
1566 } // end-of-if(rpcnt
1567 rpcpnt = rpcpnt->next;
1568 } // end-of-while(rpcpnt)
1569 } // end-of-for(i
1570 } // end-of-if(!completed
1571 } // end-of-while(!completed)
1572 //
1573 //
1574 // open output file
1575 //
1576 ofstream vhdlinput;
1577 vhdlinput.open("k-trigger.output", ios::app);
1578 if (!vhdlinput) {
1579 cout << " File for vhdl analysis not opened. " << endl << " ==================================" << endl << endl;
1580 } else {
1581 if (m_matrixDebug & 1 << df) {
1582 cout << " File for vhdl analysis correctly opened" << endl << endl;
1583 } // end-of-if(m_matrixDebug&1<<df)
1584 } // end-of-if(!vhdlinput
1585 if (mode) {
1586 vhdlinput << " RUN " << m_run << " EVENT " << m_event << " WINDOW " << m_Nbunch;
1587 vhdlinput << " LINES " << (ntimes + ktimes) << std::endl;
1588 } // end-of-if(mode
1589 for (l = 0; l < ntimes; l++) {
1590 vhdlinput << " TIME " << times[l] + timeOffsetHit << " ";
1591 for (i = 0; i < 4; i++) {
1592 vhdlinput << plane[i][0] << plane[i][1] << " " << IJ[l][i] << " ";
1593 for (j = 0; j < IJ[l][i]; j++) { vhdlinput << channels[l][i][IJ[l][i] - 1 - j] << " "; } // end-of-for(j
1594 } // end-of-for(i
1595 vhdlinput << std::endl;
1596 } // end-of-for(l
1597 //
1598 vhdlinput.close();
1599} // end-of-makeTestPattern
1600//------------------------------------------------------------------------//
1602 // int df=17;
1603 const float timeOffsetKPa = 168.125;
1604 const float timeOffsetThr = 210.500;
1605 ubit16 i, l;
1606 CMAword bit;
1607 ubit16 chanHistory[32] = {0};
1608 const ubit16 maxchan = 100;
1609 const ubit16 maxtimes = m_nclock;
1610 ubit16 ntimes, newtime;
1611 ubit16 nchannels[s_NDLLCYC*8][2][2], channels[s_NDLLCYC*8][2][2][maxchan];
1612 float time, times[s_NDLLCYC*8]{0};
1613 //
1614 // trigger registers: k-trigger (historically was k-pattern)
1615 //
1616 ntimes = 0;
1617 for (i = 0; i < m_nclock; i++) { nchannels[i][0][0] = 0; }
1618 time = (float)m_thisBC * s_BCtime - ((float)(m_BCzero * s_NDLLCYC)) * s_DLLtime;
1619 for (i = 0; i < m_nclock; time += s_DLLtime, i++) {
1620 bit = 1;
1621 newtime = 1;
1622 for (l = 0; l < s_nchan[0]; l++) {
1623 if (m_k_pattern[i] & bit) {
1624 if (!chanHistory[l]) {
1625 if (newtime) {
1626 if (ntimes < maxtimes) ntimes += 1;
1627 times[ntimes - 1] = time;
1628 } // end-of-if(newtime
1629 if (nchannels[ntimes - 1][0][0] < maxchan) nchannels[ntimes - 1][0][0] += 1;
1630 channels[ntimes - 1][0][0][nchannels[ntimes - 1][0][0] - 1] = l;
1631 newtime = 0;
1632 } // end-of-if(!chanHistory
1633 chanHistory[l] = 1;
1634 } else { // if(m_k_pattern
1635 chanHistory[l] = 0;
1636 } // end-of-if(m_k_pattern
1637 bit = bit << 1;
1638 } // end-of-for(l
1639 } // end-of-for(i
1640
1641 ubit16 nthresPass, thresPass[8], overlPass[8], BCidentifier[8];
1642 nthresPass = 0;
1643 for (i = 0; i < m_Nbunch; i++) {
1644 if (m_highestth[i]) {
1645 thresPass[nthresPass] = m_highestth[i];
1646 overlPass[nthresPass] = m_overlap[i];
1647 BCidentifier[nthresPass] = i;
1648 nthresPass += 1;
1649 }
1650 }
1651 makeTestPattern(1, ntimes + 2 * nthresPass);
1652 //
1653 // open output file
1654 //
1655 ofstream out_k_trigger;
1656 out_k_trigger.open("k-trigger.output", ios::app);
1657 //
1658 // code to print out m_k_pattern
1659 //
1660 for (i = 0; i < ntimes; i++) {
1661 out_k_trigger << " TIME " << times[i] + timeOffsetKPa << " K ";
1662 out_k_trigger << nchannels[i][0][0] << " ";
1663 for (l = 0; l < nchannels[i][0][0]; l++) { out_k_trigger << channels[i][0][0][l] << " "; } // end-of-for(l
1664 out_k_trigger << endl;
1665 } // end-of-for(i
1666 //
1667 if (nthresPass) {
1668 for (i = 0; i < nthresPass; i++) {
1669 out_k_trigger << " TIME " << BCidentifier[i] * 25. + timeOffsetThr;
1670 out_k_trigger << " THR " << thresPass[i] << endl;
1671 if (overlPass[i]) {
1672 out_k_trigger << " TIME " << BCidentifier[i] * 25. + timeOffsetThr;
1673 out_k_trigger << " OVL " << overlPass[i] << std::endl;
1674 }
1675 }
1676 }
1677 //
1678 out_k_trigger.close();
1679 //
1680} // end-of-makeOutPattern
1681//------------------------------------------------------------------------//
1683 //
1684 // input: i threshold address
1685 // *arr pointer to bidimen. array
1686 //
1687 // returns the number of possible configurations compatible with the
1688 // required majority pointed by majorities[i]
1689 //
1690 // Data *arr(k) and *arr(k+1) give the majority addresses for the side-x
1691 // and side-y respectevely.
1692 //
1693 ubit16 nconf = 0;
1694 //
1695 // cout<<"lowhig="<<m_lowhigh<< "majorities= "<<m_majorities[0]
1696 // <<" "<< m_majorities[1]<<" "<<m_majorities[2]<<endl;
1697 //
1698 switch (m_lowhigh) {
1699 case 0: // low-pt trigger matrix
1700 switch (m_majorities[i]) { // select the required majority for each thresh.;
1701 case 0: // 1-out-of-4 majority: no implementation yet
1702 // gives 1/2 in I OR 1/2 in J
1703 nconf = 0;
1704 break;
1705 case 1: // 2-out-of-4 majority
1706 nconf = 1;
1707 *(arr + 0) = 0;
1708 *(arr + 1) = 0;
1709 break;
1710 case 2: // 3-out-of-4 majority
1711 nconf = 2;
1712 *(arr + 0) = 0;
1713 *(arr + 1) = 1;
1714 *(arr + 2) = 1;
1715 *(arr + 3) = 0;
1716 break;
1717 case 3: // 4-out-of-4 majority
1718 nconf = 1;
1719 *(arr + 0) = 1;
1720 *(arr + 1) = 1;
1721 break;
1722 default: throw std::runtime_error("Matrix::config: the majority " + std::to_string(m_majorities[i]) + " is unforeseen");
1723 }
1724 break;
1725 case 1: // high-pt trigger matrix
1726 // high-pt trigger
1727 switch (m_majorities[i]) {
1728 case 1: // 1-out-of-2 majority
1729 nconf = 1;
1730 *(arr + 0) = 0;
1731 *(arr + 1) = 0;
1732 break;
1733 case 2: // 2-out-of-2 majority
1734 nconf = 1;
1735 *(arr + 0) = 0;
1736 *(arr + 1) = 1;
1737 break;
1738 default: throw std::runtime_error("Matrix::config: the majority " + std::to_string(m_majorities[i]) + " is unforeseen");
1739 }
1740 break;
1741 default: throw std::runtime_error("Matrix::config: lowhighpt " + std::to_string(m_lowhigh) + " is unforeseen");
1742 }
1743 return nconf;
1744} // end-of-method-config
1745//------------------------------------------------------------------------//
1746int Matrix::getSubsystem() const { return m_subsystem; }
1747//------------------------------------------------------------------------//
1749//------------------------------------------------------------------------//
1750int Matrix::getSector() const { return m_sector; }
1751//------------------------------------------------------------------------//
1752int Matrix::getPad() const { return m_pad; }
1753//------------------------------------------------------------------------//
1754int Matrix::getLowHigh() const { return m_lowhigh; }
1755//------------------------------------------------------------------------//
1756int Matrix::getAddress0() const { return m_address[0]; }
1757//------------------------------------------------------------------------//
1758int Matrix::getAddress1() const { return m_address[1]; }
1759//------------------------------------------------------------------------//
1760int Matrix::getLocalAdd() const { return m_localadd; }
1761//------------------------------------------------------------------------//
1762ubit16 Matrix::getOutputThres(ubit16 bunch) const { return m_highestth[bunch]; } // end-of-ubit16-getOutput
1763//------------------------------------------------------------------------//
1764ubit16 Matrix::getOutputOverl(ubit16 bunch) const { return m_overlap[bunch]; } // end-of-ubit16-getOutput
1765//------------------------------------------------------------------------//
1766sbit16 Matrix::getBunchPhase() const { return m_BunchPhase; } // end-of-ubit16-getBunchPhase
1767//------------------------------------------------------------------------//
1768sbit16 Matrix::getBunchOffset() const { return m_BunchOffset; } // end-of-ubit16-getBunchOffset
1769//------------------------------------------------------------------------//
1770void Matrix::set_to_1(CMAword *p, sbit16 channel) const {
1771 CMAword j{1};
1772 std::array<ubit16, 2> i = inds(channel);
1773 if (!(channel < 0)) {
1774 *(p + i[0]) = *(p + i[0]) | j << i[1];
1775 } else {
1776 throw std::out_of_range("Matrix::set_to_1: channel is negative; channel=" + std::to_string(channel));
1777 } // end-of-if(!(channel<0
1778} // end-of-Matrix::set_to_1
1779//----------------------------------------------------------------------//
1780void Matrix::set_to_0(CMAword *p, sbit16 channel) const {
1781 CMAword j{1};
1782 std::array<ubit16, 2> i = inds(channel);
1783 if (!(channel < 0)) {
1784 *(p + i[0]) = *(p + i[0]) & ~(j << i[1]);
1785 } else {
1786 throw std::out_of_range("Matrix::set_to_1: channel is negative; channel=" + std::to_string(channel));
1787 } // end-of-if(!(channel<0
1788} // end-of-Matrix::set_to_1
1789
1790//----------------------------------------------------------------------//
1791void Matrix::wind() const {
1792 sbit16 i, j;
1793 cout << "-----------------------" << endl
1794 << "| Matrix::wind |" << endl
1795 << "-----------------------" << endl
1796 << " Matrix Roads " << endl;
1797 for (i = 0; i < s_nthres; i++) {
1798 for (j = 0; j < s_nchan[0]; j++) {
1799 cout << " thres. " << i << " channel "
1800 << j
1801 // <<" Road0 "<<hex<<(*(m_roads+32*2*i+2*j+0))<<dec
1802 // <<" Road1 "<<hex<<(*(m_roads+32*2*i+2*j+1))<<dec<<endl;
1803 << " Road0 " << hex << (m_trigRoad[i][j][0]) << dec << " Road1 " << hex << (m_trigRoad[i][j][1]) << dec << endl;
1804 }
1805 }
1806 cout << " majorities: " << endl;
1807 for (i = 0; i < 3; i++) { cout << m_majorities[i] << " " << endl; }
1808 cout << endl
1809 << " number of overlapping ' low' channels: " << m_matOverlap[0] << endl
1810 << " number of overlapping 'high' channels: " << m_matOverlap[1] << endl;
1811 for (i = 0; i < s_nchan[0]; i++) { cout << " channel " << i << " in coincidence with " << m_diagonal[i] << endl; } // end-of-for(i
1812} // end-of-method-wind
1813//----------------------------------------------------------------------//
1814void Matrix::display() const {
1815 ubit16 i;
1816 ubit16 df = 19;
1817 rpcdata *rpcpnt;
1818 //
1819 // if(this) {
1820 cout << "=======================" << endl << "|| Matrix Display ||" << endl << "=======================" << endl << endl;
1822
1823 cout << endl << " All raw data " << endl;
1824 for (i = 0; i < 2; i++) {
1825 cout << " Matrix Side is " << i << endl;
1826 rpcpnt = m_datarpc[i];
1827 while (rpcpnt) {
1828 cout << " Layer= " << rpcpnt->layer << " stripadd= " << rpcpnt->stripadd << " time= " << rpcpnt->time
1829 << " mask= " << rpcpnt->masked << " BC= " << rpcpnt->BC << " DLL= " << rpcpnt->DLL << " delay= " << rpcpnt->delay << endl;
1830 rpcpnt = rpcpnt->next;
1831 } // end-of-while(rpcpnt)
1832 } // end-of-for(i
1833 //
1834 if (m_matrixDebug & 1 << (df + 0)) {
1835 cout << " Display Matrix Input " << endl;
1836 disp_CMAreg(0); // display the input registers
1837 }
1838 //
1839 //
1840 if (m_matrixDebug & 1 << (df + 1)) {
1841 cout << " Display Matrix Preprocessing " << endl;
1842 disp_CMAreg(1); // display the prepro registers
1843 }
1844 //
1845 if (m_matrixDebug & 1 << (df + 2)) {
1846 cout << " Display Matrix Majority " << endl;
1847 disp_CMAreg(2); // display the majority registers
1848 }
1849 //
1850 if (m_matrixDebug & 1 << (df + 3)) {
1851 cout << " Display Trigger " << endl;
1852 disp_CMAreg(3); // display the trigger registers
1853 }
1854 //
1855 //} else {
1856 // cout<<"======================="<<endl
1857 // <<"|| Matrix EMPTY ||"<<endl
1858 // <<"======================="<<endl;
1859 //}//end-of-Matrix::display
1860} // end-of-method display
1861//------------------------------------------------------------------------//
1863 cout << " Matrix Attributes: " << endl
1864 << " Subsystem " << m_subsystem << "; Projection " << m_projection << "; Sector " << m_sector << "; Pad " << m_pad << "; LowHig "
1865 << m_lowhigh << "; addresses: " << m_address[0] << " " << m_address[1] << endl;
1866} // end-of-Matrix::attributes
1867//------------------------------------------------------------------------//
1869 //
1870 // display the CMA registers
1871 //
1872 ubit16 i, j, k;
1873 if (id < 2) {
1874 for (i = 0; i < 2; i++) { // loop on the two Matrix sides
1875 cout << " CMA Side (0=side-x; 1=side-y) " << i << endl;
1876 for (j = 0; j < 2; j++) { // loop on the two Matrix layers
1877 switch (id) {
1878 case 0:
1879 cout << " Layer " << j << endl;
1880 dispRegister(&m_input[i][j][0][0], i);
1881 break;
1882 case 1:
1883 cout << " Layer " << j << endl;
1884 dispRegister(&m_prepr[0][i][j][0][0], i);
1885 break;
1886 default: cout << " Matrix::disp_CMAreg id value " << id << " not foreseen " << endl;
1887 } // end-of-switch
1888 } // end-of-for(j
1889 } // end-of-for(i
1890
1891 } else {
1892 switch (id) {
1893 case 2:
1894 for (i = 0; i < s_nthres; i++) { // loop on threshold
1895 cout << " Threshold address " << i << endl;
1896 for (j = 0; j < 2; j++) { // loop on matrix sides
1897 cout << " CMA Side (0=side-x; 1=side-y) " << j << endl;
1898 for (k = 0; k < 2; k++) { // loop on majority types
1899 cout << " Majority type (0=1/2; 1=2/2) " << k << endl;
1900 dispRegister(&m_mjori[i][j][k][0][0], j);
1901 } // end-of-for(k
1902 } // end-of-for(j
1903 } // end-of-for(i
1904 break;
1905 case 3:
1906 for (i = 0; i < s_nthres; i++) { // loop on the three thresholds
1907 cout << " Trigger Threshold address " << i << endl;
1908 dispTrigger(&m_trigg[i][0]);
1909 } // end-of-for(i
1910 cout << " ReadOut Buffer " << endl;
1911 dispRegister(&rodat[0][0][0][0], 0);
1912 break;
1913 default: cout << " Matrix::disp_CMAreg id value " << id << " not foreseen " << endl;
1914 } // end-of-switch (id)
1915
1916 } // end-of-if(id
1917 cout << " " << endl;
1918} // end-of-Matrix::disp_CMAreg
1919//------------------------------------------------------------------------//
1920void Matrix::dispRegister(const CMAword *p, ubit16 side) const {
1921 ubit16 n, j, k;
1922 //
1923 // allocation for oststream strdisp
1924 //
1925 std::ostringstream strdisp;
1926 n = (s_nchan[side] - 1) / s_wordlen + 1;
1927 strdisp << " ";
1928
1929 for (j = 0; j < s_nchan[side]; j += 2) { strdisp << " " << j % 10; } // end-of-for
1930 strdisp << " " << endl;
1931 for (j = 0; j < m_nclock; j++) { // loop on the m_nclock cycles
1932 strdisp << " " << j % 10 << " ";
1933 for (k = 0; k < n; k++) { // loop on the buffer words
1934 dispBinary(p + k + 2 * j, strdisp);
1935 } // end-of-for(k
1936 strdisp << " " << endl;
1937
1938 } // end-of-for(j
1939
1940 cout << strdisp.str() << endl;
1941} // end-of-Matrix::dispRegister
1942//------------------------------------------------------------------------//
1943void Matrix::dispTrigger(const CMAword *p) const {
1944 ubit16 j;
1945 //
1946 // allocation for oststream strdisp
1947 //
1948
1949 std::ostringstream strdisp;
1950 strdisp << " ";
1951
1952 for (j = 0; j < s_nchan[0]; j += 2) { strdisp << " " << j % 10; } // end-of-for
1953 strdisp << " " << endl;
1954 for (j = 0; j < m_nclock; j++) { // loop on the m_nclock cycles
1955 strdisp << " " << j % 10 << " ";
1956 dispBinary(p + j, strdisp);
1957 strdisp << " " << endl;
1958 } // end-of-for(j
1959
1960 cout << strdisp.str() << endl;
1961} // end-of-Matrix::dispTrigger
1962//------------------------------------------------------------------------//
1963void Matrix::dispBinary(const CMAword *p, std::ostringstream &strdisp) const {
1964 ubit16 i;
1965 CMAword j;
1966 j = 1;
1967 for (i = 0; i < s_wordlen; i++) {
1968 if ((*p) & j) {
1969 strdisp << "|";
1970 } else {
1971 strdisp << ".";
1972 } // end-of-if
1973 j = j << 1;
1974 } // end-of-for(
1975} // end-of-Matrix::dispBinary
1976//------------------------------------------------------------------------//
1977void Matrix::dispWind() const {
1978 for (ubit16 i = 0; i < s_nthres; i++) { dispWind(i); }
1979} // end-of-dispWind
1980//------------------------------------------------------------------------//
1981void Matrix::dispWind(ubit16 thres) const {
1982 std::ostringstream strdisp;
1983
1984 strdisp << endl
1985 << " =========================" << endl
1986 << " = =" << endl
1987 << " = Matrix::dispWind =" << endl
1988 << " = Threshold address " << thres << " =" << endl
1989 << " = =" << endl
1990 << " =========================" << endl
1991 << endl;
1992 //
1993 for (sbit16 j = s_nchan[1] - 1; j >= 0; j--) {
1994 ubit16 ad1 = j / 32;
1995 ubit16 ad2 = j % 32;
1996 if (j < 10) {
1997 strdisp << " " << j << " ";
1998 } else {
1999 strdisp << j << " ";
2000 }
2001 for (ubit16 k = 0; k < s_nchan[0]; k++) {
2002 if ((m_trigRoad[thres][k][ad1]) & (1 << ad2)) {
2003 strdisp << "*";
2004 } else {
2005 strdisp << ".";
2006 } // end-of-if
2007 } // end-of-for(k
2008 strdisp << " " << endl;
2009 } // end-of-for(j
2010 strdisp << " " << endl;
2011 strdisp << " 00000000001111111111222222222233" << endl << " 01234567890123456789012345678901" << endl;
2012 //
2013 cout << strdisp.str() << endl;
2014} // end-of-dispWind
2015
2016//----------------------------------------------------------------------------//
2017ubit16 Matrix::char2int(const char *str, CMAword the32[2]) {
2018 ubit16 outflag = 0;
2019 the32[0] = 0;
2020 the32[1] = 0;
2021 ubit16 stringLength = strlen(str);
2022 if (stringLength > 16) {
2023 outflag = 1;
2024 } else {
2025 for (ubit16 i = 0; i < stringLength; i++) {
2026 // cout<<" Reading character "<<*(str+stringLength-1-i)<<endl;
2027 if (*(str + stringLength - 1 - i) == '0')
2028 the32[i / 8] = the32[i / 8] + 0;
2029 else if (*(str + stringLength - 1 - i) == '1')
2030 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 1;
2031 else if (*(str + stringLength - 1 - i) == '2')
2032 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 2;
2033 else if (*(str + stringLength - 1 - i) == '3')
2034 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 3;
2035 else if (*(str + stringLength - 1 - i) == '4')
2036 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 4;
2037 else if (*(str + stringLength - 1 - i) == '5')
2038 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 5;
2039 else if (*(str + stringLength - 1 - i) == '6')
2040 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 6;
2041 else if (*(str + stringLength - 1 - i) == '7')
2042 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 7;
2043 else if (*(str + stringLength - 1 - i) == '8')
2044 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 8;
2045 else if (*(str + stringLength - 1 - i) == '9')
2046 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 9;
2047 else if (*(str + stringLength - 1 - i) == 'a' || *(str + stringLength - 1 - i) == 'A')
2048 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 10;
2049 else if (*(str + stringLength - 1 - i) == 'b' || *(str + stringLength - 1 - i) == 'B')
2050 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 11;
2051 else if (*(str + stringLength - 1 - i) == 'c' || *(str + stringLength - 1 - i) == 'C')
2052 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 12;
2053 else if (*(str + stringLength - 1 - i) == 'd' || *(str + stringLength - 1 - i) == 'D')
2054 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 13;
2055 else if (*(str + stringLength - 1 - i) == 'e' || *(str + stringLength - 1 - i) == 'E')
2056 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 14;
2057 else if (*(str + stringLength - 1 - i) == 'f' || *(str + stringLength - 1 - i) == 'F')
2058 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 15;
2059 else
2060 outflag = 2;
2061 } // end-of-for
2062 }
2063
2064 // if(outflag) {
2065 // the32[0]=0;
2066 // the32[1]=1;
2067 // } else {
2068 // CMAword temp = the32[1];
2069 // the32[1]=the32[0];
2070 // the32[0]=temp;
2071 // }
2072 return outflag;
2073} // end-of-char2int
2074//----------------------------------------------------------------------------//
2075CMAword Matrix::intPow(const ubit16 base, const ubit16 expo) const {
2076 CMAword output = 1;
2077 if (expo) {
2078 for (ubit16 i = 1; i <= expo; i++) { output = output * base; } // end-of-for
2079 }
2080 return output;
2081} // end-of-CMAword Matrix::intPow
@ Hardware
Definition BaseObject.h:11
#define CMAVERSION
Definition CMAVERSION.h:6
double length(const pvec &v)
int16_t sbit16
Definition Lvl1Def.h:21
int32_t sbit32
Definition Lvl1Def.h:19
uint32_t CMAword
Definition Lvl1Def.h:17
const bool debug
unsigned short int ubit16
BaseObject(ObjectType, const std::string &)
Definition BaseObject.cxx:7
CMAword intPow(const ubit16 base, const ubit16 expo) const
Matrix(int run, int event, CMAword debug, int subsys, int proj, int sect, int padadd, int lowhig, int add[2], int locadd, int NOBXS, int BCZERO)
void setRunEvent(int runNum, int eventNum)
void setDelay(ubit16 iside, ubit16 ilayer, ubit16 delay)
void set_to_1(CMAword *p, sbit16 channel) const
void reduce(ubit16 ia, ubit16 ja, ubit16 ka, ubit16 la, ubit16 nup, ubit16 first)
ubit16 char2int(const char *str, CMAword the32[2])
ubit16 config(ubit16 i, ubit16 *arr) const
ubit16 getOutputThres(ubit16 bunch) const
CMAword getMatOverlap(ubit16 add) const
void setMask1(ubit16 ithreshold, ubit16 iside, ubit16 imajority, ubit16 ichannel)
void set_to_0(CMAword *p, sbit16 channel) const
void makeTestPattern(ubit16 mode, ubit16 ktimes)
void dispTrigger(const CMAword *p) const
CMAword rodat[2][2][64][2]
Note array lengths using hardcoded values rather than to depend on NOBXS as they were in the past (as...
void setMaskReadOut(ubit16 iside, ubit16 ilayer, ubit16 ichannel)
void shift(CMAword *buffi, CMAword *buffo, ubit16 i) const
void setConfig(int *l, ubit16 *p1, int *k, CMAword *p2, int *q, CMAword *o, sbit32 *g)
ubit16 getOutputOverl(ubit16 bunch) const
void setMask0(ubit16 iside, ubit16 ilayer, ubit16 ichannel)
void dispRegister(const CMAword *p, ubit16 side) const
void putData(int sidemat, int layer, int stripaddress, float time)
CMAword getRoad(ubit16 addThres, ubit16 addChn, ubit16 add64) const
void setMatOverlap(ubit16 add, CMAword content)
void setLocalDirection(ubit16 add, int content)
void dispBinary(const CMAword *p, std::ostringstream &strdisp) const
void setMajority(ubit16 add, int content)
void setRoad(ubit16 addThres, ubit16 addChn, ubit16 add64, CMAword content)
void setDiagonal(ubit16 add, sbit32 content)
void zero(TH2 *h)
zero the contents of a 2d histogram
bool add(const std::string &hname, TKey *tobj)
Definition fastadd.cxx:55
int r
Definition globals.cxx:22
std::string base
Definition hcg.cxx:81
Definition run.py:1
STL namespace.