ATLAS Offline Software
Loading...
Searching...
No Matches
MatrixReadOut.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <cstring>
8#include <fstream>
9#include <iomanip>
10
11
12using namespace std;
13
14//----------------------------------------------------------------------------//
15MatrixReadOut::MatrixReadOut(Matrix *m, ubit16 FEevent, uint NOBXS, DataVersion ver) : BaseObject(Hardware, "MatrixReadOut") {
16 //
17 // Constructor used by the simulation program
18 //
19 // m the pointer to the object "Matrix"
20 // FEevent FrontEnd Event identifier
21 //
22 m_data_version = ver;
23 initialize(NOBXS);
24 FEevent = FEevent % 512;
25 m_FEL1ID = FEevent;
26 m_CM = m;
28 m_BS = 0;
29} // end-of-MatrixReadOut::MatrixReadOut
30//----------------------------------------------------------------------------//
31MatrixReadOut::MatrixReadOut(ubit16 FEevent, uint NOBXS, DataVersion ver) : BaseObject(Hardware, "MatrixReadOut") {
32 //
33 // Constructor used by an external user
34 // the readout words are supplied by the methods:
35 // "writeHeader" , "writeSubHeader" , "writeCMABody" and "writ".
36 //
37 // FEevent FrontEnd Event identifier
38 //
39 m_data_version = ver;
40 initialize(NOBXS);
41 m_MROS.setInit();
42 FEevent = FEevent % 512;
43 m_FEL1ID = FEevent;
44 m_CM = 0;
45 m_BS = 0;
46 m_myBoss = 0;
48} // end-of-MatrixReadOut::MatrixReadOut
49//----------------------------------------------------------------------------//
50MatrixReadOut::MatrixReadOut(ubit16 *v, ubit16 numWords, uint NOBXS, DataVersion ver) : BaseObject(Hardware, "MatrixReadOut") {
51 //
52 // Constructor used by an external user
53 //
54 // v pointer to the CM readout fragment (16-bit words)
55 // numWords number of words in the readout fragment
56 //
57 m_data_version = ver;
58 initialize(NOBXS);
59 char field;
60 m_CM = 0;
61 m_BS = v;
62 m_myBoss = 0;
64
65 //
66 m_numberOfWordsInFrag = numWords;
67 ubit16 nWordsMax = 100;
68 //
69 ubit16 nWord = 0;
70 while (nWord < nWordsMax && !m_checkFooterNum) {
71 m_MROS.decodeFragment(*(m_BS + nWord), field);
72 //
73 // Fragment Scanning ...
74 //
75 // cout<<" field= "<<field<<endl;
76 if (field == 'B') {
77 //
78 // this is a Body word
79 //
80 makeNewHit(*(m_BS + nWord));
81 } else {
82 //
83 // this is a control word
84 //
85 if (field == 'H') {
86 //
87 // Header
88 //
89 m_Header = *(m_BS + nWord);
91 m_checkHeaderPos = nWord + 1;
92 } else if (field == 'S') {
93 //
94 // Subheader
95 //
96 m_SubHeader = *(m_BS + nWord);
98 m_checkSubHeaderPos = nWord + 1;
99 } else if (field == 'F') {
100 //
101 // Footer
102 //
103 m_Footer = *(m_BS + nWord);
105 m_checkFooterPos = nWord + 1;
106 m_checkCR = checkCRC8(*(m_BS + nWord));
107 } else {
108 //
109 // Word code unknown
110 //
112 } // end-if
113 } // end-if
114 nWord++;
115 } // end-of-while
116} // end-of-MatrixReadOut::MatrixReadOut
117//----------------------------------------------------------------------------//
119 //
120 // Copy Constructor
121 //
123
124 m_BunchFrom = MROOrig.m_BunchFrom;
125 m_BunchTo = MROOrig.m_BunchTo;
126 m_FEL1ID = MROOrig.m_FEL1ID;
127 m_Header = MROOrig.m_Header;
128 m_Footer = MROOrig.m_Footer;
129 m_SubHeader = MROOrig.m_SubHeader;
130 m_Body = 0;
133 m_BodyLast = 0;
134 m_BodyCurr = 0;
143 m_checkCR = MROOrig.m_checkCR;
145 m_myBoss = 0;
146 m_ROOffset = 2;
147 m_NDLLCYC = 8;
148 m_NBunch = MROOrig.m_NBunch;
151 m_CM = 0;
152 m_BS = 0;
153 //
154 // copy m_CM hit structure
155 //
156 CMROData *q = 0;
157 CMROData *r = 0;
158 CMROData *p = MROOrig.m_Body;
159 ubit16 cnter = 0;
160 while (p) {
161 q = new CMROData;
162 q->hit = p->hit;
163 q->next = 0;
164 if (!cnter)
165 m_Body = q;
166 else
167 r->next = q;
168 cnter++;
169 r = q;
170 p = p->next;
171 } // end-of-while
172 m_BodyLast = r;
173} // end-of-MatrixReadOut::MatrixReadOut(const MatrixReadOut &MRCopy)
174//----------------------------------------------------------------------------//
176 //
177 // delete the CMROData dynamic structure used to describe Body part
178 // of the event fragment.
179 //
181} // end-of-MatrixReadOut::~MatrixReadOut
182//----------------------------------------------------------------------------//
183void MatrixReadOut::writeRecord(ubit16 thisRecord, bool last) {
184 if (m_numberOfWordsInFrag == 0) {
185 m_Header = thisRecord;
188 } else if (m_numberOfWordsInFrag == 1) {
189 m_SubHeader = thisRecord;
192 } else if (m_numberOfWordsInFrag > 1 && !last) {
193 makeNewHit(thisRecord);
194 } else {
195 m_Footer = thisRecord;
198 m_checkCR = checkCRC8(thisRecord);
199 } //
201} // end-of-MatrixReadOut::writeRecord
202//----------------------------------------------------------------------------//
204 m_BunchFrom = 0;
205 m_BunchTo = 7;
206 m_Header = 0;
207 m_Footer = 0;
208 m_SubHeader = 0;
209 m_Body = 0;
210 m_BodyLast = 0;
211 m_BodyCurr = 0;
212 //
213 m_FEL1ID = 0;
214 // m_ROOffset = 1; // use this for comparison with hardware (VHDL) output
215 // m_ROOffset = 0; // use this for MC
216 m_ROOffset = 2;
217 m_NBunch = NOBXS;
218 m_NDLLCYC = 8;
219 m_nchan[0] = 32;
220 m_nchan[1] = 64;
223 //
224 m_first8bitsON = 0x00ff;
225 //
226 // initialize check flags
227 //
236 m_checkCR = 0;
237 m_checkUnkown = 0;
238} // end-of-initialize
239//----------------------------------------------------------------------------//
242 initialize(NOBXS);
243 m_MROS.setInit();
244} // end-of-reset
245//----------------------------------------------------------------------------//
247 CMROData *p, *q;
248 p = m_Body;
249 while (p) {
250 q = p;
251 p = p->next;
252 delete q;
253 } // end-of-while
254 p = 0;
255 q = 0;
256 m_Body = 0;
257 m_BodyLast = 0;
258 m_BodyCurr = 0;
260} // end-of-deleteCMABody
261//----------------------------------------------------------------------------//
263 //
264 // method executed in conjunction with the simulation program
265 //
266 makeHeader();
268 makeCMABody();
269 makeFooter();
270 m_checkUnkown = 0;
272} // end-of-MatrixReadOut::makeFragment
273//----------------------------------------------------------------------------//
275 // ubit16 headerval[3];
276 if (m_CM) {
277 ubit16 CMcode;
279 // storical CMcode defintion (till 30/July/2007)
280 CMcode = 4 * m_CM->getLowHigh() + 2 * m_CM->getProjection() + m_CM->getLocalAdd();
281 } else {
282 // new CMcode defintion, used in the hardware
283 CMcode = 4 * m_CM->getLowHigh() + 2 * abs(m_CM->getProjection() - 1) + m_CM->getLocalAdd();
284 }
285 writeHeader(CMcode);
286 } else {
287 throw std::runtime_error("MatrixReadOut::makeHeader: m_CM object does not exist");
288 } // end-of-if
289} // end-of-MatrixReadOut::makeHeader
290//----------------------------------------------------------------------------//
292 if (m_CM) {
294 } else {
295 throw std::runtime_error("MatrixReadOut::makeSubHeader: m_CM object does not exist");
296 } // end-of-if
297} // end-of-MatrixReadOut::makeSubHeader
298//----------------------------------------------------------------------------//
300 if (m_CM) {
301 // cout<<"number of hits in matrixReadOut:"<<makeCMABodyHit()<<endl;
304 } else {
305 throw std::runtime_error("MatrixReadOut::makeCMABody: m_CM object does not exist");
306 } // end-of-if
307} // end-of-MatrixReadOut::makeCMABody
308//----------------------------------------------------------------------------//
310 if (m_CM) {
311 writeFooter();
312 } else {
313 throw std::runtime_error("MatrixReadOut::makeFooter: m_CM object does not exist");
314 } // end-of-if(m_CM
315} // end-of-makeFooter
316//----------------------------------------------------------------------------//
318 //
319 // compute the CR value of the event fragment stored in
320 // the words "m_Header" , "m_SubHeader" , "m_Body" .
321 //
322 // The value computed is then returned.
323 //
324 crc8 CR;
325 CMROData *p;
326 CR.calc(m_Header);
327 CR.calc(m_SubHeader);
328 p = m_Body;
329 while (p) {
330 CR.calc(p->hit);
331 p = p->next;
332 } // end-of-while
333 return CR.current();
334} // end-of-MatrixReadOut::computeCR()
335//----------------------------------------------------------------------------//
337 //
338 // set up the Body section of the event fragment.
339 //
340 // CMA_BODY --> |0|0| BCID | TIME | IJK | STRIP |
341 //
342 // This section is organized storing following the increasing value
343 // of IJK, BCID, TIME, STRIP.
344 //
345
346 ubit16 i, j, k, l, ijk, lijk;
347 ubit16 CMABodyval[5];
348 ubit16 numberOfHits = 0;
349 if (m_CM) {
350 for (ijk = 0; ijk < 6; ijk++) { // ijk values
351 //
352 // define the CMA side "i" as a fucntion of ijk value
353 //
354 if (ijk <= 1)
355 i = 0;
356 else
357 i = 1;
358 //
359 // define the layer address as a function of the ijk value
360 //
361 if (ijk == 0 || ijk == 2 || ijk == 3)
362 j = 0;
363 else
364 j = 1;
365 //
366 for (k = 0; k < m_nclock; k++) { // clock
367 //
368 // loop up to 32 "channels" (lijk)
369 //
370 for (lijk = 0; lijk < 32; lijk++) { // channel
371 //
372 // define the absolute channel address as a function of lijk
373 //
374 l = lijk;
375 if (ijk == 3 || ijk == 5) l = lijk + 32;
376 //
377 //
378 // Decoding map for CMA_BODY:
379 // #1 BCID filled with BC
380 // #2 TIME filled with TIME in DLL steps
381 // #3 IJK filled with:
382 //
383 // Side Layer #Channel IJK
384 // x 0 // 0
385 // x 1 // 1
386 // y 0 < 32 2
387 // y 0 > 32 3
388 // y 1 < 32 4
389 // y 1 > 32 5
390 // TRIGGER 6
391 //
392 // more info (Trigger case)
393 // 5 bit-word for IJK = 7
394 // |__|__|__|__|__| _____>Threshold(1="0" threshold
395 // | |***| |***| | 2="1" threshold
396 // | | |______| 3="2" threshold)
397 // | |
398 // 0 <-| |___overlap(2 bit)(0=no overlap,
399 // 1=overlap low chan
400 // 2=overlap high chann,
401 // 3 overlap low+high)
402 //
403 // #4 STRIP filled with: CHANNEL or k-readout
404 //
405 // cout<<"rodat="<<m_CM->rodat[i][j][k][l/32]<<" boh="<<(1<<(l%32))<<endl;
406 if ((m_CM->rodat[i][j][k][l / 32] & (1 << (l % 32)))) {
407 ubit16 SIDE = i;
408 ubit16 TIME = (k + m_ROOffset) % m_NDLLCYC; // from struct rpcdata in Matrix
409 ubit16 CHANNEL = l % 32; // from struct rpcdata
410 ubit16 IJK = 0;
411 ubit16 BC = (k + m_ROOffset) / m_NDLLCYC; // fill BCID word
412 //
413 if (SIDE == 0) {
414 IJK = j; // Fill the IJK-word(3-bit word for CMA_BODY)
415 } else {
416 IJK = 2 * j + l / 32 + 2;
417 } // end-of-if
418 //
419 // WARNING !!! BC>=0 ?? TIME >=0??
420 // Per riprodurre l'output di stefano si deve imporre
421 // BC>0 and BC<=7 and time>0
422 //
423 if (BC >= m_BunchFrom && BC <= m_BunchTo) {
424 // cout<<"Now store CM_hit with: BCID= "<<BC<<" TIME = "<<TIME
425 // <<" SIDE = "<<SIDE<<" layer = "<<j
426 // <<" IJK = " <<IJK<< " CHANNEL = "<<CHANNEL<<endl;
427 CMABodyval[0] = 0;
428 CMABodyval[1] = BC - m_BunchFrom;
429 CMABodyval[2] = TIME;
430 CMABodyval[3] = IJK;
431 CMABodyval[4] = CHANNEL;
432 makeNewHit(m_MROS.makeBody(CMABodyval));
433 numberOfHits++;
434 } // end of if(BC
435 } // end-of-if(input[....
436 } // end-of-for(lijk
437 } // end-of-for(k
438 } // end-of-for(ijk
439
440 //
441 } else {
442 throw std::runtime_error("MatrixReadOut::makeCMABodyHit: m_CM object does not exist");
443 } // end-of-if
444 return numberOfHits;
445} // end-of-MatrixReadOut::makeCMABodyHit
446//----------------------------------------------------------------------------//
448 ubit16 CMABodyval[5];
449 ubit16 channel = 0;
450 ubit16 BC, TIME, IJK, CHANNEL;
451 // int set_latenza;
452 // Removed h_last because it is not used
453 // int h_last[32]; // only pivot plane
454 //
455 // initialize h_last with large values
456 //
457 // for(ubit16 i=0; i<m_nchan[0]; i++) {h_last[i]=0xffff;}
458 //
459 ubit16 numberOfHits = 0;
460 bool triggerRO; // flag that indicates a trigger hit recorded in the ReadOut
461 if (m_CM) {
462 CMAword one = 1;
463 //
464 for (int h = 0; h < m_nclock; h++) { // loop on time clock
465 triggerRO = false; // initialize triggeRO
466 for (channel = 0; channel < m_nchan[0]; channel++) {
467 if (m_CM->k_readout[h] & (one << channel)) { // check K-readout register for
468 // set_latenza=abs(h-h_last[channel]);
469 // if (set_latenza >= m_timeSeparation) {
470 // a real-trigger data!
471 BC = (h + m_ROOffset) / m_NDLLCYC; // fill BCID word
472 TIME = (h + m_ROOffset) % m_NDLLCYC; // from struct rpcdata in Matrix
473 IJK = 6; // Trigger flag for IJK
474 CHANNEL = channel;
475 // h_last[channel]=h;
476
477 // cout<<"MatrixReadOut: Now store Trigger_hit with: BCID= "<<BC
478 //<<" TIME = "<<TIME<<" IJK = "<<IJK<<" CHANNEL = "<<CHANNEL<<endl;
479 //
480 if (BC >= m_BunchFrom && BC <= m_BunchTo) {
481 triggerRO = true; // there is a trigger hit in the ReadOut
482 CMABodyval[0] = 0;
483 CMABodyval[1] = BC - m_BunchFrom;
484 CMABodyval[2] = TIME;
485 CMABodyval[3] = IJK;
486 CMABodyval[4] = CHANNEL;
487 makeNewHit(m_MROS.makeBody(CMABodyval));
488 numberOfHits++;
489 } // end-of-if(BC
490 // }//end of if set_latenza
491 } // end of if k_readout
492 } // end of for(channel
493 //
494 // insert here the Threshold and overlap word
495 //
496 if (m_CM->highestthRO[h]) {
497 if (triggerRO) { // if there is a trigger in the RO add IJK=7 record
498 ubit16 thresh_h = m_CM->highestthRO[h];
499 ubit16 over_h = m_CM->overlapRO[h];
500 over_h = over_h << 2;
501 BC = (h + m_ROOffset) / m_NDLLCYC; // fill BCID word
502 TIME = (h + m_ROOffset) % m_NDLLCYC;
503 CHANNEL = (over_h | thresh_h);
504 IJK = 7;
505 //
506 // cout<<"MatrixReadOut: Now store Trigger_hit with: BCID= "
507 // <<BC<<" TIME = "<<TIME
508 // <<" IJK = "<<IJK<<" CHANNEL = "<<CHANNEL<<endl;
509 //
510 CMABodyval[0] = 0;
511 CMABodyval[1] = BC - m_BunchFrom;
512 CMABodyval[2] = TIME;
513 CMABodyval[3] = IJK;
514 CMABodyval[4] = CHANNEL;
515 makeNewHit(m_MROS.makeBody(CMABodyval));
516 numberOfHits++;
517 } // end-of-if(triggerRO
518 } // end-of-if(highestthRO
519 } // end of for(int h
520 //
521 // cout<<" ** Exit from makeCMABodyTrg method **"<<endl<<endl;
522 //
523 } else {
524 throw std::runtime_error("MatrixReadOut::makeHeader: m_CM object does not exist");
525 } // end-of-if(m_CM
526 return numberOfHits;
527} // end-of-MatrixReadOut::makeCMABodyTrg
528//----------------------------------------------------------------------------//
530 ubit16 headerval[3];
531 headerval[0] = 0;
532 headerval[1] = CMcode;
533 headerval[2] = m_FEL1ID;
534 m_Header = m_MROS.makeHeader(headerval);
535 m_checkHeaderNum++; //=1
536 m_checkHeaderPos = 1; //=1
537} // end-of-writeHeader
538//----------------------------------------------------------------------------//
540 m_SubHeader = m_MROS.makeSubHeader();
541 m_checkSubHeaderNum++; //=1
543
544} // end-of-MatrixReadOut::writeSubHeader
545//----------------------------------------------------------------------------//
547 ubit16 CMABodyval[5];
548 CMABodyval[0] = 0;
549 CMABodyval[1] = BC;
550 CMABodyval[2] = TIME;
551 CMABodyval[3] = IJK;
552 CMABodyval[4] = CHANNEL;
553 sortAndMakeNewHit(m_MROS.makeBody(CMABodyval));
554} // end-of-MatrixReadOut::writeCMABody
555//----------------------------------------------------------------------------//
557 ubit16 footerval;
558 footerval = computeCR() & m_first8bitsON;
559 m_Footer = m_MROS.makeFooter(footerval);
560 m_checkCR = 0;
563} // end-of-MatrixReadOut::writeFooter
564//----------------------------------------------------------------------------//
566 CMROData *p;
567 p = new CMROData;
568 p->hit = newHit;
569 p->next = 0;
570 if (!m_Body) {
571 m_Body = p;
572 } else {
573 m_BodyLast->next = p;
574 } // end-of-if
575 m_BodyLast = p;
577} // end-of-MatrixReadOut::makeNewHit
578//----------------------------------------------------------------------------//
579void MatrixReadOut::makeNewHit(ubit16 newHit, CMROData *previous, CMROData *next) {
580 CMROData *newElement;
581 newElement = new CMROData;
582 newElement->hit = newHit;
583 newElement->next = next;
584 if (next == m_Body)
585 m_Body = newElement;
586 else
587 previous->next = newElement;
589} // end-of-MatrixReadOut::makeNewHit
590//----------------------------------------------------------------------------//
592 CMROData *p, *previous; //, *newElement;
593 char field;
594 // cout<<" new Hit is "<<hex<<newHit<<dec<<endl;
595 p = m_Body;
596 previous = m_Body;
597 // newElement = 0;
598 m_MROS.decodeFragment(newHit, field);
599 // cout<<" IELD= "<<field<<endl;
600 const ubit16 hitBCID = m_MROS.bcid();
601 const ubit16 hitTIME = m_MROS.time();
602 const ubit16 hitIJK = m_MROS.ijk();
603 const ubit16 hitCHANNEL = m_MROS.channel();
604 // cout<<" decode HIT "<<hitBCID<<" "<<hitTIME<<" "<<hitIJK<<" "<<hitCHANNEL<<endl;
605 //
606 do {
607 if (p) {
608 m_MROS.decodeFragment(p->hit, field);
609
610 if (hitIJK > m_MROS.ijk()) {
611 previous = p;
612 p = p->next;
613 } else if (hitIJK < m_MROS.ijk()) {
614 makeNewHit(newHit, previous, p);
615 break;
616 } else if (hitIJK == m_MROS.ijk()) {
617 if (hitBCID > m_MROS.bcid()) {
618 previous = p;
619 p = p->next;
620 } else if (hitBCID < m_MROS.bcid()) {
621 makeNewHit(newHit, previous, p);
622 break;
623 } else if (hitBCID == m_MROS.bcid()) {
624 if (hitTIME > m_MROS.time()) {
625 previous = p;
626 p = p->next;
627 } else if (hitTIME < m_MROS.time()) {
628 makeNewHit(newHit, previous, p);
629 break;
630 } else if (hitTIME == m_MROS.time()) {
631 if (hitCHANNEL > m_MROS.channel()) {
632 previous = p;
633 p = p->next;
634 } else if (hitCHANNEL < m_MROS.channel()) {
635 makeNewHit(newHit, previous, p);
636 break;
637 } else {
638 throw std::runtime_error("duplicazione di hit???");
639 break;
640 } // end-of-if(hitCHANNEL
641 } // end-of-if(hitTIME
642 } // end-of-if(hitBCID
643 } // end-of-if(hitIJK
644
645 } // if(p
646
647 if (!p) {
648 if (!m_Body) { // structure empty
649 makeNewHit(newHit);
650 } else { // we are in the end of the structure
651 makeNewHit(newHit, previous, p);
652 } // end-of-if(!m_Body
653 } // end-of-if(p
654 } while (p);
655} // end-of-MatrixReadOut::sortAndMakeNewHit
656//----------------------------------------------------------------------------//
658//----------------------------------------------------------------------------//
660//----------------------------------------------------------------------------//
662//----------------------------------------------------------------------------//
664 if (m_BodyCurr) {
665 ubit16 hit = m_BodyCurr->hit;
666 m_BodyCurr = m_BodyCurr->next;
667 return hit;
668 } else {
669 return 0xffff;
670 }
671} // end-of-MatrixReadout::readCMABodyCurrent
672//----------------------------------------------------------------------------//
674 ubit16 i = 0;
675 CMROData *p;
677 p = m_Body;
678 for (i = 0; i < m_numberOfWordsInBody; i++) {
679 *(Body + i) = p->hit;
680 p = p->next;
681 } // end-of-for
682 } // end-of-if
683} // end-of-MatrixReadout::readCMABody
684//----------------------------------------------------------------------------//
686 ubit16 output = 0xffff;
687 if (m_addressOfWordScanned == 0)
688 output = readHeader();
689 else if (m_addressOfWordScanned == 1)
690 output = readSubHeader();
692 output = readFooter();
693 else
694 output = readCMABodyCurrent();
696 return output;
697} // end-of-MatrixReadout::readCMAWord
698//----------------------------------------------------------------------------//
700 MatrixReadOutStructure theStruct;
701 ubit16 theHit;
703 // cout<<" getCMAHit: Wrong index given;"
704 //<<" numberOfWordsInBody= "<<m_numberOfWordsInBody
705 //<<" index = "<<index<<endl;
706 } else {
707 CMROData *p;
708 p = m_Body;
709 for (int i = 0; i < m_numberOfWordsInBody; i++) {
710 theHit = p->hit;
711 if (index == i) { theStruct = MatrixReadOutStructure(theHit); }
712 p = p->next;
713 }
714 }
715 return theStruct;
716} // end-of-MatrixReadOut::getCMAHit(int index)
717//----------------------------------------------------------------------------//
721} // MatrixReadOut::end-of-topCMABody
722//----------------------------------------------------------------------------//
723void MatrixReadOut::display(ostream &stream) {
724 displayHeader(stream);
725 displaySubHeader(stream);
726 displayBody(stream);
727 displayFooter(stream);
728} // end-of-MatrixReadOut::display
729//----------------------------------------------------------------------------//
730void MatrixReadOut::displayHeader(ostream &stream) {
731 char field;
732 stream << endl;
733 stream << hex << m_Header << dec;
734 ubit16 errorDecode = m_MROS.decodeFragment(m_Header, field);
735 if (!errorDecode && field == 'H') {
736 stream << " -- CMID " << m_MROS.cmid();
737 stream << " FEL1ID " << m_MROS.fel1id();
738 } else {
739 stream << " ERROR IN HEADER DECODING ";
740 } // end-of-if
741 stream << endl;
742} // end-of-MatrixReadOut::displayHeader
743//----------------------------------------------------------------------------//
744void MatrixReadOut::displaySubHeader(ostream &stream) {
745 char field;
746 stream << hex << m_SubHeader << dec;
747 ubit16 errorDecode = m_MROS.decodeFragment(m_SubHeader, field);
748 if (!errorDecode && field == 'S') {
749 stream << " -- FEBCID " << m_MROS.febcid();
750 } else {
751 stream << " ERROR IN SUBHEADER DECODING ";
752 } // end-of-if
753 stream << endl;
754} // end-of-MatrixReadOut::displaySubHeader
755//----------------------------------------------------------------------------//
756void MatrixReadOut::displayBody(ostream &stream) {
757 CMROData *p;
758 char field;
759 p = m_Body;
760 //
761 while (p) {
762 stream << hex << p->hit << dec;
763 ubit16 errorDecode = m_MROS.decodeFragment(p->hit, field);
764 if (!errorDecode && field == 'B') {
765 stream << " -- BC " << m_MROS.bcid();
766 stream << " TIME " << m_MROS.time();
767 if (m_MROS.ijk() < 7) {
768 stream << " IJK " << m_MROS.ijk();
769 stream << " STRIP " << m_MROS.channel();
770 } else {
771 stream << " OVL " << m_MROS.overlap();
772 stream << " THR " << m_MROS.threshold();
773 } // end-of-if
774 } else {
775 stream << " ERROR IN BODY DECODING ";
776 } // end-of-if(!errorDecode
777 stream << endl;
778 p = p->next;
779 } // end-of-while
780} // end-of-MatrixReadOut::displayBody
781//----------------------------------------------------------------------------//
782void MatrixReadOut::displayFooter(ostream &stream) {
783 char field;
784 stream << hex << m_Footer << dec;
785 stream << " -- CODE " << 1;
786 ubit16 errorDecode = m_MROS.decodeFragment(m_Footer, field);
787 if (!errorDecode && field == 'F') {
788 stream << " CRC " << hex << m_MROS.crc() << dec;
789 } else {
790 stream << " ERROR IN FOOTER DECODING ";
791 } // end-of-if(!errorDecode
792 stream << endl;
793} // end-of-MatrixReadOut::displayFooter
794//----------------------------------------------------------------------------//
795void MatrixReadOut::bytestream(ostream &stream) {
796 CMROData *p;
797 stream << hex << m_Header << dec << endl; // header
798 stream << hex << m_SubHeader << dec << endl; // subheader
799 p = m_Body;
800 while (p) {
801 stream << hex << p->hit << dec << endl; // body
802 p = p->next;
803 } // end-of-while
804 stream << hex << m_Footer << dec << endl; // footer
805} // end-of-MatrixReadOut::bytestream
806//----------------------------------------------------------------------------//
808 // cout<<" MatrixReadOut(ubit16 *pointer, ubit16 num) ";
809 // cout<<endl
810 // cout<<" check dump "<<endl
811 // std::cout<<" m_checkHeaderNum = "<<m_checkHeaderNum
812 // <<" CheckHeaderPos = "<<m_checkHeaderPos<<std::endl;
813 // cout<<" m_checkSubHeaderNum = "<<m_checkSubHeaderNum
814 // <<" CheckSubHeaderPos = "<<m_checkSubHeaderPos<<endl
815 // cout<<" m_checkFooterNum = "<<m_checkFooterNum
816 // <<" CheckFooterPos = "<<m_checkFooterPos<<endl
817 // cout<<" CheckUnkown = "<<m_checkUnkown<<endl
818 // cout<<" Number of Words In Fragment = "<<m_numberOfWordsInFrag<<endl;
819 ubit16 output = 0;
820 if (m_checkHeaderNum != 1 && !(output & 0x00000001)) output += 1; //=1
821 if (m_checkHeaderPos > 1 && !(output & 0x00000002)) output += 2; //=1
822 if (m_checkSubHeaderNum != 1 && !(output & 0x00000004)) output += 4; //=1
823 if (m_checkSubHeaderPos != 2 && !(output & 0x00000008)) output += 8; //=2
824 if (m_checkFooterPos != m_numberOfWordsInFrag && !(output & 0x00000010)) output += 16;
825 if (m_checkCR && !(output & 0x00000020)) output += 32;
826 if (m_checkUnkown && !(output & 0x00000040)) output += 64;
827 if (checkBodyOrder() && !(output & 0x00000080)) output += 128;
828 return output;
829} // end-of-MatrixReadOut::checkFragment
830//----------------------------------------------------------------------------//
832 ubit16 output = 0;
833 if ((computeCR() & m_first8bitsON) != (foot & m_first8bitsON)) output = 1;
834 return output;
835} // end-of-MatrixReadOut::checkCRC8()
836//----------------------------------------------------------------------------//
838 CMROData *p, *pnext;
839 char field;
840 ubit16 currIJK, currBCID, currTIME, currCHANNEL;
841 ubit16 nextIJK, nextBCID, nextTIME, nextCHANNEL;
842 ubit16 prevIJK; //, prevBCID, prevTIME, prevCHANNEL;
843 ubit16 output = 0;
844 ubit16 outTemp = 0;
845 p = m_Body;
846
847 prevIJK = 8; // use a non-sense initializer
848 // prevBCID=0;
849 // prevTIME=0;
850 // prevCHANNEL=0;
851
852 while (p) {
853 m_MROS.decodeFragment(p->hit, field);
854 currIJK = m_MROS.ijk();
855 currBCID = m_MROS.bcid();
856 currTIME = m_MROS.time();
857 currCHANNEL = m_MROS.channel();
858 pnext = p->next;
859 if (pnext) {
860 // output=0;
861 m_MROS.decodeFragment(pnext->hit, field);
862 nextIJK = m_MROS.ijk();
863 nextBCID = m_MROS.bcid();
864 nextTIME = m_MROS.time();
865 nextCHANNEL = m_MROS.channel();
866 //
867
868 if (currIJK < 6) { // analyze first IJK=0,1,2,3,4,5 ...
869
870 if (nextIJK < currIJK) {
871 output += 1;
872 outTemp = 1;
873 } else if (nextIJK == currIJK) {
874 if (nextBCID < currBCID) {
875 output += 2;
876 outTemp = 2;
877 } else if (nextBCID == currBCID) {
878 if (nextTIME < currTIME) {
879 output += 4;
880 outTemp = 4;
881 } else if (nextTIME == currTIME) {
882 if (nextCHANNEL <= currCHANNEL) {
883 output += 8;
884 outTemp = 8;
885 }
886 }
887 }
888 }
889
890 } else if (currIJK == 6) { // ... then first IJK=6 ...
891
892 if (nextIJK == currIJK) {
893 if (nextBCID != currBCID || nextTIME != currTIME) {
894 output += 16;
895 outTemp = 16;
896 } else {
897 if (nextCHANNEL <= currCHANNEL) {
898 output += 32;
899 outTemp = 32;
900 }
901 } // end-of-if(nextBCID!=currBCID || nextTIME!=currTIME)
902 } else if (nextIJK == 7) {
903 } // end-of-if(nextIJK==currIJK)
904
905 } else if (currIJK == 7) { // finally IJK=7.
906
907 if (prevIJK != 6) { // if this m_CM hit has IJK=7 then the previous on must have IJK=6
908 output += 64;
909 outTemp = 64;
910 }
911
912 } else {
913 } // end-of-if(currIJK
914
915 if (outTemp > 0 && debugPrint) {
916 cout << "checkBodyOrder output= " << output << " with " << hex << pnext->hit << dec << endl;
917 } // end-of-if(outTemp
918 outTemp = 0;
919
920 } else { // else of if(p->next
921
922 if (currIJK == 6) {
923 output += 64;
924 if (debugPrint) cout << " CheckBodyOrder; IJK 6 exists but the related IJK 7 has been found " << endl;
925 } else if (currIJK == 7 && prevIJK != 6) { // we are at the last m_CM hit; if this has IJK=7
926 output += 128; // then the previous m_CM hit must have IJK=6
927 if (debugPrint) cout << " CheckBodyOrder; IJK 7 exists but the related IJK 6 has been found " << endl;
928 }
929
930 } // end-of-if(p->next
931
932 prevIJK = currIJK;
933 // prevBCID =currBCID; // not used in this version
934 // prevTIME =currTIME; // not used in this version
935 // prevCHANNEL=currCHANNEL; // not used in this version
936 p = p->next;
937
938 } // end-of-while(p)
939
940 return output;
941} // end-of-checkBodyOrder
942//----------------------------------------------------------------------------//
944 m_myBoss = boss;
945 return;
946} // end-of-MatrixReadOut::setManager( ReadOutManager* boss )
947//----------------------------------------------------------------------------//
950 return theStruct;
951} // end-of-MatrixReadOut::getHeader()
952//----------------------------------------------------------------------------//
955 return theStruct;
956} // end-of-MatrixReadOut::getSubHeader()
957//----------------------------------------------------------------------------//
960 return theStruct;
961} // end-of-MatrixReadOut::getFooter()
962//----------------------------------------------------------------------------//
964 //
965 // copy the pointer to CMA "CMpointer" in "m_CM" member
966 //
967 m_CM = CMpointer;
968 m_CM->reset();
969 ubit16 sidemat = 0;
970 ubit16 layer = 0;
971 ubit16 stripaddress = 0;
972 const ubit16 ROOffset = 2;
973
974 for (ubit16 n = 0; n < m_numberOfWordsInBody; n++) {
976 ubit16 IJK = locMRO.ijk();
977 ubit16 CHANNEL = locMRO.global_channel();
978 ubit16 BCID = locMRO.bcid();
979 ubit16 TIME = locMRO.time();
980 float absTime = 0.;
981
982 //
983 // select CMA strip data (IJK from 0 to 5; 6 and 7 are for trigger data
984 //
985 if (IJK < 6) {
986 switch (IJK) {
987 case 0:
988 sidemat = 0;
989 layer = 0;
990 stripaddress = CHANNEL;
991 break;
992 case 1:
993 sidemat = 0;
994 layer = 1;
995 stripaddress = CHANNEL;
996 break;
997 case 2:
998 sidemat = 1;
999 layer = 0;
1000 stripaddress = CHANNEL;
1001 break;
1002 case 3:
1003 sidemat = 1;
1004 layer = 0;
1005 stripaddress = CHANNEL;
1006 break;
1007 case 4:
1008 sidemat = 1;
1009 layer = 1;
1010 stripaddress = CHANNEL;
1011 break;
1012 case 5:
1013 sidemat = 1;
1014 layer = 1;
1015 stripaddress = CHANNEL;
1016 break;
1017 default: throw std::runtime_error("MatrixReadOut::doMatrix: IJK= " + std::to_string(IJK) + " out of RANGE");
1018 } // end-of-switch
1019 //
1020 // estimate absolute time from CMA time
1021 //
1022 absTime = 25. * ((float)BCID + ((float)(TIME - ROOffset)) / 8.);
1023 m_CM->putData(sidemat, layer, stripaddress, absTime);
1024 } // end-of-if(IJK<6
1025 } // end-of-for(ubit16 n
1026 //
1027 // use the Matrix data buffer from the the first available location and not
1028 // at the center as it is done by default
1029 //
1030 m_CM->setBCzero(0);
1031 //
1032 // run the CMA logic
1033 //
1034 m_CM->execute();
1035} // end-of-MatrixReadOut::doMatrix()
1036//----------------------------------------------------------------------------//
1037void MatrixReadOut::makeTestPattern(ubit16 mode, ubit16 ktimes, int eventNum) {
1038 std::cout << " makeTestPattern " << std::endl;
1039 MatrixReadOutStructure MRS = getHeader(); // get the m_CM Header
1040 ubit16 cmid = MRS.cmid(); // m_CM Address (or identifier)
1041 //
1042 ofstream vhdlinput;
1043 vhdlinput.open("vhdl.input", ios::app);
1044 if (!vhdlinput) { cout << " File for vhdl analysis not opened. " << endl << " ==================================" << endl << endl; };
1045 //
1046 const ubit16 maxchan = 100;
1047 const ubit16 maxtimes = 200;
1048 ubit16 IJ[maxtimes][4], channels[maxtimes][4][maxchan];
1049 float times[maxtimes] = {0};
1050 char plane[4][3];
1051 strcpy(plane[0], "I0");
1052 strcpy(plane[1], "I1");
1053 strcpy(plane[2], "J0");
1054 strcpy(plane[3], "J1");
1055 ubit16 ntimes = 0;
1056 for (ubit16 l = 0; l < maxtimes; l++) {
1057 for (ubit16 i = 0; i < 4; i++) { IJ[l][i] = 0; }
1058 }
1059
1060 float timeover = 999999.;
1061 bool completed = false;
1062 float timelast = -timeover;
1063
1064 std::cout << this << std::endl;
1065
1066 while (!completed) {
1067 float timemin = timeover;
1068 for (int iCMhit = 0; iCMhit < m_numberOfWordsInBody; iCMhit++) {
1069 MatrixReadOutStructure MRS = getCMAHit(iCMhit);
1070 int ijk = MRS.ijk();
1071 if (ijk < 6) {
1072 float time = ((float)(MRS.bcid() * 8 + MRS.time()) - 0.5) * 3.125;
1073 // int channel=MRS.global_channel(); // m_CM channel
1074 // std::cout<<"time "<<time<<" IJK= "<<ijk<<" channel "<<channel<<std::endl;
1075 if (time > timelast && time < timemin) timemin = time;
1076 } // end-of-if(
1077 } // end-of-for(
1078
1079 if (timemin == timeover) {
1080 completed = true;
1081 } else {
1082 ubit16 this_time_counter = 0;
1083 for (int iCMhit = 0; iCMhit < m_numberOfWordsInBody; iCMhit++) {
1084 MatrixReadOutStructure MRS = getCMAHit(iCMhit);
1085 int ijk = MRS.ijk();
1086 if (ijk < 6) {
1087 int channel = MRS.global_channel(); // m_CM channel
1088 float time = ((float)(MRS.bcid() * 8 + MRS.time()) - 0.5) * 3.125;
1089 if (time == timemin && ntimes < maxtimes) {
1090 if (!this_time_counter) ntimes++;
1091 this_time_counter++;
1092 ubit16 ijk_index = 0;
1093 if (ijk == 0)
1094 ijk_index = 0;
1095 else if (ijk == 1)
1096 ijk_index = 1;
1097 else if (ijk == 2 || ijk == 3)
1098 ijk_index = 2;
1099 else if (ijk == 4 || ijk == 5)
1100 ijk_index = 3;
1101 times[ntimes - 1] = time;
1102 if (IJ[ntimes - 1][ijk_index] < maxchan) {
1103 IJ[ntimes - 1][ijk_index]++;
1104 channels[ntimes - 1][ijk_index][IJ[ntimes - 1][ijk_index] - 1] = channel;
1105 } // end-of-if
1106 } // end-of-if(time==timemin
1107 } // end-of-if(
1108 } // end-of-for(
1109 timelast = timemin;
1110 // std::cout<<" time min found: "<<timelast<<std::endl;
1111 }
1112 } // end-of-while
1113
1114 if (mode) {
1115 int NBunch = 0;
1116 int run = 0;
1117 vhdlinput << " RUN " << run << " EVENT " << eventNum << " CMID " << cmid << " WINDOW " << NBunch;
1118 vhdlinput << " LINES " << (ntimes + ktimes) << std::endl;
1119 } // end-of-if(mode
1120 for (ubit16 l = 0; l < ntimes; l++) {
1121 vhdlinput << " TIME " << times[l] << " ";
1122 for (ubit16 i = 0; i < 4; i++) {
1123 vhdlinput << plane[i][0] << plane[i][1] << " " << IJ[l][i] << " ";
1124 for (ubit16 j = 0; j < IJ[l][i]; j++) { vhdlinput << channels[l][i][j] << " "; } // end-of-for(j
1125 } // end-of-for(i
1126 vhdlinput << std::endl;
1127 } // end-of-for(l
1128 //
1129 vhdlinput.close();
1130} // end-of-MatrixReadOut::makeTestPattern
@ Hardware
Definition BaseObject.h:11
unsigned int uint
uint32_t CMAword
Definition Lvl1Def.h:17
unsigned short int ubit16
BaseObject(ObjectType, const std::string &)
Definition BaseObject.cxx:7
void writeRecord(ubit16 thisRecord, bool last)
ubit16 m_checkFooterNum
ubit16 checkCRC8(ubit16 foot)
MatrixReadOut(Matrix *p, ubit16 FEevent, uint NOBXS, DataVersion=MatrixReadOut::Atlas)
MatrixReadOut::DataVersion m_data_version
void setManager(ReadOutManager *boss)
void doMatrix(Matrix *CMpointer)
void readCMABody(ubit16 *Body)
ubit16 m_timeSeparation
CMROData * m_Body
ubit16 m_numberOfWordsInFrag
ubit16 checkBodyOrder(bool debugPrint=false)
MatrixReadOutStructure getFooter()
ubit16 readSubHeader()
void displayHeader(std::ostream &stream)
ubit16 makeCMABodyTrg()
void displayBody(std::ostream &stream)
ReadOutManager * m_myBoss
ubit16 m_checkHeaderPos
ubit16 m_addressOfWordScanned
friend class ReadOutManager
void bytestream(std::ostream &stream)
CMROData * m_BodyCurr
void sortAndMakeNewHit(ubit16 newHit)
void displayFooter(std::ostream &stream)
void writeHeader(ubit16 CMcode)
MatrixReadOutStructure m_MROS
CMROData * m_BodyLast
ubit16 makeCMABodyHit()
MatrixReadOutStructure getCMAHit(int index)
ubit16 m_numberOfWordsInBody
ubit16 m_checkFooterPos
void display(std::ostream &stream)
void makeTestPattern(ubit16 mode, ubit16 ktimes, int eventNum)
ubit16 m_checkSubHeaderPos
ubit16 m_first8bitsON
ubit16 readCMABodyCurrent()
MatrixReadOutStructure getHeader()
ubit16 m_nchan[2]
ubit16 m_checkHeaderNum
ubit16 numberOfFragmentWords()
void initialize(uint NOBXS)
void writeCMABody(ubit16 _BC, ubit16 _TIME, ubit16 IJK, ubit16 _STRIP)
ubit16 m_checkSubHeaderNum
void reset(uint NOBXS)
void makeNewHit(ubit16 newHit)
void displaySubHeader(std::ostream &stream)
ubit16 checkFragment()
MatrixReadOutStructure getSubHeader()
Definition crc8.h:8
int calc(int dato)
Definition crc8.cxx:29
int current()
Definition crc8.cxx:23
int r
Definition globals.cxx:22
Definition index.py:1
Definition run.py:1
STL namespace.
void initialize()