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