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
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 }
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 }
801 m_trigRoad[addThres][addChn][0] = the32[0];
802 m_trigRoad[addThres][addChn][1] = the32[1];
803} // end-of-Matrix::setRoad
804//----------------------------------------------------------------------//
806 if (add > 1) {
807 throw std::out_of_range("Matrix::setMatOverlap : add= " + std::to_string(add) + " not valid");
808 } else {
809 m_matOverlap[add] = content;
810 }
811} // end-of-Matrix::setMatOverlap
812//----------------------------------------------------------------------//
814 if (add > s_nchan[0]) {
815 throw std::out_of_range("Matrix::setDiagonal : add= " + std::to_string(add) + " not valid");
816 } else {
817 m_diagonal[add] = content;
818 } // end-of-if
819} // end-of-Matrix::setDiagonal
820//----------------------------------------------------------------------//
822 CMAword output = 0;
823 if (add > 1) {
824 throw std::out_of_range("Matrix::getMatOverlap : add= " + std::to_string(add) + " not valid");
825 } else {
826 output = m_matOverlap[add];
827 }
828 return output;
829} // end-of-Matrix::getMatOverlap
830//----------------------------------------------------------------------//
831CMAword Matrix::getRoad(ubit16 addThres, ubit16 addChn, ubit16 add64) const {
832 CMAword output = 0;
833 if (addThres >= s_nthres || addChn > s_nchan[0] || add64 > 1) {
834 throw std::out_of_range("Matrix::getRoad : addThres= " + std::to_string(addThres) + " addChn= " + std::to_string(addChn) +
835 " add64= " + std::to_string(add64) + " not valid");
836 } else {
837 output = m_trigRoad[addThres][addChn][add64];
838 } // end-of-if
839 return output;
840} // end-of-Matrix::getRoad
841//----------------------------------------------------------------------//
843 int output = 0;
844 if (add >= s_nthres) {
845 throw std::out_of_range("Matrix::getMajority : add= " + std::to_string(add) + " not valid");
846 } else {
847 output = m_majorities[add];
848 } // end-of-if
849 return output;
850} // end-of-Matrix::getMajority
851//----------------------------------------------------------------------//
853 // returns coincidence flag: 0 if there is no trigger for all thresholds
854 // 1 if there is at least one threshold with trigger
855 // 2 if the lowtohigh threshold (or higher) is m_trigg
856 //
857 // execute this active CM
858 //
859 ubit16 df = 4; // debug flag address
860 if (m_matrixDebug & 1 << df) {
861 cout << "====================" << endl
862 << "| |" << endl
863 << "| Matrix::execute |" << endl
864 << "| --------------- |" << endl
865 << "| |" << endl
866 << "====================" << endl;
868 } // end-of-if(m_matrixDebug&1<<df)
869 //
870 // 0) programmed windows (s_nthres) and time calibration constants for this
871 // matrix
872 if (m_matrixDebug & 1 << df) wind();
873 // 1) store deadtime in dyn. structure; deadtime is applied by "applyDeadTime"
875 // 2) masking;
876 masking();
877 // 3) delay
878 delay();
879 // 5) fill the CMA
880 load();
881 // 6) apply deadtime response to Input signals
882 deadTime();
884 // 7) preprocessing
885 prepro();
886 // 8) coincidence;
887 coincide();
888 //
889 makeOut();
890
891 // Code to be activated for testing the VHDL simulation.
892 // makeOutPattern ();
893 //
894} // end-of-method execute;
895//----------------------------------------------------------------------//
897 ubit16 df = 5;
898 rpcdata *rpchit;
899 if (m_matrixDebug & 1 << df) {
900 cout << "--------------------------" << endl << "| Matrix::storeDeadtime |" << endl << "--------------------------" << endl;
901 } // end-of-if(m_matrixDebug&1<<df)
902 for (ubit16 i = 0; i < 2; i++) {
903 rpchit = m_datarpc[i];
904 while (rpchit) {
905 rpchit->deadtime = m_channDeadT[i][rpchit->layer][rpchit->stripadd / s_timeGroupB];
906 rpchit = rpchit->next;
907 } // end-of-while(rpchit
908 } // end-of-for(ubit16 i
909} // end-of-Matrix::storeDeadtime
910//----------------------------------------------------------------------//
912 ubit16 df = 6;
913 rpcdata *rpchit;
914 if (m_matrixDebug & 1 << df) {
915 cout << "--------------------" << endl << "| Matrix::masking |" << endl << "--------------------" << endl;
916 } // end-of-if(m_matrixDebug&1<<df)
917 for (ubit16 i = 0; i < 2; i++) {
918 rpchit = m_datarpc[i];
919 while (rpchit) {
920 rpchit->masked = m_channMask0[i][rpchit->layer][rpchit->stripadd];
921 rpchit = rpchit->next;
922 } // end-of-while(rpchit
923 } // end-of-for(ubit16 i
924} // end-of-Matrix::masking
925//----------------------------------------------------------------------//
927 ubit16 df = 7;
928 rpcdata *rpchit;
929 if (m_matrixDebug & 1 << df) {
930 cout << "--------------------" << endl << "| Matrix::delay |" << endl << "--------------------" << endl;
931 } // end-of-if(m_matrixDebug&1<<df)
932 for (ubit16 i = 0; i < 2; i++) {
933 rpchit = m_datarpc[i];
934 while (rpchit) {
935 rpchit->delay = m_channDelay[i][rpchit->layer][rpchit->stripadd / s_timeGroupA];
936 rpchit = rpchit->next;
937 } // end-of-while(rpchit
938 } // end-of-for(ubit16 i
939} // end-of-Matrix::delay
940//----------------------------------------------------------------------//
942 ubit16 df = 8;
943 sbit32 abs_time, timeadd;
944 rpcdata *rpcpnt;
945 //
946 if (m_matrixDebug & 1 << df) {
947 cout << "--------------------" << endl << "| Matrix::load |" << endl << "--------------------" << endl;
948 } // end-of-if(m_matrixDebug&1<<df)
949 //
950 for (ubit16 i = 0; i < 2; i++) { // "i" is the CMA side address
951 rpcpnt = m_datarpc[i];
952 while (rpcpnt) {
953 if (m_matrixDebug & 1 << df) {
954 cout << " Layer= " << rpcpnt->layer << " stripadd= " << rpcpnt->stripadd << " time= " << rpcpnt->time
955 << " mask= " << rpcpnt->masked << " BC= " << rpcpnt->BC << " DLL= " << rpcpnt->DLL << " delay= " << rpcpnt->delay
956 << endl;
957 } // end-of-if(m_matrixDebug&1<<df)
958 abs_time = s_NDLLCYC * rpcpnt->BC + rpcpnt->DLL + rpcpnt->delay;
959
960 timeadd = abs_time - s_NDLLCYC * m_thisBC // synchronize the data to m_thisBC
961 + s_NDLLCYC * m_BCzero; // put m_thisBC at the center of the buffer
962
963 if (m_matrixDebug & 1 << df) { cout << " abs_time= " << abs_time << " timeadd= " << timeadd << endl; }
964
965 //
966 // store this digit if it is within time window and not masked
967 //
968 if (timeadd >= 0 && timeadd < m_nclock && !rpcpnt->masked) {
969 if (m_matrixDebug & 1 << df) {
970 cout << " setting input with side " << i << " " << rpcpnt->layer << " " << timeadd << " 0"
971 << " for channel " << rpcpnt->stripadd << " timeadd " << timeadd << endl;
972 } // end-of-if(m_matrixDebug&1<<df)
973 set_to_1(&m_input[i][rpcpnt->layer][timeadd][0], rpcpnt->stripadd);
974 } // end-of-if(timeadd
975 //
976 rpcpnt = rpcpnt->next;
977 //
978 } // end-of-while(rpcpnt)
979 } // end-of-for(i
980} // end-of-Matrix::load()
981//------------------------------------------------------------------------//
983 //
984 // copy input to rodat
985 //
986 for (ubit16 i = 0; i < 2; i++) { // side address
987 for (ubit16 j = 0; j < 2; j++) { // layer address
988 for (ubit16 k = 0; k < m_nclock; k++) { // clock bins
989 for (ubit16 l = 0; l < 2; l++) { // the two words to make 64 bits
990 rodat[i][j][k][l] = m_input[i][j][k][l] & ~m_channReadOutMask[i][j][l];
991 } // end-of-for(l
992 } // end-of-for(k
993 } // end-of-for(j
994 } // end-of-for(i
995} // end-of-copyDataToReadOut
996//------------------------------------------------------------------------//
998 ubit16 df = 9;
999 if (m_matrixDebug & 1 << df) {
1000 cout << "-------------------------" << endl << "| matrix: preprocessing |" << endl << "-------------------------" << endl;
1001 } // end-of-if(m_matrixDebug&1<<df)
1002 //
1003 // 1) pulse width
1004 pulse_width();
1005 // 2) declustering
1006 declus();
1007 // 3) majority
1008 majori();
1009 // 4) mask to 1
1010 maskTo1();
1011} // end-of-method prepro
1012//------------------------------------------------------------------------//
1014 //
1015 // input none
1016 //
1017 // returns trigger flag
1018 //
1019 //
1020 sbit16 BCaddress = 0;
1021 //
1022 ubit16 df = 10;
1023 ubit16 i, j, l, m;
1024 ubit16 thres, chan, nconf, conf[4][2];
1025 for (i = 0; i < 4; i++) {
1026 for (j = 0; j < 2; j++) { conf[i][j] = 0; }
1027 }
1028 //
1029 if (m_matrixDebug & 1 << df) {
1030 cout << "--------------------" << endl << "| matrix: coincide |" << endl << "--------------------" << endl;
1031 } // end-of-if(m_matrixDebug&1<<df)
1032 //
1033 // nconf gives the number of possible configurations compatible with
1034 // the required majority;
1035 // conf[i][j] gives the two indices "j" for the side-x (pivot) and side-y
1036 // array respectively correspondent to the configurtion number "i"
1037 //
1038 if (m_matrixDebug & 1 << df) {
1039 cout << " Matrix::coincidence; lowhigh= " << m_lowhigh << endl
1040 << " Matrix::coincidence; majority array ="
1041 << " " << m_majorities[0] << " " << m_majorities[1] << " " << m_majorities[2] << endl;
1042 } // end-of-if(m_matrixDebug&1<<df)
1043 //
1044 for (i = 0; i < m_nclock; i++) { // loop on clock cycles
1045 for (thres = 0; thres < s_nthres; thres++) { // loop on the three possible thresholds
1046 // thresholds address increases with
1047 // increasing pT
1048 nconf = config(thres, &conf[0][0]); // number of config. for this threshold
1049 //
1050 // if(m_matrixDebug&1<<df) {
1051 // cout<<"nconf="<<nconf<<" conf="<<endl;
1052 // for(int ii=0;ii<4;ii++){ cout<<" "<<conf[ii][0]<<endl;}
1053 // cout<<endl;
1054 // for(int ii=0;ii<4;ii++){ cout<<" "<<conf[ii][1]<<endl;}
1055 // cout<<endl;
1056 //}//end-of-if(m_matrixDebug&1<<df)
1057
1058 for (l = 0; l < nconf; l++) { // loop on all config. for this threshold
1059 for (j = 0; j < s_nchan[0]; j++) { // loop on all side-x channels
1060 //
1061 // coincidence evaluation:
1062 // for the given configuration "l" and the given channel "j" in the
1063 // pivot plane, the coincidence requires
1064 // a) the required majority "m_mjori[thres][0][conf[l][0]][i][0]"
1065 // for channel "j"
1066 // b) the required majority "m_mjori[thres][1][conf[l][0]][i][0,1]"
1067 // in coincidence with the programmed road in "*(m_roads+2*j)" and
1068 // "*(m_roads+2*j+1)
1069 //
1070 // if( bitstatus(&m_mjori[thres][0][conf[l][0]][i][0],j)
1071 // *( m_mjori[thres][1][conf[l][1]][i][0]&(*(m_roads+32*2*thres+2*j+0))
1072 // | m_mjori[thres][1][conf[l][1]][i][1]&(*(m_roads+32*2*thres+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_trigRoad[thres][j][0]) |
1076 (m_mjori[thres][1][conf[l][1]][i][1] & m_trigRoad[thres][j][1]))) {
1077 if (m_matrixDebug & 1 << df) {
1078 cout << "coincidence!!!"
1079 << " clock=" << i << " xchan=" << j << endl;
1080 } // end-of-if(m_matrixDebug
1081
1082 set_to_1(&m_trigg[thres][i], j);
1083 BCaddress = ((i + m_BunchPhase) / s_NDLLCYC) + m_BunchOffset;
1084 if (BCaddress >= 0 && BCaddress < m_Nbunch)
1085 m_trigger[thres][BCaddress] = 1; // set "m_trigger" to 1 for this threshold...
1086 // ...and this Bunch Crossing
1087
1088 } // end-of-if(bitstatus...
1089 } // end-of-for(j
1090 } // end-of-for(l
1091 //
1092 // for(m=0;m<2;m++) { // loop on left-right sides to evaluate overlap
1093 // if(!m_triggerOverlapRO[i][m])
1094 // m_triggerOverlapRO[i][m] = (m_trigg[thres][i] & m_matOverlap[m]);
1095 // if(!m_triggerOverlap[i/s_NDLLCYC][m])
1096 // m_triggerOverlap[i/s_NDLLCYC][m] = (m_trigg[thres][i] & m_matOverlap[m]);
1097 // }//end-of-for(m
1098 } // end-of-for(thres
1099 } // end-of-for(i
1100
1101 if (CMAVERSION == 2004) {
1102 //
1103 // build the rise pulse for "m_trigg" (320 MHz trigger output) signals
1104 //
1105 CMAword previousTime = 0;
1106 for (chan = 0; chan < s_nchan[0]; chan++) {
1107 for (thres = 0; thres < s_nthres; thres++) { // loop on the three possible thresholds
1108 for (i = m_nclock - 1; i > 0; i--) { // loop on clock cycles
1109 previousTime = bitstatus(&m_trigg[thres][i - 1], chan);
1110 if (bitstatus(&m_trigg[thres][i], chan) && previousTime) { set_to_0(&m_trigg[thres][i], chan); } // end-of-if(bitstatus
1111 } // end-of-for(i
1112 } // end-of-for(thres
1113 } // end-of-for(chan
1114 } // end-of-if(CMAVERSION
1115 // - - - - - - - - - - -
1116
1117 for (chan = 0; chan < s_nchan[0]; chan++) {
1118 for (thres = 0; thres < s_nthres; thres++) { // loop on the three possible thresholds
1119 for (i = m_nclock - 1; i > 0; i--) { // loop on clock cycles
1120 if (bitstatus(&m_trigg[thres][i], chan)) {
1121 for (ubit16 idead = 1; idead < m_trigDeadTime[chan / s_timeGroupB]; idead++) {
1122 set_to_0(&m_trigg[thres][i + idead], chan);
1123 } // end-of-for(
1124 } // end-of-bitstatus
1125 } // end-of-for(i
1126 } // end-of-for(thres
1127 } // end-of-for(chan
1128
1129 if (CMAVERSION == 2004) {
1130 //
1131 // ...now determine the correspondent "m_trigger" (40 MHz trigger output)
1132 //
1133 for (thres = 0; thres < s_nthres; thres++) { // loop on the three possible thresholds
1134 // reset trigger
1135 for (j = 0; j < m_Nbunch; j++) { m_trigger[thres][j] = 0; } // end-of-for(j
1136 // compute new "m_trigger"
1137 for (i = 0; i < m_nclock; i++) { // loop on clock cycles
1138 BCaddress = ((i + m_BunchPhase) / s_NDLLCYC) + m_BunchOffset;
1139 if (BCaddress >= 0 && BCaddress < m_Nbunch) {
1140 if (m_trigg[thres][i]) m_trigger[thres][BCaddress] = 1;
1141 } // emd-of-if(BCadd
1142 } // end-of-for(i
1143 } // end-of-for(thres
1144 } // end-of-if(CMAVERSION
1145 // - - - - - - - - - - -
1146 //
1147 // find triggers in overlap regions
1148 //
1149 // for(thres=0; thres<s_nthres; thres++){ // loop on the three possible thresholds
1150 thres = m_overlapthres;
1151 for (i = 0; i < m_nclock; i++) { // loop on clock cycles
1152 if (m_trigg[thres][i]) {
1153 for (m = 0; m < 2; m++) { // loop on left-right sides to evaluate overlap
1154 if (!m_triggerOverlapRO[i][m]) { m_triggerOverlapRO[i][m] = (m_trigg[thres][i] & m_matOverlap[m]); }
1155 BCaddress = ((i + m_BunchPhase) / s_NDLLCYC) + m_BunchOffset;
1156 if (BCaddress >= 0 && BCaddress < m_Nbunch) {
1157 if (!m_triggerOverlap[BCaddress][m]) m_triggerOverlap[BCaddress][m] = (m_trigg[thres][i] & m_matOverlap[m]);
1158 } // end-of-if(BCaddress
1159 } // end-of-for(m
1160
1161 } // end-of-for(m_trigg
1162 } // end-of-for(i
1163 //}//end-of-for(thres
1164 //
1165 // normalize m_triggerOverlapRO
1166 //
1167 for (i = 0; i < m_nclock; i++) { // loop on clock cycles
1168 for (m = 0; m < 2; m++) { // normalize to 1 overlap flags
1169 m_triggerOverlapRO[i][m] = m_triggerOverlapRO[i][m] ? 1 : 0;
1170 } // end-of-for(m
1171 } // end-of-for(i
1172 //
1173 // normalize m_triggerOverlap
1174 //
1175 for (i = 0; i < m_Nbunch; i++) { // loop on bunches
1176 for (m = 0; m < 2; m++) { // normalize to 1 overlap flags
1177 m_triggerOverlap[i][m] = m_triggerOverlap[i][m] ? 1 : 0;
1178 } // end-of-for(m
1179 } // end-of-for(i
1180} // end-of-Matrix::coincide
1181//------------------------------------------------------------------------//
1183 ubit16 df = 11;
1184 if (m_matrixDebug & 1 << df) {
1185 cout << "---------------------" << endl << "| Matrix::mask_to_1 |" << endl << "---------------------" << endl;
1186 } // end-of-if(m_matrixDebug&1<<df)
1187
1188 ubit16 i, j, k, l, m;
1189 for (m = 0; m < s_nthres; m++) { // thresholds
1190 for (i = 0; i < 2; i++) { // side address
1191 for (j = 0; j < 2; j++) { // majority address
1192 for (l = 0; l < s_nchan[i]; l++) { // channel
1193 if (bitstatus(&m_channMask1[m][i][j][0], l)) {
1194 for (k = 0; k < m_nclock; k++) { // clock bins
1195 set_to_1(&m_mjori[m][i][j][k][0], l);
1196 } // end-of-for(k
1197 } // end-of-if(m_channMask1
1198 } // end-of-for(l
1199 } // end-of-for(j
1200 } // end-of-for(i
1201 } // end-of-for(m
1202
1203} // end-of-Matrix::mask_to_1
1204//------------------------------------------------------------------------//
1206 ubit16 i, j, k, l;
1208 //
1209 for (i = 0; i < 2; i++) { // loop on both matrix sides
1210 for (j = 0; j < 2; j++) { // loop on both trigger layers
1211 for (k = 0; k < s_nchan[i]; k++) { // loop on all channels
1212 //
1213 // set to 1 the bins in "temp" where signals are "on" for the first time
1214 //
1215 for (l = 0; l < (m_nclock - 1); l++) { // loop on clock bins
1216 ((!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;
1217 } // end-of-for(l
1218 temp[0] = bitstatus(&m_input[i][j][0][0], k);
1219 //
1220 // transfer to "input" the signals in "temp" far enough each other in time
1221 //
1222 sbit16 lastUp = -1;
1223 for (l = 0; l < m_nclock; l++) { // loop on clock bins
1224 //
1225 if (!temp[l]) {
1226 set_to_0(&m_input[i][j][l][0], k);
1227 } else {
1228 //
1229 if ((lastUp < 0) || (l - lastUp) >= m_channDeadT[i][j][k / s_timeGroupB]) {
1230 lastUp = l;
1231 set_to_1(&m_input[i][j][l][0], k);
1232 } else {
1233 set_to_0(&m_input[i][j][l][0], k);
1234 } // end-of-if
1235 } // end-of-if
1236 //
1237 } // end-of-for(l
1238 } // end-of-for(k
1239 } // end-of-for(j
1240 } // end-of-for(i
1241} // end-of-Matrix::deadTime
1242//------------------------------------------------------------------------//
1244 ubit16 df = 12;
1245 ubit16 i, j, l, m;
1246 sbit16 k;
1247 if (m_matrixDebug & 1 << df) {
1248 cout << "-----------------------" << endl << "| Matrix::pulse_width |" << endl << "-----------------------" << endl;
1249 } // end-of-if(m_matrixDebug&1<<df)
1250 //
1251 for (i = 0; i < 2; i++) { // loop on the two Matrix sides
1252 for (j = 0; j < 2; j++) { // loop on both layers
1253 for (l = 0; l < s_nchan[i]; l++) { // loop on all channels
1254 for (k = m_nclock - 1; k >= 0; k--) { // loop on the m_nclock cycles backwards
1255 if (bitstatus(&m_input[i][j][k][0], l)) {
1256 // loop on all time bins to be set to 1
1257 for (m = k + 1; m < k + m_pulseWidth[i][j][l / s_timeGroupB]; m++) {
1258 if (m < m_nclock) {
1259 set_to_1(&m_input[i][j][m][0], l);
1260 } else {
1261 break;
1262 } // end-of-if(m
1263 } // end-of-for(m
1264 } // end-of-if(bitstatus
1265 } // end-of-for(k
1266 } // end-of-for(l
1267 } // end-of-for(j
1268 } // end-of-for(i
1269 //
1270} // end-of-Matrix::pulse_width
1271//------------------------------------------------------------------------//
1273 //
1274 // input none
1275 // returns nothing
1276 //
1277 // Fills the majority registers the 1/2 and 2/2 majority logic
1278 //
1279 // Dynamic scanning of "on" channels has not to be done
1280 // in this first part of the method
1281 //
1282 ubit16 i, j, k, l, n;
1283 ubit16 df = 13; // debug flag address
1284 CMAword buffi[2], buffo[2];
1285 if (m_matrixDebug & 1 << df) {
1286 cout << "-------------------" << endl << "| Matrix::majori |" << endl << "-------------------" << endl;
1287 } // end-of-if(m_matrixDebug&1<<df)
1288 //
1289 // the loop on the CMA sides has to be made as follows:
1290 // 1) side=0 and side=1 as long as the lowpt Matrix is concerned;
1291 // 2) side=1 only as long as the highpt Matrix is concerned.
1292 // To do this, loop from lowhigh address.
1293 //
1294 for (n = 0; n < s_nthres; n++) { // the s_nthres thresholds
1295 for (i = 0; i < 2; i++) { // the two Matrix sides
1296 for (j = 0; j < m_nclock; j++) { // the clock cycles
1297 for (k = 0; k < 2; k++) { // the two words to make 64 bits
1298 // copy layer with address 0,1 to buffi; initialize buffoutput
1299 buffi[k] = m_prepr[n][i][1][j][k];
1300 buffo[k] = 0;
1301 }
1302 shift(&buffi[0], &buffo[0], i);
1303 for (k = 0; k < 2; k++) { // the two words
1304 // 1/2 majority
1305 m_mjori[n][i][0][j][k] = m_prepr[n][i][0][j][k] | m_prepr[n][i][1][j][k];
1306 // 2/2 majority
1307 m_mjori[n][i][1][j][k] = m_prepr[n][i][0][j][k] & buffo[k];
1308 } // end-of-for(k
1309 //
1310 // complete preprocessing...
1311 //
1312 for (l = 0; l < s_nchan[i]; l++) { // loop in the number of channel for this side
1313 if (bitstatus(&m_mjori[n][i][1][j][0], l)) {
1314 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);
1315 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);
1316 } // end-of-if(
1317 } // end-of-for(l
1318 // preprocessing completed
1319 } // end-of-for(j
1320 } // end-of-for(i
1321 } // end-of-for(n
1322} // end-of-method majori
1323//------------------------------------------------------------------------//
1324void Matrix::shift(CMAword *buffi, CMAword *buffo, ubit16 i) const {
1325 //
1326 ubit16 k;
1327 switch (m_localDirec[i]) {
1328 case 1: // n(layer0)-->n(layer1)
1329 for (k = 0; k < 2; k++) { *(buffo + k) = *(buffi + k); }
1330 break;
1331 case 2: // n(0)-->n-1(1)
1332 for (k = 0; k < 2; k++) { *(buffo + k) = *(buffi + k) << 1; }
1333 *(buffo + 1) = (*(buffi + 0) & 0x80000000) ? (*(buffo + 1) | 0x1) : (*(buffo + 1) | 0);
1334 break;
1335 case 3: // case 2 plus case 1
1336 for (k = 0; k < 2; k++) { *(buffo + k) = *(buffi + k) | (*(buffi + k) << 1); }
1337 *(buffo + 1) = (*(buffi + 0) & 0x80000000) ? (*(buffo + 1) | 0x1) : (*(buffo + 1) | 0);
1338 break;
1339 case 4: // n(0)-->n+1(1)
1340 for (k = 0; k < 2; k++) { *(buffo + k) = *(buffi + k) >> 1; }
1341 *(buffo + 0) = (*(buffi + 1) & 0x1) ? (*(buffo + 0) | 0x80000000) : (*(buffo + 0) | 0);
1342 break;
1343 case 5: // case 4 plus case 1
1344 for (k = 0; k < 2; k++) { *(buffo + k) = *(buffi + k) | (*(buffi + k) >> 1); }
1345 *(buffo + 0) = (*(buffi + 1) & 0x1) ? (*(buffo + 0) | 0x80000000) : (*(buffo + 0) | 0);
1346 break;
1347 case 6: // case 4 plus case 2
1348 for (k = 0; k < 2; k++) { *(buffo + k) = (*(buffi + k) >> 1) | (*(buffi + k) << 1); }
1349 *(buffo + 0) = (*(buffi + 1) & 0x1) ? (*(buffo + 0) | 0x80000000) : (*(buffo + 0) | 0);
1350 *(buffo + 1) = (*(buffi + 0) & 0x80000000) ? (*(buffo + 1) | 0x1) : (*(buffo + 1) | 0);
1351 break;
1352 case 7: // case 4 plus case 2 pluse case 1
1353 for (k = 0; k < 2; k++) { *(buffo + k) = *(buffi + k) | (*(buffi + k) >> 1) | (*(buffi + k) << 1); }
1354 *(buffo + 0) = (*(buffi + 1) & 0x1) ? (*(buffo + 0) | 0x80000000) : (*(buffo + 0) | 0);
1355 *(buffo + 1) = (*(buffi + 0) & 0x80000000) ? (*(buffo + 1) | 0x1) : (*(buffo + 1) | 0);
1356 break;
1357 default:
1358 cout << " Matrix::shift -- m_localDirec[" << i << "]=" << m_localDirec[i] << " not expected; m_localDirec forced to be 1 "
1359 << endl;
1360 for (k = 0; k < 2; k++) { *(buffo + k) = *(buffi + k); }
1361 }
1362 //
1363 // correct patter in *(buffo+1) in case side of Matrix (="i" in this method)
1364 // is = 1
1365 //
1366 if (!i) *(buffo + 1) = 0;
1367 //
1368} // end-of-Matrix::shift(buff0, buffi, buffo)
1369//------------------------------------------------------------------------//
1371 //
1372 // Dynamic scanning of "on" channels has not to be done
1373 // in this first part of the method
1374 //
1375 ubit16 df = 14;
1376 ubit16 nup, first, i, j, k, l;
1377 first = 0;
1378 if (m_matrixDebug & 1 << df) {
1379 cout << "------------------------" << endl << "| matrix: declustering |" << endl << "------------------------" << endl;
1380 } // end-of-if(m_matrixDebug&1<<df)
1381 //
1382 // loop on m_input data
1383 //
1384 for (i = 0; i < 2; i++) { // loop on the two sides
1385 for (j = 0; j < 2; j++) { // loop on the two layers
1386 for (k = 0; k < m_nclock; k++) { // loop on the time bins
1387 nup = 0; // counter of consecutive "on" channels
1388 for (l = 0; l < s_nchan[i]; l++) { // loop on the Matrix channels
1389 if (bitstatus(&m_input[i][j][k][0], l)) {
1390 nup++;
1391 if (nup == 1) first = l;
1392 } // end-of-if(bitstatus
1393 if (!bitstatus(&m_input[i][j][k][0], l) || (l == (s_nchan[i] - 1))) {
1394 if (nup) {
1395 reduce(i, j, k, 0, nup, first);
1396 nup = 0;
1397 } // end-of-if(nup
1398 } // end-of-if(bitstatus
1399 } // end-of-for(l
1400 } // end-of-for(k
1401 } // end-of-for(j
1402 } // end-of-for(i
1403} // end-of-method declustering
1404//------------------------------------------------------------------------//
1405void Matrix::reduce(ubit16 ia, ubit16 ja, ubit16 ka, ubit16 la, ubit16 nup, ubit16 first) {
1406 //
1407 // input ia, ja, ka, la indices of the Matrix data
1408 // nup cluster size = number of consecutive channels on
1409 // first address of the first channel on in the cluster (from 0)
1410 // returns nothing
1411 //
1412 // It copies into m_prepr the channels from input selected by the
1413 // declustering logic.
1414 //
1415 //
1416 ubit16 ncop, i, j, na;
1417 ubit16 df = 15;
1418 ncop = 0;
1419 j = 0;
1420 if (m_matrixDebug & 1 << df) {
1421 cout << " --------------------" << endl
1422 << " | Matrix::reduce |" << endl
1423 << " --------------------" << endl
1424 << " nup= " << nup << " first " << first << endl;
1425 } // end-of-if(m_matrixDebug&1<<df)
1426 //
1427 // analyse nup value and apply the cluster reduction according to it.
1428 // j is the first channel of the cluster retained after declustering;
1429 // ncop is the cluster size after declustering
1430 //
1431 if (nup <= 2) {
1432 j = first;
1433 ncop = nup;
1434 } else if (nup == 3) {
1435 j = first + 1;
1436 ncop = 1;
1437 } else if (nup == 4) {
1438 j = first + 1;
1439 ncop = 2;
1440 } else if (nup > 4) {
1441 j = first + 2;
1442 ncop = nup - 4;
1443 } // end-of-if
1444 if (m_matrixDebug & 1 << df) { cout << " j= " << j << " ncop= " << ncop << endl; } // end-of-if(m_matrixDebug&1<<df)
1445 //
1446 // copy the reduced cluster into the "s_nthres" m_prepr registers
1447 //
1448 for (na = 0; na < s_nthres; na++) {
1449 for (i = j; i < j + ncop; i++) { // loop on each element of the reduced cluster
1450 set_to_1(&m_prepr[na][ia][ja][ka][la], i);
1451 } // end-of-for(i
1452 } // end-of-for(na
1453} // end-of-reduce
1454//------------------------------------------------------------------------//
1456 ubit16 i, j, k;
1457 //
1458 // fill k-pattern
1459 //
1460 for (j = 0; j < m_nclock; j++) { // loop on the clock bins
1462 k_readout[j] = m_trigg[m_toreadout][j];
1463 } // end-of-for(j
1464 //
1465 // find the highest satisfied threshold;
1466 // identify Bunch Crossing and put it in BCID.
1467 //
1468 for (j = 0; j < m_Nbunch; j++) {
1469 for (i = 0; i < s_nthres; i++) {
1470 if (m_trigger[i][j]) {
1471 m_highestth[j] = i + 1; // put threshold address+1 (correct threshold value)
1472 if (m_BCID < 0)
1473 m_BCID = j // local Bunch Crossing IDentifier
1474 + m_thisBC; // re-syncronize to absolute BCID
1475 // - m_BCzero; // remove offset used
1476 } // end-of-if(m_trigger
1477 } // end-of-for(i
1478 } // end-of-for(j
1479 //
1480 // Trigger in Overlapping channels is reported in m_triggerOverlap
1481 //
1482 for (j = 0; j < m_Nbunch; j++) { m_overlap[j] = m_triggerOverlap[j][0] + 2 * m_triggerOverlap[j][1]; } // end-of-for(j
1483 //
1484 // find the highest satisfied threshold for ReadOut pourposes;
1485 //
1486 for (j = 0; j < m_nclock; j++) { // loop on the clock bins
1487 for (i = 0; i < s_nthres; i++) { // loop on thresholds
1488 for (k = 0; k < s_nchan[0]; k++) { // loop on channels (pivot side)
1489 if (m_trigg[i][j] & (1 << k)) highestthRO[j] = i + 1;
1490 } // end-of-for(k
1491 } // end-of-for(i
1492 } // end-of-for(j
1493 //
1494 //
1495 // Trigger in Overlapping channels is reported in m_triggerOverlapRO
1496 //
1497 for (j = 0; j < m_nclock; j++) { overlapRO[j] = m_triggerOverlapRO[j][0] + 2 * m_triggerOverlapRO[j][1]; } // end-of-for(j
1498 //
1499} // end-of-Matrix::makeOut
1500//------------------------------------------------------------------------//
1502 //
1503 int df = 16;
1504 const ubit16 maxchan = 100;
1505 const ubit16 maxtimes = 1000;
1506 ubit16 i, j, l;
1507 ubit16 IJ[maxtimes][4] = {{0}};
1508 ubit16 channels[maxtimes][4][maxchan] = {{{0}}};
1509 float times[maxtimes] = {0};
1510 char plane[4][3];
1511 const float timeOffsetHit = 114.675;
1512 //
1513 rpcdata *rpcpnt;
1514 float timemin;
1515 //
1516 strcpy(plane[0], "I0");
1517 strcpy(plane[1], "I1");
1518 strcpy(plane[2], "J0");
1519 strcpy(plane[3], "J1");
1520 if (m_matrixDebug & 1 << df) {
1521 cout << "-------------------------------" << endl
1522 << "| Matrix::makeTestPattern |" << endl
1523 << "-------------------------------" << endl;
1524 } // end-of-if(m_matrixDebug&1<<df)
1525 //
1526 int ntimes = 0;
1527 ubit16 completed = 0;
1528 //
1529 // first reset the marker flags
1530 //
1531 for (i = 0; i < 2; i++) {
1532 rpcpnt = m_datarpc[i];
1533 while (rpcpnt) {
1534 rpcpnt->mark = 0;
1535 rpcpnt = rpcpnt->next;
1536 } // end-of-while(rpcpnt
1537 } // end-of-for(i
1538 //
1539 while (!completed) {
1540 completed = 1;
1541 timemin = 999999999.;
1542 for (i = 0; i < 2; i++) { // "i" is the CMA side address
1543 rpcpnt = m_datarpc[i];
1544 while (rpcpnt) {
1545 if (rpcpnt->time < timemin && !rpcpnt->mark) {
1546 timemin = rpcpnt->time;
1547 completed = 0;
1548 } // end-of-if(rpcnt
1549 rpcpnt = rpcpnt->next;
1550 } // end-of-while(rpcpnt)
1551 } // end-of-for(i
1552 if (!completed) {
1553 if (ntimes < maxtimes) ntimes += 1;
1554 times[ntimes - 1] = timemin;
1555 for (i = 0; i < 2; i++) { // "i" is the CMA side address
1556 rpcpnt = m_datarpc[i];
1557 while (rpcpnt) {
1558 if (rpcpnt->time == timemin) {
1559 rpcpnt->mark = 1;
1560 if (IJ[ntimes - 1][rpcpnt->layer + 2 * i] < maxchan) { IJ[ntimes - 1][rpcpnt->layer + 2 * i] += 1; }
1561 channels[ntimes - 1][rpcpnt->layer + 2 * i][IJ[ntimes - 1][rpcpnt->layer + 2 * i] - 1] = rpcpnt->stripadd;
1562 } // end-of-if(rpcnt
1563 rpcpnt = rpcpnt->next;
1564 } // end-of-while(rpcpnt)
1565 } // end-of-for(i
1566 } // end-of-if(!completed
1567 } // end-of-while(!completed)
1568 //
1569 //
1570 // open output file
1571 //
1572 ofstream vhdlinput;
1573 vhdlinput.open("k-trigger.output", ios::app);
1574 if (!vhdlinput) {
1575 cout << " File for vhdl analysis not opened. " << endl << " ==================================" << endl << endl;
1576 } else {
1577 if (m_matrixDebug & 1 << df) {
1578 cout << " File for vhdl analysis correctly opened" << endl << endl;
1579 } // end-of-if(m_matrixDebug&1<<df)
1580 } // end-of-if(!vhdlinput
1581 if (mode) {
1582 vhdlinput << " RUN " << m_run << " EVENT " << m_event << " WINDOW " << m_Nbunch;
1583 vhdlinput << " LINES " << (ntimes + ktimes) << std::endl;
1584 } // end-of-if(mode
1585 for (l = 0; l < ntimes; l++) {
1586 vhdlinput << " TIME " << times[l] + timeOffsetHit << " ";
1587 for (i = 0; i < 4; i++) {
1588 vhdlinput << plane[i][0] << plane[i][1] << " " << IJ[l][i] << " ";
1589 for (j = 0; j < IJ[l][i]; j++) { vhdlinput << channels[l][i][IJ[l][i] - 1 - j] << " "; } // end-of-for(j
1590 } // end-of-for(i
1591 vhdlinput << std::endl;
1592 } // end-of-for(l
1593 //
1594 vhdlinput.close();
1595} // end-of-makeTestPattern
1596//------------------------------------------------------------------------//
1598 // int df=17;
1599 const float timeOffsetKPa = 168.125;
1600 const float timeOffsetThr = 210.500;
1601 ubit16 i, l;
1602 CMAword bit;
1603 ubit16 chanHistory[32] = {0};
1604 const ubit16 maxchan = 100;
1605 const ubit16 maxtimes = m_nclock;
1606 ubit16 ntimes, newtime;
1607 ubit16 nchannels[s_NDLLCYC*8][2][2], channels[s_NDLLCYC*8][2][2][maxchan];
1608 float time, times[s_NDLLCYC*8]{0};
1609 //
1610 // trigger registers: k-trigger (historically was k-pattern)
1611 //
1612 ntimes = 0;
1613 for (i = 0; i < m_nclock; i++) { nchannels[i][0][0] = 0; }
1614 time = (float)m_thisBC * s_BCtime - ((float)(m_BCzero * s_NDLLCYC)) * s_DLLtime;
1615 for (i = 0; i < m_nclock; time += s_DLLtime, i++) {
1616 bit = 1;
1617 newtime = 1;
1618 for (l = 0; l < s_nchan[0]; l++) {
1619 if (m_k_pattern[i] & bit) {
1620 if (!chanHistory[l]) {
1621 if (newtime) {
1622 if (ntimes < maxtimes) ntimes += 1;
1623 times[ntimes - 1] = time;
1624 } // end-of-if(newtime
1625 if (nchannels[ntimes - 1][0][0] < maxchan) nchannels[ntimes - 1][0][0] += 1;
1626 channels[ntimes - 1][0][0][nchannels[ntimes - 1][0][0] - 1] = l;
1627 newtime = 0;
1628 } // end-of-if(!chanHistory
1629 chanHistory[l] = 1;
1630 } else { // if(m_k_pattern
1631 chanHistory[l] = 0;
1632 } // end-of-if(m_k_pattern
1633 bit = bit << 1;
1634 } // end-of-for(l
1635 } // end-of-for(i
1636
1637 ubit16 nthresPass, thresPass[8], overlPass[8], BCidentifier[8];
1638 nthresPass = 0;
1639 for (i = 0; i < m_Nbunch; i++) {
1640 if (m_highestth[i]) {
1641 thresPass[nthresPass] = m_highestth[i];
1642 overlPass[nthresPass] = m_overlap[i];
1643 BCidentifier[nthresPass] = i;
1644 nthresPass += 1;
1645 }
1646 }
1647 makeTestPattern(1, ntimes + 2 * nthresPass);
1648 //
1649 // open output file
1650 //
1651 ofstream out_k_trigger;
1652 out_k_trigger.open("k-trigger.output", ios::app);
1653 //
1654 // code to print out m_k_pattern
1655 //
1656 for (i = 0; i < ntimes; i++) {
1657 out_k_trigger << " TIME " << times[i] + timeOffsetKPa << " K ";
1658 out_k_trigger << nchannels[i][0][0] << " ";
1659 for (l = 0; l < nchannels[i][0][0]; l++) { out_k_trigger << channels[i][0][0][l] << " "; } // end-of-for(l
1660 out_k_trigger << endl;
1661 } // end-of-for(i
1662 //
1663 if (nthresPass) {
1664 for (i = 0; i < nthresPass; i++) {
1665 out_k_trigger << " TIME " << BCidentifier[i] * 25. + timeOffsetThr;
1666 out_k_trigger << " THR " << thresPass[i] << endl;
1667 if (overlPass[i]) {
1668 out_k_trigger << " TIME " << BCidentifier[i] * 25. + timeOffsetThr;
1669 out_k_trigger << " OVL " << overlPass[i] << std::endl;
1670 }
1671 }
1672 }
1673 //
1674 out_k_trigger.close();
1675 //
1676} // end-of-makeOutPattern
1677//------------------------------------------------------------------------//
1679 //
1680 // input: i threshold address
1681 // *arr pointer to bidimen. array
1682 //
1683 // returns the number of possible configurations compatible with the
1684 // required majority pointed by majorities[i]
1685 //
1686 // Data *arr(k) and *arr(k+1) give the majority addresses for the side-x
1687 // and side-y respectevely.
1688 //
1689 ubit16 nconf = 0;
1690 //
1691 // cout<<"lowhig="<<m_lowhigh<< "majorities= "<<m_majorities[0]
1692 // <<" "<< m_majorities[1]<<" "<<m_majorities[2]<<endl;
1693 //
1694 switch (m_lowhigh) {
1695 case 0: // low-pt trigger matrix
1696 switch (m_majorities[i]) { // select the required majority for each thresh.;
1697 case 0: // 1-out-of-4 majority: no implementation yet
1698 // gives 1/2 in I OR 1/2 in J
1699 nconf = 0;
1700 break;
1701 case 1: // 2-out-of-4 majority
1702 nconf = 1;
1703 *(arr + 0) = 0;
1704 *(arr + 1) = 0;
1705 break;
1706 case 2: // 3-out-of-4 majority
1707 nconf = 2;
1708 *(arr + 0) = 0;
1709 *(arr + 1) = 1;
1710 *(arr + 2) = 1;
1711 *(arr + 3) = 0;
1712 break;
1713 case 3: // 4-out-of-4 majority
1714 nconf = 1;
1715 *(arr + 0) = 1;
1716 *(arr + 1) = 1;
1717 break;
1718 default: throw std::runtime_error("Matrix::config: the majority " + std::to_string(m_majorities[i]) + " is unforeseen");
1719 }
1720 break;
1721 case 1: // high-pt trigger matrix
1722 // high-pt trigger
1723 switch (m_majorities[i]) {
1724 case 1: // 1-out-of-2 majority
1725 nconf = 1;
1726 *(arr + 0) = 0;
1727 *(arr + 1) = 0;
1728 break;
1729 case 2: // 2-out-of-2 majority
1730 nconf = 1;
1731 *(arr + 0) = 0;
1732 *(arr + 1) = 1;
1733 break;
1734 default: throw std::runtime_error("Matrix::config: the majority " + std::to_string(m_majorities[i]) + " is unforeseen");
1735 }
1736 break;
1737 default: throw std::runtime_error("Matrix::config: lowhighpt " + std::to_string(m_lowhigh) + " is unforeseen");
1738 }
1739 return nconf;
1740} // end-of-method-config
1741//------------------------------------------------------------------------//
1742int Matrix::getSubsystem() const { return m_subsystem; }
1743//------------------------------------------------------------------------//
1745//------------------------------------------------------------------------//
1746int Matrix::getSector() const { return m_sector; }
1747//------------------------------------------------------------------------//
1748int Matrix::getPad() const { return m_pad; }
1749//------------------------------------------------------------------------//
1750int Matrix::getLowHigh() const { return m_lowhigh; }
1751//------------------------------------------------------------------------//
1752int Matrix::getAddress0() const { return m_address[0]; }
1753//------------------------------------------------------------------------//
1754int Matrix::getAddress1() const { return m_address[1]; }
1755//------------------------------------------------------------------------//
1756int Matrix::getLocalAdd() const { return m_localadd; }
1757//------------------------------------------------------------------------//
1758ubit16 Matrix::getOutputThres(ubit16 bunch) const { return m_highestth[bunch]; } // end-of-ubit16-getOutput
1759//------------------------------------------------------------------------//
1760ubit16 Matrix::getOutputOverl(ubit16 bunch) const { return m_overlap[bunch]; } // end-of-ubit16-getOutput
1761//------------------------------------------------------------------------//
1762sbit16 Matrix::getBunchPhase() const { return m_BunchPhase; } // end-of-ubit16-getBunchPhase
1763//------------------------------------------------------------------------//
1764sbit16 Matrix::getBunchOffset() const { return m_BunchOffset; } // end-of-ubit16-getBunchOffset
1765//------------------------------------------------------------------------//
1766void Matrix::set_to_1(CMAword *p, sbit16 channel) const {
1767 CMAword j{1};
1768 std::array<ubit16, 2> i = inds(channel);
1769 if (!(channel < 0)) {
1770 *(p + i[0]) = *(p + i[0]) | j << i[1];
1771 } else {
1772 throw std::out_of_range("Matrix::set_to_1: channel is negative; channel=" + std::to_string(channel));
1773 } // end-of-if(!(channel<0
1774} // end-of-Matrix::set_to_1
1775//----------------------------------------------------------------------//
1776void Matrix::set_to_0(CMAword *p, sbit16 channel) const {
1777 CMAword j{1};
1778 std::array<ubit16, 2> i = inds(channel);
1779 if (!(channel < 0)) {
1780 *(p + i[0]) = *(p + i[0]) & ~(j << i[1]);
1781 } else {
1782 throw std::out_of_range("Matrix::set_to_1: channel is negative; channel=" + std::to_string(channel));
1783 } // end-of-if(!(channel<0
1784} // end-of-Matrix::set_to_1
1785
1786//----------------------------------------------------------------------//
1787void Matrix::wind() const {
1788 sbit16 i, j;
1789 cout << "-----------------------" << endl
1790 << "| Matrix::wind |" << endl
1791 << "-----------------------" << endl
1792 << " Matrix Roads " << endl;
1793 for (i = 0; i < s_nthres; i++) {
1794 for (j = 0; j < s_nchan[0]; j++) {
1795 cout << " thres. " << i << " channel "
1796 << j
1797 // <<" Road0 "<<hex<<(*(m_roads+32*2*i+2*j+0))<<dec
1798 // <<" Road1 "<<hex<<(*(m_roads+32*2*i+2*j+1))<<dec<<endl;
1799 << " Road0 " << hex << (m_trigRoad[i][j][0]) << dec << " Road1 " << hex << (m_trigRoad[i][j][1]) << dec << endl;
1800 }
1801 }
1802 cout << " majorities: " << endl;
1803 for (i = 0; i < 3; i++) { cout << m_majorities[i] << " " << endl; }
1804 cout << endl
1805 << " number of overlapping ' low' channels: " << m_matOverlap[0] << endl
1806 << " number of overlapping 'high' channels: " << m_matOverlap[1] << endl;
1807 for (i = 0; i < s_nchan[0]; i++) { cout << " channel " << i << " in coincidence with " << m_diagonal[i] << endl; } // end-of-for(i
1808} // end-of-method-wind
1809//----------------------------------------------------------------------//
1810void Matrix::display() const {
1811 ubit16 i;
1812 ubit16 df = 19;
1813 rpcdata *rpcpnt;
1814 //
1815 // if(this) {
1816 cout << "=======================" << endl << "|| Matrix Display ||" << endl << "=======================" << endl << endl;
1818
1819 cout << endl << " All raw data " << endl;
1820 for (i = 0; i < 2; i++) {
1821 cout << " Matrix Side is " << i << endl;
1822 rpcpnt = m_datarpc[i];
1823 while (rpcpnt) {
1824 cout << " Layer= " << rpcpnt->layer << " stripadd= " << rpcpnt->stripadd << " time= " << rpcpnt->time
1825 << " mask= " << rpcpnt->masked << " BC= " << rpcpnt->BC << " DLL= " << rpcpnt->DLL << " delay= " << rpcpnt->delay << endl;
1826 rpcpnt = rpcpnt->next;
1827 } // end-of-while(rpcpnt)
1828 } // end-of-for(i
1829 //
1830 if (m_matrixDebug & 1 << (df + 0)) {
1831 cout << " Display Matrix Input " << endl;
1832 disp_CMAreg(0); // display the input registers
1833 }
1834 //
1835 //
1836 if (m_matrixDebug & 1 << (df + 1)) {
1837 cout << " Display Matrix Preprocessing " << endl;
1838 disp_CMAreg(1); // display the prepro registers
1839 }
1840 //
1841 if (m_matrixDebug & 1 << (df + 2)) {
1842 cout << " Display Matrix Majority " << endl;
1843 disp_CMAreg(2); // display the majority registers
1844 }
1845 //
1846 if (m_matrixDebug & 1 << (df + 3)) {
1847 cout << " Display Trigger " << endl;
1848 disp_CMAreg(3); // display the trigger registers
1849 }
1850 //
1851 //} else {
1852 // cout<<"======================="<<endl
1853 // <<"|| Matrix EMPTY ||"<<endl
1854 // <<"======================="<<endl;
1855 //}//end-of-Matrix::display
1856} // end-of-method display
1857//------------------------------------------------------------------------//
1859 cout << " Matrix Attributes: " << endl
1860 << " Subsystem " << m_subsystem << "; Projection " << m_projection << "; Sector " << m_sector << "; Pad " << m_pad << "; LowHig "
1861 << m_lowhigh << "; addresses: " << m_address[0] << " " << m_address[1] << endl;
1862} // end-of-Matrix::attributes
1863//------------------------------------------------------------------------//
1865 //
1866 // display the CMA registers
1867 //
1868 ubit16 i, j, k;
1869 if (id < 2) {
1870 for (i = 0; i < 2; i++) { // loop on the two Matrix sides
1871 cout << " CMA Side (0=side-x; 1=side-y) " << i << endl;
1872 for (j = 0; j < 2; j++) { // loop on the two Matrix layers
1873 switch (id) {
1874 case 0:
1875 cout << " Layer " << j << endl;
1876 dispRegister(&m_input[i][j][0][0], i);
1877 break;
1878 case 1:
1879 cout << " Layer " << j << endl;
1880 dispRegister(&m_prepr[0][i][j][0][0], i);
1881 break;
1882 default: cout << " Matrix::disp_CMAreg id value " << id << " not foreseen " << endl;
1883 } // end-of-switch
1884 } // end-of-for(j
1885 } // end-of-for(i
1886
1887 } else {
1888 switch (id) {
1889 case 2:
1890 for (i = 0; i < s_nthres; i++) { // loop on threshold
1891 cout << " Threshold address " << i << endl;
1892 for (j = 0; j < 2; j++) { // loop on matrix sides
1893 cout << " CMA Side (0=side-x; 1=side-y) " << j << endl;
1894 for (k = 0; k < 2; k++) { // loop on majority types
1895 cout << " Majority type (0=1/2; 1=2/2) " << k << endl;
1896 dispRegister(&m_mjori[i][j][k][0][0], j);
1897 } // end-of-for(k
1898 } // end-of-for(j
1899 } // end-of-for(i
1900 break;
1901 case 3:
1902 for (i = 0; i < s_nthres; i++) { // loop on the three thresholds
1903 cout << " Trigger Threshold address " << i << endl;
1904 dispTrigger(&m_trigg[i][0]);
1905 } // end-of-for(i
1906 cout << " ReadOut Buffer " << endl;
1907 dispRegister(&rodat[0][0][0][0], 0);
1908 break;
1909 default: cout << " Matrix::disp_CMAreg id value " << id << " not foreseen " << endl;
1910 } // end-of-switch (id)
1911
1912 } // end-of-if(id
1913 cout << " " << endl;
1914} // end-of-Matrix::disp_CMAreg
1915//------------------------------------------------------------------------//
1916void Matrix::dispRegister(const CMAword *p, ubit16 side) const {
1917 ubit16 n, j, k;
1918 //
1919 // allocation for oststream strdisp
1920 //
1921 std::ostringstream strdisp;
1922 n = (s_nchan[side] - 1) / s_wordlen + 1;
1923 strdisp << " ";
1924
1925 for (j = 0; j < s_nchan[side]; j += 2) { strdisp << " " << j % 10; } // end-of-for
1926 strdisp << " " << endl;
1927 for (j = 0; j < m_nclock; j++) { // loop on the m_nclock cycles
1928 strdisp << " " << j % 10 << " ";
1929 for (k = 0; k < n; k++) { // loop on the buffer words
1930 dispBinary(p + k + 2 * j, strdisp);
1931 } // end-of-for(k
1932 strdisp << " " << endl;
1933
1934 } // end-of-for(j
1935
1936 cout << strdisp.str() << endl;
1937} // end-of-Matrix::dispRegister
1938//------------------------------------------------------------------------//
1939void Matrix::dispTrigger(const CMAword *p) const {
1940 ubit16 j;
1941 //
1942 // allocation for oststream strdisp
1943 //
1944
1945 std::ostringstream strdisp;
1946 strdisp << " ";
1947
1948 for (j = 0; j < s_nchan[0]; j += 2) { strdisp << " " << j % 10; } // end-of-for
1949 strdisp << " " << endl;
1950 for (j = 0; j < m_nclock; j++) { // loop on the m_nclock cycles
1951 strdisp << " " << j % 10 << " ";
1952 dispBinary(p + j, strdisp);
1953 strdisp << " " << endl;
1954 } // end-of-for(j
1955
1956 cout << strdisp.str() << endl;
1957} // end-of-Matrix::dispTrigger
1958//------------------------------------------------------------------------//
1959void Matrix::dispBinary(const CMAword *p, std::ostringstream &strdisp) const {
1960 ubit16 i;
1961 CMAword j;
1962 j = 1;
1963 for (i = 0; i < s_wordlen; i++) {
1964 if ((*p) & j) {
1965 strdisp << "|";
1966 } else {
1967 strdisp << ".";
1968 } // end-of-if
1969 j = j << 1;
1970 } // end-of-for(
1971} // end-of-Matrix::dispBinary
1972//------------------------------------------------------------------------//
1973void Matrix::dispWind() const {
1974 for (ubit16 i = 0; i < s_nthres; i++) { dispWind(i); }
1975} // end-of-dispWind
1976//------------------------------------------------------------------------//
1977void Matrix::dispWind(ubit16 thres) const {
1978 std::ostringstream strdisp;
1979
1980 strdisp << endl
1981 << " =========================" << endl
1982 << " = =" << endl
1983 << " = Matrix::dispWind =" << endl
1984 << " = Threshold address " << thres << " =" << endl
1985 << " = =" << endl
1986 << " =========================" << endl
1987 << endl;
1988 //
1989 for (sbit16 j = s_nchan[1] - 1; j >= 0; j--) {
1990 ubit16 ad1 = j / 32;
1991 ubit16 ad2 = j % 32;
1992 if (j < 10) {
1993 strdisp << " " << j << " ";
1994 } else {
1995 strdisp << j << " ";
1996 }
1997 for (ubit16 k = 0; k < s_nchan[0]; k++) {
1998 if ((m_trigRoad[thres][k][ad1]) & (1 << ad2)) {
1999 strdisp << "*";
2000 } else {
2001 strdisp << ".";
2002 } // end-of-if
2003 } // end-of-for(k
2004 strdisp << " " << endl;
2005 } // end-of-for(j
2006 strdisp << " " << endl;
2007 strdisp << " 00000000001111111111222222222233" << endl << " 01234567890123456789012345678901" << endl;
2008 //
2009 cout << strdisp.str() << endl;
2010} // end-of-dispWind
2011
2012//----------------------------------------------------------------------------//
2013ubit16 Matrix::char2int(const char *str, CMAword the32[2]) {
2014 ubit16 outflag = 0;
2015 the32[0] = 0;
2016 the32[1] = 0;
2017 ubit16 stringLength = strlen(str);
2018 if (stringLength > 16) {
2019 outflag = 1;
2020 } else {
2021 for (ubit16 i = 0; i < stringLength; i++) {
2022 // cout<<" Reading character "<<*(str+stringLength-1-i)<<endl;
2023 if (*(str + stringLength - 1 - i) == '0')
2024 the32[i / 8] = the32[i / 8] + 0;
2025 else if (*(str + stringLength - 1 - i) == '1')
2026 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 1;
2027 else if (*(str + stringLength - 1 - i) == '2')
2028 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 2;
2029 else if (*(str + stringLength - 1 - i) == '3')
2030 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 3;
2031 else if (*(str + stringLength - 1 - i) == '4')
2032 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 4;
2033 else if (*(str + stringLength - 1 - i) == '5')
2034 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 5;
2035 else if (*(str + stringLength - 1 - i) == '6')
2036 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 6;
2037 else if (*(str + stringLength - 1 - i) == '7')
2038 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 7;
2039 else if (*(str + stringLength - 1 - i) == '8')
2040 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 8;
2041 else if (*(str + stringLength - 1 - i) == '9')
2042 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 9;
2043 else if (*(str + stringLength - 1 - i) == 'a' || *(str + stringLength - 1 - i) == 'A')
2044 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 10;
2045 else if (*(str + stringLength - 1 - i) == 'b' || *(str + stringLength - 1 - i) == 'B')
2046 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 11;
2047 else if (*(str + stringLength - 1 - i) == 'c' || *(str + stringLength - 1 - i) == 'C')
2048 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 12;
2049 else if (*(str + stringLength - 1 - i) == 'd' || *(str + stringLength - 1 - i) == 'D')
2050 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 13;
2051 else if (*(str + stringLength - 1 - i) == 'e' || *(str + stringLength - 1 - i) == 'E')
2052 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 14;
2053 else if (*(str + stringLength - 1 - i) == 'f' || *(str + stringLength - 1 - i) == 'F')
2054 the32[i / 8] = the32[i / 8] + (intPow(16, i % 8)) * 15;
2055 else
2056 outflag = 2;
2057 } // end-of-for
2058 }
2059
2060 // if(outflag) {
2061 // the32[0]=0;
2062 // the32[1]=1;
2063 // } else {
2064 // CMAword temp = the32[1];
2065 // the32[1]=the32[0];
2066 // the32[0]=temp;
2067 // }
2068 return outflag;
2069} // end-of-char2int
2070//----------------------------------------------------------------------------//
2071CMAword Matrix::intPow(const ubit16 base, const ubit16 expo) const {
2072 CMAword output = 1;
2073 if (expo) {
2074 for (ubit16 i = 1; i <= expo; i++) { output = output * base; } // end-of-for
2075 }
2076 return output;
2077} // 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
STL namespace.
int run(int argc, char *argv[])