ATLAS Offline Software
Loading...
Searching...
No Matches
MatrixReadOut.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 <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
676 if (m_Body and m_numberOfWordsInBody!=0) {
677 CMROData *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 CMROData *p = m_Body;
704 for (int i = 0; i < m_numberOfWordsInBody; i++) {
705 theHit = p->hit;
706 if (index == i) { theStruct = MatrixReadOutStructure(theHit); }
707 p = p->next;
708 }
709 }
710 return theStruct;
711} // end-of-MatrixReadOut::getCMAHit(int index)
712//----------------------------------------------------------------------------//
716} // MatrixReadOut::end-of-topCMABody
717//----------------------------------------------------------------------------//
718void MatrixReadOut::display(ostream &stream) {
719 displayHeader(stream);
720 displaySubHeader(stream);
721 displayBody(stream);
722 displayFooter(stream);
723} // end-of-MatrixReadOut::display
724//----------------------------------------------------------------------------//
725void MatrixReadOut::displayHeader(ostream &stream) {
726 char field;
727 stream << endl;
728 stream << hex << m_Header << dec;
729 ubit16 errorDecode = m_MROS.decodeFragment(m_Header, field);
730 if (!errorDecode && field == 'H') {
731 stream << " -- CMID " << m_MROS.cmid();
732 stream << " FEL1ID " << m_MROS.fel1id();
733 } else {
734 stream << " ERROR IN HEADER DECODING ";
735 } // end-of-if
736 stream << endl;
737} // end-of-MatrixReadOut::displayHeader
738//----------------------------------------------------------------------------//
739void MatrixReadOut::displaySubHeader(ostream &stream) {
740 char field;
741 stream << hex << m_SubHeader << dec;
742 ubit16 errorDecode = m_MROS.decodeFragment(m_SubHeader, field);
743 if (!errorDecode && field == 'S') {
744 stream << " -- FEBCID " << m_MROS.febcid();
745 } else {
746 stream << " ERROR IN SUBHEADER DECODING ";
747 } // end-of-if
748 stream << endl;
749} // end-of-MatrixReadOut::displaySubHeader
750//----------------------------------------------------------------------------//
751void MatrixReadOut::displayBody(ostream &stream) {
752 CMROData *p;
753 char field;
754 p = m_Body;
755 //
756 while (p) {
757 stream << hex << p->hit << dec;
758 ubit16 errorDecode = m_MROS.decodeFragment(p->hit, field);
759 if (!errorDecode && field == 'B') {
760 stream << " -- BC " << m_MROS.bcid();
761 stream << " TIME " << m_MROS.time();
762 if (m_MROS.ijk() < 7) {
763 stream << " IJK " << m_MROS.ijk();
764 stream << " STRIP " << m_MROS.channel();
765 } else {
766 stream << " OVL " << m_MROS.overlap();
767 stream << " THR " << m_MROS.threshold();
768 } // end-of-if
769 } else {
770 stream << " ERROR IN BODY DECODING ";
771 } // end-of-if(!errorDecode
772 stream << endl;
773 p = p->next;
774 } // end-of-while
775} // end-of-MatrixReadOut::displayBody
776//----------------------------------------------------------------------------//
777void MatrixReadOut::displayFooter(ostream &stream) {
778 char field;
779 stream << hex << m_Footer << dec;
780 stream << " -- CODE " << 1;
781 ubit16 errorDecode = m_MROS.decodeFragment(m_Footer, field);
782 if (!errorDecode && field == 'F') {
783 stream << " CRC " << hex << m_MROS.crc() << dec;
784 } else {
785 stream << " ERROR IN FOOTER DECODING ";
786 } // end-of-if(!errorDecode
787 stream << endl;
788} // end-of-MatrixReadOut::displayFooter
789//----------------------------------------------------------------------------//
790void MatrixReadOut::bytestream(ostream &stream) {
791 CMROData *p;
792 stream << hex << m_Header << dec << endl; // header
793 stream << hex << m_SubHeader << dec << endl; // subheader
794 p = m_Body;
795 while (p) {
796 stream << hex << p->hit << dec << endl; // body
797 p = p->next;
798 } // end-of-while
799 stream << hex << m_Footer << dec << endl; // footer
800} // end-of-MatrixReadOut::bytestream
801//----------------------------------------------------------------------------//
803 // cout<<" MatrixReadOut(ubit16 *pointer, ubit16 num) ";
804 // cout<<endl
805 // cout<<" check dump "<<endl
806 // std::cout<<" m_checkHeaderNum = "<<m_checkHeaderNum
807 // <<" CheckHeaderPos = "<<m_checkHeaderPos<<std::endl;
808 // cout<<" m_checkSubHeaderNum = "<<m_checkSubHeaderNum
809 // <<" CheckSubHeaderPos = "<<m_checkSubHeaderPos<<endl
810 // cout<<" m_checkFooterNum = "<<m_checkFooterNum
811 // <<" CheckFooterPos = "<<m_checkFooterPos<<endl
812 // cout<<" CheckUnkown = "<<m_checkUnkown<<endl
813 // cout<<" Number of Words In Fragment = "<<m_numberOfWordsInFrag<<endl;
814 ubit16 output = 0;
815 if (m_checkHeaderNum != 1 && !(output & 0x00000001)) output += 1; //=1
816 if (m_checkHeaderPos > 1 && !(output & 0x00000002)) output += 2; //=1
817 if (m_checkSubHeaderNum != 1 && !(output & 0x00000004)) output += 4; //=1
818 if (m_checkSubHeaderPos != 2 && !(output & 0x00000008)) output += 8; //=2
819 if (m_checkFooterPos != m_numberOfWordsInFrag && !(output & 0x00000010)) output += 16;
820 if (m_checkCR && !(output & 0x00000020)) output += 32;
821 if (m_checkUnkown && !(output & 0x00000040)) output += 64;
822 if (checkBodyOrder() && !(output & 0x00000080)) output += 128;
823 return output;
824} // end-of-MatrixReadOut::checkFragment
825//----------------------------------------------------------------------------//
827 ubit16 output = 0;
828 if ((computeCR() & m_first8bitsON) != (foot & m_first8bitsON)) output = 1;
829 return output;
830} // end-of-MatrixReadOut::checkCRC8()
831//----------------------------------------------------------------------------//
833 CMROData *p, *pnext;
834 char field;
835 ubit16 currIJK, currBCID, currTIME, currCHANNEL;
836 ubit16 nextIJK, nextBCID, nextTIME, nextCHANNEL;
837 ubit16 prevIJK; //, prevBCID, prevTIME, prevCHANNEL;
838 ubit16 output = 0;
839 ubit16 outTemp = 0;
840 p = m_Body;
841
842 prevIJK = 8; // use a non-sense initializer
843 // prevBCID=0;
844 // prevTIME=0;
845 // prevCHANNEL=0;
846
847 while (p) {
848 m_MROS.decodeFragment(p->hit, field);
849 currIJK = m_MROS.ijk();
850 currBCID = m_MROS.bcid();
851 currTIME = m_MROS.time();
852 currCHANNEL = m_MROS.channel();
853 pnext = p->next;
854 if (pnext) {
855 // output=0;
856 m_MROS.decodeFragment(pnext->hit, field);
857 nextIJK = m_MROS.ijk();
858 nextBCID = m_MROS.bcid();
859 nextTIME = m_MROS.time();
860 nextCHANNEL = m_MROS.channel();
861 //
862
863 if (currIJK < 6) { // analyze first IJK=0,1,2,3,4,5 ...
864
865 if (nextIJK < currIJK) {
866 output += 1;
867 outTemp = 1;
868 } else if (nextIJK == currIJK) {
869 if (nextBCID < currBCID) {
870 output += 2;
871 outTemp = 2;
872 } else if (nextBCID == currBCID) {
873 if (nextTIME < currTIME) {
874 output += 4;
875 outTemp = 4;
876 } else if (nextTIME == currTIME) {
877 if (nextCHANNEL <= currCHANNEL) {
878 output += 8;
879 outTemp = 8;
880 }
881 }
882 }
883 }
884
885 } else if (currIJK == 6) { // ... then first IJK=6 ...
886
887 if (nextIJK == currIJK) {
888 if (nextBCID != currBCID || nextTIME != currTIME) {
889 output += 16;
890 outTemp = 16;
891 } else {
892 if (nextCHANNEL <= currCHANNEL) {
893 output += 32;
894 outTemp = 32;
895 }
896 } // end-of-if(nextBCID!=currBCID || nextTIME!=currTIME)
897 } else if (nextIJK == 7) {
898 } // end-of-if(nextIJK==currIJK)
899
900 } else if (currIJK == 7) { // finally IJK=7.
901
902 if (prevIJK != 6) { // if this m_CM hit has IJK=7 then the previous on must have IJK=6
903 output += 64;
904 outTemp = 64;
905 }
906
907 } else {
908 } // end-of-if(currIJK
909
910 if (outTemp > 0 && debugPrint) {
911 cout << "checkBodyOrder output= " << output << " with " << hex << pnext->hit << dec << endl;
912 } // end-of-if(outTemp
913 outTemp = 0;
914
915 } else { // else of if(p->next
916
917 if (currIJK == 6) {
918 output += 64;
919 if (debugPrint) cout << " CheckBodyOrder; IJK 6 exists but the related IJK 7 has been found " << endl;
920 } else if (currIJK == 7 && prevIJK != 6) { // we are at the last m_CM hit; if this has IJK=7
921 output += 128; // then the previous m_CM hit must have IJK=6
922 if (debugPrint) cout << " CheckBodyOrder; IJK 7 exists but the related IJK 6 has been found " << endl;
923 }
924
925 } // end-of-if(p->next
926
927 prevIJK = currIJK;
928 // prevBCID =currBCID; // not used in this version
929 // prevTIME =currTIME; // not used in this version
930 // prevCHANNEL=currCHANNEL; // not used in this version
931 p = p->next;
932
933 } // end-of-while(p)
934
935 return output;
936} // end-of-checkBodyOrder
937//----------------------------------------------------------------------------//
939 m_myBoss = boss;
940 return;
941} // end-of-MatrixReadOut::setManager( ReadOutManager* boss )
942//----------------------------------------------------------------------------//
945 return theStruct;
946} // end-of-MatrixReadOut::getHeader()
947//----------------------------------------------------------------------------//
950 return theStruct;
951} // end-of-MatrixReadOut::getSubHeader()
952//----------------------------------------------------------------------------//
955 return theStruct;
956} // end-of-MatrixReadOut::getFooter()
957//----------------------------------------------------------------------------//
959 //
960 // copy the pointer to CMA "CMpointer" in "m_CM" member
961 //
962 m_CM = CMpointer;
963 m_CM->reset();
964 ubit16 sidemat = 0;
965 ubit16 layer = 0;
966 ubit16 stripaddress = 0;
967 const ubit16 ROOffset = 2;
968
969 for (ubit16 n = 0; n < m_numberOfWordsInBody; n++) {
971 ubit16 IJK = locMRO.ijk();
972 ubit16 CHANNEL = locMRO.global_channel();
973 ubit16 BCID = locMRO.bcid();
974 ubit16 TIME = locMRO.time();
975 float absTime = 0.;
976
977 //
978 // select CMA strip data (IJK from 0 to 5; 6 and 7 are for trigger data
979 //
980 if (IJK < 6) {
981 switch (IJK) {
982 case 0:
983 sidemat = 0;
984 layer = 0;
985 stripaddress = CHANNEL;
986 break;
987 case 1:
988 sidemat = 0;
989 layer = 1;
990 stripaddress = CHANNEL;
991 break;
992 case 2:
993 sidemat = 1;
994 layer = 0;
995 stripaddress = CHANNEL;
996 break;
997 case 3:
998 sidemat = 1;
999 layer = 0;
1000 stripaddress = CHANNEL;
1001 break;
1002 case 4:
1003 sidemat = 1;
1004 layer = 1;
1005 stripaddress = CHANNEL;
1006 break;
1007 case 5:
1008 sidemat = 1;
1009 layer = 1;
1010 stripaddress = CHANNEL;
1011 break;
1012 default: throw std::runtime_error("MatrixReadOut::doMatrix: IJK= " + std::to_string(IJK) + " out of RANGE");
1013 } // end-of-switch
1014 //
1015 // estimate absolute time from CMA time
1016 //
1017 absTime = 25. * ((float)BCID + ((float)(TIME - ROOffset)) / 8.);
1018 m_CM->putData(sidemat, layer, stripaddress, absTime);
1019 } // end-of-if(IJK<6
1020 } // end-of-for(ubit16 n
1021 //
1022 // use the Matrix data buffer from the the first available location and not
1023 // at the center as it is done by default
1024 //
1025 m_CM->setBCzero(0);
1026 //
1027 // run the CMA logic
1028 //
1029 m_CM->execute();
1030} // end-of-MatrixReadOut::doMatrix()
1031//----------------------------------------------------------------------------//
1032void MatrixReadOut::makeTestPattern(ubit16 mode, ubit16 ktimes, int eventNum) {
1033 std::cout << " makeTestPattern " << std::endl;
1034 MatrixReadOutStructure MRS = getHeader(); // get the m_CM Header
1035 ubit16 cmid = MRS.cmid(); // m_CM Address (or identifier)
1036 //
1037 ofstream vhdlinput;
1038 vhdlinput.open("vhdl.input", ios::app);
1039 if (!vhdlinput) { cout << " File for vhdl analysis not opened. " << endl << " ==================================" << endl << endl; };
1040 //
1041 const ubit16 maxchan = 100;
1042 const ubit16 maxtimes = 200;
1043 ubit16 IJ[maxtimes][4], channels[maxtimes][4][maxchan];
1044 float times[maxtimes] = {0};
1045 char plane[4][3];
1046 strcpy(plane[0], "I0");
1047 strcpy(plane[1], "I1");
1048 strcpy(plane[2], "J0");
1049 strcpy(plane[3], "J1");
1050 ubit16 ntimes = 0;
1051 for (ubit16 l = 0; l < maxtimes; l++) {
1052 for (ubit16 i = 0; i < 4; i++) { IJ[l][i] = 0; }
1053 }
1054
1055 float timeover = 999999.;
1056 bool completed = false;
1057 float timelast = -timeover;
1058
1059 std::cout << this << std::endl;
1060
1061 while (!completed) {
1062 float timemin = timeover;
1063 for (int iCMhit = 0; iCMhit < m_numberOfWordsInBody; iCMhit++) {
1064 MatrixReadOutStructure MRS = getCMAHit(iCMhit);
1065 int ijk = MRS.ijk();
1066 if (ijk < 6) {
1067 float time = ((float)(MRS.bcid() * 8 + MRS.time()) - 0.5) * 3.125;
1068 // int channel=MRS.global_channel(); // m_CM channel
1069 // std::cout<<"time "<<time<<" IJK= "<<ijk<<" channel "<<channel<<std::endl;
1070 if (time > timelast && time < timemin) timemin = time;
1071 } // end-of-if(
1072 } // end-of-for(
1073
1074 if (timemin == timeover) {
1075 completed = true;
1076 } else {
1077 ubit16 this_time_counter = 0;
1078 for (int iCMhit = 0; iCMhit < m_numberOfWordsInBody; iCMhit++) {
1079 MatrixReadOutStructure MRS = getCMAHit(iCMhit);
1080 int ijk = MRS.ijk();
1081 if (ijk < 6) {
1082 int channel = MRS.global_channel(); // m_CM channel
1083 float time = ((float)(MRS.bcid() * 8 + MRS.time()) - 0.5) * 3.125;
1084 if (time == timemin && ntimes < maxtimes) {
1085 if (!this_time_counter) ntimes++;
1086 this_time_counter++;
1087 ubit16 ijk_index = 0;
1088 if (ijk == 0)
1089 ijk_index = 0;
1090 else if (ijk == 1)
1091 ijk_index = 1;
1092 else if (ijk == 2 || ijk == 3)
1093 ijk_index = 2;
1094 else if (ijk == 4 || ijk == 5)
1095 ijk_index = 3;
1096 times[ntimes - 1] = time;
1097 if (IJ[ntimes - 1][ijk_index] < maxchan) {
1098 IJ[ntimes - 1][ijk_index]++;
1099 channels[ntimes - 1][ijk_index][IJ[ntimes - 1][ijk_index] - 1] = channel;
1100 } // end-of-if
1101 } // end-of-if(time==timemin
1102 } // end-of-if(
1103 } // end-of-for(
1104 timelast = timemin;
1105 // std::cout<<" time min found: "<<timelast<<std::endl;
1106 }
1107 } // end-of-while
1108
1109 if (mode) {
1110 int NBunch = 0;
1111 int run = 0;
1112 vhdlinput << " RUN " << run << " EVENT " << eventNum << " CMID " << cmid << " WINDOW " << NBunch;
1113 vhdlinput << " LINES " << (ntimes + ktimes) << '\n';
1114 } // end-of-if(mode
1115 for (ubit16 l = 0; l < ntimes; l++) {
1116 vhdlinput << " TIME " << times[l] << " ";
1117 for (ubit16 i = 0; i < 4; i++) {
1118 vhdlinput << plane[i][0] << plane[i][1] << " " << IJ[l][i] << " ";
1119 for (ubit16 j = 0; j < IJ[l][i]; j++) { vhdlinput << channels[l][i][j] << " "; } // end-of-for(j
1120 } // end-of-for(i
1121 vhdlinput << '\n';
1122 } // end-of-for(l
1123 //
1124 vhdlinput.close();
1125} // 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
STL namespace.
void initialize()
int run(int argc, char *argv[])