Commit eea2c1cc authored by dauncey's avatar dauncey

More DAQ buffering classes

parent 6bdfd169
...@@ -54,7 +54,7 @@ public: ...@@ -54,7 +54,7 @@ public:
} }
unsigned used() const { unsigned used() const {
if(fReadPtr<fWritePtr) return fWritePtr-fReadPtr; if(fReadPtr<=fWritePtr) return fWritePtr-fReadPtr;
return fWritePtr+CircularBufferLength-fReadPtr; return fWritePtr+CircularBufferLength-fReadPtr;
} }
......
#ifndef CircularBufferUR_HH
#define CircularBufferUR_HH
// Write pointer points to next location to write to
// Read pointer points to next location to read from
#include "MultipleUltraRam.hh"
template <unsigned NumberOfUltraRams>
class CircularBufferUR {
public:
enum {
CircularBufferURLength=NumberOfUltraRams*UltraRam::UltraRamBufferLength
};
CircularBufferUR() {
reset();
}
bool writeAndIncrementPtr(uint64_t d) {
if(((fWritePtr+1)%CircularBufferURLength)==fReadPtr) return false;
fMultipleUltraRam.write(fWritePtr,d);
fWritePtr++;
if(fWritePtr>=CircularBufferURLength) fWritePtr-=CircularBufferURLength;
return true;
}
bool read(uint64_t& d) const {
if(fReadPtr==fWritePtr) return false;
d=fMultipleUltraRam.read(fReadPtr);
return true;
}
bool incrementReadPtr() {
if(fReadPtr==fWritePtr) return false;
fReadPtr++;
if(fReadPtr>=CircularBufferURLength) fReadPtr-=CircularBufferURLength;
return true;
}
bool readAndIncrementPtr(uint64_t& d) {
if(!read(d)) return false;
return incrementReadPtr();
}
unsigned space() const {
if(fWritePtr<fReadPtr) return fReadPtr-fWritePtr-1;
return fReadPtr+CircularBufferURLength-fWritePtr-1;
}
unsigned used() const {
if(fReadPtr<=fWritePtr) return fWritePtr-fReadPtr;
return fWritePtr+CircularBufferURLength-fReadPtr;
}
bool empty() const {
return fWritePtr==fReadPtr;
}
void reset() {
fWritePtr=0;
fReadPtr=0;
}
private:
MultipleUltraRam<NumberOfUltraRams> fMultipleUltraRam;
unsigned fWritePtr;
unsigned fReadPtr;
};
#endif
#ifndef EconAna_HH
#define EconAna_HH
#include <iostream>
#include <iomanip>
#include <cassert>
#include "TH1D.h"
#include "TH2D.h"
#include "TH1I.h"
#include "Buffering/EconSim.hh"
class EconAna {
public:
EconAna(const EconSim &e, unsigned nHistory=100000) :
fEconSim(e) {
std::ostringstream sout;
sout << "EconAna" << std::setw(2) << std::setfill('0')
<< fEconSim.econNumber();
std::string sHgcroc[18]={"00","01","02","03","04","05","06","07","08",
"09","10","11","12","13","14","15","16","17"};
hMapWordsVsChannels=new TH1I((sout.str()+"MapWordsVsChannels").c_str(),
";Number of channels per HGCROC packet;Number of words per HGCROC packet",73,0,73);
hLabelWordsVsChannels=new TH1I((sout.str()+"LabelWordsVsChannels").c_str(),
";Number of channels per HGCROC packet;Number of words per HGCROC packet",73,0,73);
hTotalWords=new TH1D((sout.str()+"TotalWords").c_str(),
";Total number of words",1000,0,1000);
hEventBufferUsed=new TH1D((sout.str()+"EventBufferUsed").c_str(),
";Number of event buffer words used",10000,0,10000);
hEventBufferUsedHistory=new TH1I((sout.str()+"EventBufferUsedHistory").c_str(),
";BX;Number of event buffer words used",nHistory,0,nHistory);
for(unsigned c(0);c<=72;c++) {
hMapWordsVsChannels->Fill(c,fEconSim.channelsToWords(c,true));
hLabelWordsVsChannels->Fill(c,fEconSim.channelsToWords(c,false));
}
for(unsigned h(0);h<18;h++) {
hChannels[h]=new TH1D((sout.str()+"Hgcroc"+sHgcroc[h]+"Channels").c_str(),
";Number of channels per HGCROC packet",73,0,73);
hWords[h]=new TH1D((sout.str()+"Hgcroc"+sHgcroc[h]+"Words").c_str(),
";Number of words per HGCROC packet",60,0,60);
hWordsVsChannels[h]=new TH2D((sout.str()+"Hgcroc"+sHgcroc[h]+"WordsVsChannels").c_str(),
";Number of channels per HGCROC packet;Number of words per HGCROC packet",73,0,73,60,0,60);
}
}
void analyseZs(uint64_t bx) {
unsigned nWords(0);
for(unsigned h(0);h<18;h++) {
hChannels[h]->Fill(fEconSim.numberOfChannels(h));
hWords[h]->Fill(fEconSim.numberOfWords(h));
hWordsVsChannels[h]->Fill(fEconSim.numberOfChannels(h),fEconSim.numberOfWords(h));
nWords+=fEconSim.numberOfWords(h);
}
hTotalWords->Fill(nWords);
}
void analyseBx(uint64_t bx) {
hEventBufferUsed->Fill(fEconSim.fEventBuffer.used());
hEventBufferUsedHistory->Fill(bx,fEconSim.fEventBuffer.used());
}
private:
const EconSim &fEconSim;
TH1I *hMapWordsVsChannels;
TH1I *hLabelWordsVsChannels;
TH1D *hChannels[18];
TH1D *hWords[18];
TH2D *hWordsVsChannels[18];
TH1D *hTotalWords;
TH1D *hEventBufferUsed;
TH1I *hEventBufferUsedHistory;
};
#endif
This diff is collapsed.
#ifndef HgcrocAna_HH
#define HgcrocAna_HH
#include <iostream>
#include <iomanip>
#include <cassert>
#include "TH1D.h"
#include "TH1I.h"
#include "Buffering/HgcrocSim.hh"
class HgcrocAna {
public:
HgcrocAna(const HgcrocSim &h, unsigned nHistory=100000) :
fHgcrocSim(h), fBusyLength(0) {
unsigned bd(fHgcrocSim.bufferDepth());
std::string sName("HgcrocAna");
hEvents=new TH1D((sName+"Events").c_str(),
";Number of events in buffer;BXs",bd,0,bd);
hL1AEvents=new TH1D((sName+"L1AEvents").c_str(),
";Number of events in buffer;L1Accepts",bd,0,bd);
hBusyLength=new TH1D((sName+"BusyLength").c_str(),
";Length of continuous output (Events);Number",1000,0,1000);
hL1AcceptHistory=new TH1I((sName+"L1AcceptHistory").c_str(),
";BX;L1Accept",nHistory,0,nHistory);
hEventCompleteHistory=new TH1I((sName+"EventCompleteHistory").c_str(),
";BX;Event complete",nHistory,0,nHistory);
hEventsHistory=new TH1I((sName+"EventsHistory").c_str(),
";BX;Number of events in buffer",nHistory,0,nHistory);
hWordsHistory=new TH1I((sName+"WordsHistory").c_str(),
";BX;Number of words transmitted",nHistory,0,nHistory);
}
void analyseBx(uint64_t bx) {
hEvents->Fill(fHgcrocSim.numberOfEvents());
if(fHgcrocSim.l1Accept()) {
hL1AEvents->Fill(fHgcrocSim.numberOfEvents());
hL1AcceptHistory->Fill(bx,3);
}
if(fHgcrocSim.eventComplete()) hEventCompleteHistory->Fill(bx,2);
hEventsHistory->Fill(bx,fHgcrocSim.numberOfEvents());
hWordsHistory->Fill(bx,fHgcrocSim.numberOfWords());
if(fHgcrocSim.numberOfEvents()>0) fBusyLength++;
else {
if(fBusyLength!=0) {
hBusyLength->Fill((fBusyLength+1)/fHgcrocSim.eventLength());
fBusyLength=0;
}
}
}
private:
const HgcrocSim &fHgcrocSim;
unsigned fBusyLength;
TH1D *hEvents;
TH1D *hL1AEvents;
TH1D *hBusyLength;
TH1I *hL1AcceptHistory;
TH1I *hEventCompleteHistory;
TH1I *hEventsHistory;
TH1I *hWordsHistory;
};
#endif
#ifndef HgcrocBoe_HH
#define HgcrocBoe_HH
#include <iostream>
#include <iomanip>
#include <cassert>
class HgcrocBoe {
public:
HgcrocBoe() {
fWord=0x00ff0000; // Non-existant HGCROC value
}
HgcrocBoe(uint32_t w) {
fWord=w;
}
HgcrocBoe(uint8_t e, uint8_t h, uint8_t b, uint8_t l, uint8_t n) {
fWord=(b<<24)+((18*e+h)<<16)+(l<<8)+n;
}
uint8_t bx() const {
return fWord>>24;
}
uint8_t econ() const {
return ((fWord>>16)&0xff)/18;
}
uint8_t hgcroc() const {
return ((fWord>>16)&0xff)%18;
}
uint8_t l1a() const {
return (fWord>>8)&0xff;
}
uint16_t numberOfWords() const {
return fWord&0xff;
}
uint32_t word() const {
return fWord;
}
void word(uint32_t w) {
fWord=w;
}
void print() const {
std::cout << "HgcrocBoe::print() Value = 0x" << std::hex << std::setw(8) << std::setfill('0') << fWord << std::dec << std::endl;
std::cout << " BX = " << unsigned(bx()) << std::endl;
std::cout << " ECON, HGCROC = " << unsigned(econ()) << ", " << unsigned(hgcroc()) << std::endl;
std::cout << " L1Accept = " << unsigned(l1a()) << std::endl;
std::cout << " Number of words = " << unsigned(numberOfWords()) << std::endl;
}
private:
uint32_t fWord;
};
#endif
#ifndef HgcrocSim_HH
#define HgcrocSim_HH
#include <iostream>
#include <iomanip>
#include <cassert>
class HgcrocSim {
public:
HgcrocSim(unsigned e=7, unsigned w=44) : fBufferDepth(1<<e), fEventLength(w) {
if(fPrintLevel>1) {
std::cout << "HgcrocSim::ctor(" << e << "," << w << ")" << std::endl;
}
}
bool processBx(bool l1A=false) {
if(fPrintLevel>4) {
std::cout << "HgcrocSim::processBx(" << (l1A?"true":"false") << ") "
<< "Entered" << std::endl;
}
fL1Accept=l1A;
if(fL1Accept) {
fNumberOfEvents++;
if(fPrintLevel>3) {
std::cout << "HgcrocSim::processBx(" << (l1A?"true":"false") << ") "
<< "L1Accept seen: new number of events in buffer = "
<< fNumberOfEvents << std::endl;
}
}
if(fNumberOfEvents>0) {
if(fPrintLevel>4) {
std::cout << "HgcrocSim::processBx(" << (l1A?"true":"false") << ") "
<< "Number of events in buffer = "
<< fNumberOfEvents << std::endl;
}
fNumberOfWords++;
if(fPrintLevel>4) {
std::cout << "HgcrocSim::processBx(" << (l1A?"true":"false") << ") "
<< "Number of words sent = "
<< fNumberOfWords << std::endl;
}
fEventComplete=(fNumberOfWords==fEventLength);
if(fEventComplete) {
fNumberOfWords=0;
fNumberOfEvents--;
if(fPrintLevel>3) {
std::cout << "HgcrocSim::processBx(" << (l1A?"true":"false") << ") "
<< "Finished sending event: number remaining in buffer = "
<< fNumberOfEvents << std::endl;
}
}
} else {
fEventComplete=false;
}
if(fPrintLevel>4) {
std::cout << "HgcrocSim::processBx(" << (l1A?"true":"false") << ") "
<< "Returning " << (fEventComplete?"true":"false") << std::endl;
}
return fEventComplete;
}
bool allowL1Accept() const {
return fNumberOfEvents<fBufferDepth;
}
unsigned bufferDepth() const {
return fBufferDepth;
}
unsigned eventLength() const {
return fEventLength;
}
bool l1Accept() const {
return fL1Accept;
}
bool eventComplete() const {
return fEventComplete;
}
unsigned numberOfEvents() const {
return fNumberOfEvents;
}
unsigned numberOfWords() const {
return fNumberOfWords;
}
void print() const {
}
public:
static unsigned fPrintLevel;
private:
const unsigned fBufferDepth;
const unsigned fEventLength;
bool fL1Accept;
bool fEventComplete;
unsigned fNumberOfEvents;
unsigned fNumberOfWords;
};
unsigned HgcrocSim::fPrintLevel(1);
#endif
#ifndef LpGbtCheck_HH
#define LpGbtCheck_HH
#include <iostream>
#include <iomanip>
#include <cassert>
class LpGbtCheck {
public:
LpGbtCheck() : fActivePacket(false), fActiveHgcroc(false) {
initialise(-1,-1,0);
}
LpGbtCheck(unsigned s, unsigned e, unsigned h) : fActivePacket(false), fActiveHgcroc(false) {
initialise(s,e,h);
}
void initialise(unsigned s, unsigned e, unsigned h) {
fSlink=s;
fEcon=e;
fNumberOfHgcrocs=h;
}
bool processBx(uint32_t *a) {
if(fPrintLevel>4) {
std::cout << "LpGbtCheck[" << fSlink << "][" << fEcon
<< "]::processBx() "
<< "Entered" << std::endl;
}
for(unsigned e(0);e<7;e++) {
if(fPrintLevel>4) {
std::cout << "LpGbtCheck[" << fSlink << "][" << fEcon
<< "]::processBx() "
<< "Elink " << e << " word = "
<< std::hex << a[e] << std::dec << std::endl;
}
if(!fActivePacket) {
if(a[e]!=0) {
fActivePacket=true;
fActiveHgcroc=true;
for(unsigned h(0);h<fNumberOfHgcrocs;h++) fHgcrocSeen[h]=false;
fHgcroc=0;
checkHeader(a[e],true);
fBx=fHgcrocBoe.bx();
fWords=1;
if(fPrintLevel>4) {
std::cout << "LpGbtCheck[" << fSlink << "][" << fEcon
<< "]::processBx() "
<< "New packet found" << std::endl;
fHgcrocBoe.print();
}
if(fHgcrocBoe.numberOfWords()==1) {
fActiveHgcroc=false;
fHgcrocSeen[fHgcrocBoe.hgcroc()]=true;
if(fPrintLevel>4) {
std::cout << "LpGbtCheck[" << fSlink << "][" << fEcon
<< "]::processBx() "
<< "HGCROC " << unsigned(fHgcrocBoe.hgcroc())
<< " completed" << std::endl;
}
}
}
} else {
assert(a[e]!=0);
/*
if(a[e]==0) {
fActivePacket=false;
if(fPrintLevel>4) {
std::cout << "LpGbtCheck[" << fSlink << "][" << fEcon
<< "]::processBx() "
<< "Packet ended" << std::endl;
}
fL1Accept++;
} else {
*/
if(!fActiveHgcroc) {
fHgcroc++;
checkHeader(a[e],false);
fActiveHgcroc=true;
fWords=1;
if(fPrintLevel>4) {
std::cout << "LpGbtCheck[" << fSlink << "][" << fEcon
<< "]::processBx() "
<< "New HGCROC found" << std::endl;
fHgcrocBoe.print();
}
if(fHgcrocBoe.numberOfWords()==1) {
fActiveHgcroc=false;
fHgcrocSeen[fHgcrocBoe.hgcroc()]=true;
if(fPrintLevel>4) {
std::cout << "LpGbtCheck[" << fSlink << "][" << fEcon
<< "]::processBx() "
<< "HGCROC " << unsigned(fHgcrocBoe.hgcroc())
<< " completed" << std::endl;
}
}
} else {
assert((a[e]>>24)==fL1Accept);
assert((a[e]&0xffffff)==fWords);
fWords++;
if(fWords==fHgcrocBoe.numberOfWords()) {
fActiveHgcroc=false;
fHgcrocSeen[fHgcrocBoe.hgcroc()]=true;
if(fPrintLevel>4) {
std::cout << "LpGbtCheck[" << fSlink << "][" << fEcon
<< "]::processBx() "
<< "HGCROC " << unsigned(fHgcrocBoe.hgcroc())
<< " completed" << std::endl;
}
}
}
bool allSeen(true);
for(unsigned h(0);h<fNumberOfHgcrocs && allSeen;h++) {
allSeen=fHgcrocSeen[h];
}
if(allSeen) {
fActivePacket=false;
if(fPrintLevel>4) {
std::cout << "LpGbtCheck[" << fSlink << "][" << fEcon
<< "]::processBx() "
<< "Packet ended" << std::endl;
}
fL1Accept++;
}
}
}
return true;
}
void checkHeader(uint32_t a, bool first) {
fHgcrocBoe.word(a);
if(first) fBx=fHgcrocBoe.bx();
assert(!fHgcrocSeen[fHgcrocBoe.hgcroc()]);
//fHgcrocSeen[fHgcrocBoe.hgcroc()]=true;
assert(fHgcrocBoe.econ()==fEcon);
assert(fHgcrocBoe.hgcroc()==fHgcroc);
assert(fHgcrocBoe.bx()==fBx);
assert(fHgcrocBoe.l1a()==fL1Accept);
}
static unsigned fPrintLevel;
private:
unsigned fSlink;
unsigned fEcon;
unsigned fNumberOfHgcrocs;
unsigned fHgcroc;
bool fActivePacket;
bool fActiveHgcroc;
uint8_t fL1Accept;
uint8_t fBx;
HgcrocBoe fHgcrocBoe;
unsigned fWords;
bool fHgcrocSeen[18];
};
unsigned LpGbtCheck::fPrintLevel(1);
#endif
#ifndef SlinkBoe_HH
#define SlinkBoe_HH
class SlinkBoe {
public:
SlinkBoe() : fBoe(0) {
}
SlinkBoe(uint32_t si, uint32_t bi, uint32_t ei, uint16_t et)
: fSourceId(si), fBxId(bi), fEventId(ei), fEventType(et), fBoe(0x5555) {
}
uint32_t sourceId() const {
return fSourceId;
}
uint32_t bxId() const {
return fBxId;
}
uint32_t eventId() const {