Commit 4608124b authored by David Cussans's avatar David Cussans

Added some protection against buffer over-run. Unfortunately doesn't work at start of run ....

git-svn-id: https://svn2.phy.bris.ac.uk/svn/uob-hep-pc049a/trunk@43 e1591323-3689-4d5a-aa31-d1a7cbdc5706
parent d64c82c3
......@@ -136,6 +136,11 @@ class MarocDAQ(object):
return eventData
def resetADCPointers(self):
"""Resets read and write pointers. Hopefully doesn't reset event counter ...."""
self.board.write("adc0Ctrl",0x00000002)
self.adcReadPointer = self.numMaroc*[0]
def decodeADCData(self,adcEventData):
"""Takes data from a single ADC, unpacks it into 12-bit words, performs Gray coding and returns an array of 64-ADC values.
*** NB. This doesn't seem to work correctly at the moment ****"""
......
......@@ -5,6 +5,7 @@ import logging
from PyChipsUser import *
# N.B. Root Histogramming doesn't play nicely with multi-processing
#import threading
from threading import Thread
......@@ -12,6 +13,7 @@ import time
#import Queue
from Queue import Queue
#from multiprocessing import Queue
import MarocHistograms
......
......@@ -7,7 +7,7 @@ from ROOT import TCanvas, TF1 , TH1F , gRandom , gBenchmark
from time import sleep , time
from math import sqrt
from math import sqrt, log10
import logging
from marocLogging import marocLogging
......@@ -21,11 +21,18 @@ class MarocHistograms(object):
self.nPlotsPerCanvas = nPlotsPerCanvas
self.debugLevel = debugLevel
self.histoColour = histoColour
self.canvases = []
self.histograms = []
self.canvasNames = []
self.canvasTitles = []
self.canvasList = []
self.adcHistograms = []
self.adcCanvasNames = []
self.adcCanvasTitles = []
self.adcCanvasList = []
self.timingHistograms = []
self.timingCanvasNames = []
self.timingCanvasTitles = []
self.timingCanvasList = []
self.previousTimeStamp = -10
self.histosLastUpdated = time()
self.histoUpdateInterval = histoUpdateInterval
self.logger = logging.getLogger(__name__)
......@@ -34,26 +41,26 @@ class MarocHistograms(object):
def createHistograms(self): #canvases , histograms , nBits , nPlots , nPlotsPerCanvas , debugLevel):
"""Creates a set of ROOT histograms on several different canvasses. Number of canvasses, number of bins etc. taken from arguments"""
# ----------------------
# First book histograms for the ADC data
# ----------------------
assert(self.nPlots%self.nPlotsPerCanvas == 0),"Number of plots per canvas must be a factor of number-of-plots"
nCanvas = self.nPlots/self.nPlotsPerCanvas
nPlotsPerDirection = int(sqrt(self.nPlotsPerCanvas))
nBins = 2**self.nBits
self.canvasNames = [ "c%s"%canvas for canvas in range(nCanvas) ]
self.canvasTitles = [ "ADC Value for Channels %s - %s"%(canvas*self.nPlotsPerCanvas , (canvas+1)*self.nPlotsPerCanvas -1) for canvas in range(nCanvas) ]
self.adcCanvasNames = [ "c%s"%canvas for canvas in range(nCanvas) ]
self.adcCanvasTitles = [ "ADC Value for Channels %s - %s"%(canvas*self.nPlotsPerCanvas , (canvas+1)*self.nPlotsPerCanvas -1) for canvas in range(nCanvas) ]
#print self.canvasNames
#print self.canvasTitles
self.adcCanvasList = [ TCanvas(self.adcCanvasNames[chan],self.adcCanvasTitles[chan],600,400) for chan in range(nCanvas) ]
self.canvasList = [ TCanvas(self.canvasNames[chan],self.canvasTitles[chan],600,400) for chan in range(nCanvas) ]
self.histograms = []
self.adcHistograms = []
# sorry, this next bit isn't very Pythonesque
for canvasIndex in range(nCanvas):
canvas = self.canvasList[canvasIndex]
canvas = self.adcCanvasList[canvasIndex]
canvas.cd(0) # change to current canvas
canvas.Divide(nPlotsPerDirection,nPlotsPerDirection)
......@@ -74,7 +81,28 @@ class MarocHistograms(object):
histo.Draw("elp")
canvas.Update()
self.histograms.append( histo )
self.adcHistograms.append( histo )
# ----------------------
# Now book histograms for the timing/timestamp data
# ----------------------
nTimestampBins = 10000
self.timingCanvasNames = [ "ct1" ]
self.timingCanvasTitles = [ "Timestamp difference ( w.r.t. previous event)" ]
self.timingCanvasList = [ TCanvas(self.timingCanvasNames[0],self.timingCanvasTitles[0],600,400) ]
# set the maximum interval between timestamps we want to histogram
maxTime = 1.0
# each timestamp count is 32ns ( 1/(31250000 Hz) )
maxCounts = 31250000*maxTime
logMaxCounts = log10(maxCounts)
timingHisto = TH1F("deltaTimestamp","Logarithm of difference in Timestamp w.r.t previous Event",nTimestampBins,-0.5,logMaxCounts-0.5)
self.timingHistograms = [ timingHisto ]
#print "Timing Histo (booking) = " , self.timingHistograms[0]
self.timingCanvasList[0].cd()
timingHisto.Draw("elp")
self.timingCanvasList[0].Update()
def fillHistograms( self, eventNumber, timeStamp , ADCData ):
......@@ -84,4 +112,18 @@ class MarocHistograms(object):
self.logger.debug("Histogramming data = \n%s"%( ' , '.join([format(i,'08x') for i in ADCData ]) ))
for ADCIndex in range(0,len(ADCData)):
self.histograms[ADCIndex].Fill(ADCData[ADCIndex])
self.logger.debug("Filling histogram for channel %i"%ADCIndex)
self.adcHistograms[ADCIndex].Fill(ADCData[ADCIndex])
# Fill time-stamp histogram
deltaTimeStamp = timeStamp - self.previousTimeStamp
self.logger.debug("event , time-stamp, previous time-stamp, delta = %i %i %i %i"%( eventNumber , timeStamp , self.previousTimeStamp , deltaTimeStamp ))
self.previousTimeStamp = timeStamp
timingHisto = self.timingHistograms[0]
# print "Timing Histo (filling) = " , timingHisto
if deltaTimeStamp > 0:
timingHisto.Fill( log10(deltaTimeStamp) )
......@@ -7,11 +7,13 @@ from PyChipsUser import *
#import threading
from threading import Thread
#from multiprocessing import Process as Thread
import time
#import Queue
from Queue import Queue
#from multiprocessing import Queue
import MarocDAQ
......@@ -28,6 +30,7 @@ class MarocReadoutThread(Thread):
self.numTriggers = numTriggers
self.debugLevel = debugLevel
self.logger = logging.getLogger(__name__)
self.lastEventRead = -1
def run(self):
......@@ -35,12 +38,12 @@ class MarocReadoutThread(Thread):
self.logger.info( "Starting thread. Event limit = %i" %(self.numTriggers) )
readout_maroc(self.name, self.board , self.rawDataQueue , self.numTriggers , self.logger , self.debugLevel)
self.readout_maroc(self.name, self.board , self.rawDataQueue , self.numTriggers , self.logger , self.debugLevel)
self.logger.info( "Exiting thread" )
def readout_maroc(name, board , rawDataQueue , numTriggers , logger , debugLevel):
def readout_maroc(self, name, board , rawDataQueue , numTriggers , logger , debugLevel):
exitFlag = False
......@@ -55,6 +58,16 @@ def readout_maroc(name, board , rawDataQueue , numTriggers , logger , debugLevel
# fill the queue
for event in events:
eventNumber = event[0]
# Try to detect and recover from buffer over-run
if (eventNumber != self.lastEventRead +1) and (self.lastEventRead != -1) :
logger.warn("Buffer over-run detected! Event read = %i , previous event = %i . Resetting read and write pointers " %(eventNumber,self.lastEventRead))
marocData.resetADCPointers()
self.lastEventRead = -1
break # break out of loop and read another block of data.
self.lastEventRead = eventNumber
logger.info("Read event %i",eventNumber)
if ( eventNumber > numTriggers):
......@@ -63,6 +76,8 @@ def readout_maroc(name, board , rawDataQueue , numTriggers , logger , debugLevel
logger.debug("Pushing data into raw data queue = \n%s"%( ' , '.join([format(i,'08x') for i in event ]) ))
rawDataQueue.put(event)
# TODO - set exit flag when told to by run control. Start and stop run when told to by run control.
poisonPill = [-1]
......
......@@ -7,11 +7,13 @@ from PyChipsUser import *
#import threading
from threading import Thread
#from multiprocessing import Process as Thread
import time
#import Queue
from Queue import Queue
#from multiprocessing import Queue
import MarocRecording
......
......@@ -84,7 +84,8 @@ class MarocSC(object):
# Data structure to store the names of FPGA registers to write into. The key name is the register name value is [default,description,comment]
self.registers = {
'trigSourceSelect':[ 0x0000000D , 'Set source of triggers.' , 'There can be more than one trigger input active at the same time. 0xD turns on OR1 , OR2 and internal triggers']
'trigSourceSelect':[ 0x0000000D , 'Set source of triggers.' , 'There can be more than one trigger input active at the same time. 0xD turns on OR1 , OR2 and internal triggers'] ,
'trigHold1Delay':[ 0x00000000 , 'Set delay between trigger and Hold1 being asserted' , 'In units of fastClock ticks = 8ns']
}
# Copy default register values into dictionary
for registerName in self.registers.keys():
......
......@@ -12,11 +12,13 @@ from PyChipsUser import *
#import threading
from threading import Thread
#from multiprocessing import Process as Thread
import time
#import Queue
from Queue import Queue
#from multiprocessing import Queue
import array
......@@ -126,6 +128,11 @@ def unpack_maroc_data(name, rawDataQueue , recordingDataQueue, histogramDataQueu
poisonPill = [-1]
histogramDataQueue.put(poisonPill)
logger.info("Fed poison pill to histogrammer")
# Bodge - give time for histogrammer to fill the last histogram before sending poison pill to data recorder.
# If the ROOT file is closed the histograms become undefined....
time.sleep(2.0)
recordingDataQueue.put(poisonPill)
logger.info("Fed poison pill to data recorder")
......@@ -22,6 +22,7 @@ from PyChipsUser import *
#import Queue
from Queue import Queue
#from multiprocessing import Queue
logger = logging.getLogger(__name__)
marocLogging(logger,logging.DEBUG)
......@@ -54,8 +55,10 @@ firmwareID = board.read("FirmwareId")
logger.info("Firmware ID = %s" % (hex(firmwareID)))
debugLevel = logging.INFO
# Create object with configuration information - in the long run this should be done in a separate thread with a GUI
marocConfiguration = MarocConfiguration.MarocConfiguration(board,configurationFile = options.configFile , debugLevel=logging.DEBUG)
marocConfiguration = MarocConfiguration.MarocConfiguration(board,configurationFile = options.configFile , debugLevel=debugLevel)
rawDataQueue = Queue()
......@@ -64,15 +67,17 @@ recordingDataQueue = Queue()
histogramQueueSize = 100
histogramDataQueue = Queue(histogramQueueSize)
# Create a readout thread. Pass down an event limit. When the event limit is reached the readout thread will pass a message along chain and threads will terminate.
readoutThread = MarocReadoutThread.MarocReadoutThread(1,"readoutThread",board,rawDataQueue,numTriggers,debugLevel=logging.INFO)
readoutThread = MarocReadoutThread.MarocReadoutThread(1,"readoutThread",board,rawDataQueue,numTriggers,debugLevel=debugLevel)
unpackerThread = MarocUnpackingThread.MarocUnpackingThread(2,"unpackingThread",rawDataQueue,recordingDataQueue,histogramDataQueue,debugLevel=logging.INFO)
unpackerThread = MarocUnpackingThread.MarocUnpackingThread(2,"unpackingThread",rawDataQueue,recordingDataQueue,histogramDataQueue,debugLevel=debugLevel)
histogramThread = MarocHistogrammingThread.MarocHistogrammingThread(3,"histogrammingThread",histogramDataQueue,debugLevel=logging.INFO)
histogramThread = MarocHistogrammingThread.MarocHistogrammingThread(3,"histogrammingThread",histogramDataQueue,debugLevel=debugLevel)
recordingThread = MarocRecordingThread.MarocRecordingThread(3,"recordingThread",recordingDataQueue,fileName=options.outputFile, debugLevel=logging.INFO)
recordingThread = MarocRecordingThread.MarocRecordingThread(3,"recordingThread",recordingDataQueue,fileName=options.outputFile, debugLevel=debugLevel)
# Send configuration to board.
......
......@@ -49,4 +49,5 @@ DAC = 650,450
[registers]
trigSourceSelect = 13
trigHold1Delay = 0
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment