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): ...@@ -136,6 +136,11 @@ class MarocDAQ(object):
return eventData 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): 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. """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 ****""" *** NB. This doesn't seem to work correctly at the moment ****"""
......
...@@ -5,6 +5,7 @@ import logging ...@@ -5,6 +5,7 @@ import logging
from PyChipsUser import * from PyChipsUser import *
# N.B. Root Histogramming doesn't play nicely with multi-processing
#import threading #import threading
from threading import Thread from threading import Thread
...@@ -12,6 +13,7 @@ import time ...@@ -12,6 +13,7 @@ import time
#import Queue #import Queue
from Queue import Queue from Queue import Queue
#from multiprocessing import Queue
import MarocHistograms import MarocHistograms
......
...@@ -7,7 +7,7 @@ from ROOT import TCanvas, TF1 , TH1F , gRandom , gBenchmark ...@@ -7,7 +7,7 @@ from ROOT import TCanvas, TF1 , TH1F , gRandom , gBenchmark
from time import sleep , time from time import sleep , time
from math import sqrt from math import sqrt, log10
import logging import logging
from marocLogging import marocLogging from marocLogging import marocLogging
...@@ -21,11 +21,18 @@ class MarocHistograms(object): ...@@ -21,11 +21,18 @@ class MarocHistograms(object):
self.nPlotsPerCanvas = nPlotsPerCanvas self.nPlotsPerCanvas = nPlotsPerCanvas
self.debugLevel = debugLevel self.debugLevel = debugLevel
self.histoColour = histoColour self.histoColour = histoColour
self.canvases = []
self.histograms = [] self.adcHistograms = []
self.canvasNames = [] self.adcCanvasNames = []
self.canvasTitles = [] self.adcCanvasTitles = []
self.canvasList = [] self.adcCanvasList = []
self.timingHistograms = []
self.timingCanvasNames = []
self.timingCanvasTitles = []
self.timingCanvasList = []
self.previousTimeStamp = -10
self.histosLastUpdated = time() self.histosLastUpdated = time()
self.histoUpdateInterval = histoUpdateInterval self.histoUpdateInterval = histoUpdateInterval
self.logger = logging.getLogger(__name__) self.logger = logging.getLogger(__name__)
...@@ -34,26 +41,26 @@ class MarocHistograms(object): ...@@ -34,26 +41,26 @@ class MarocHistograms(object):
def createHistograms(self): #canvases , histograms , nBits , nPlots , nPlotsPerCanvas , debugLevel): 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""" """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" assert(self.nPlots%self.nPlotsPerCanvas == 0),"Number of plots per canvas must be a factor of number-of-plots"
nCanvas = self.nPlots/self.nPlotsPerCanvas nCanvas = self.nPlots/self.nPlotsPerCanvas
nPlotsPerDirection = int(sqrt(self.nPlotsPerCanvas)) nPlotsPerDirection = int(sqrt(self.nPlotsPerCanvas))
nBins = 2**self.nBits nBins = 2**self.nBits
self.canvasNames = [ "c%s"%canvas for canvas in range(nCanvas) ] self.adcCanvasNames = [ "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.adcCanvasTitles = [ "ADC Value for Channels %s - %s"%(canvas*self.nPlotsPerCanvas , (canvas+1)*self.nPlotsPerCanvas -1) for canvas in range(nCanvas) ]
#print self.canvasNames self.adcCanvasList = [ TCanvas(self.adcCanvasNames[chan],self.adcCanvasTitles[chan],600,400) for chan in range(nCanvas) ]
#print self.canvasTitles
self.canvasList = [ TCanvas(self.canvasNames[chan],self.canvasTitles[chan],600,400) for chan in range(nCanvas) ] self.adcHistograms = []
self.histograms = []
# sorry, this next bit isn't very Pythonesque # sorry, this next bit isn't very Pythonesque
for canvasIndex in range(nCanvas): for canvasIndex in range(nCanvas):
canvas = self.canvasList[canvasIndex] canvas = self.adcCanvasList[canvasIndex]
canvas.cd(0) # change to current canvas canvas.cd(0) # change to current canvas
canvas.Divide(nPlotsPerDirection,nPlotsPerDirection) canvas.Divide(nPlotsPerDirection,nPlotsPerDirection)
...@@ -74,7 +81,28 @@ class MarocHistograms(object): ...@@ -74,7 +81,28 @@ class MarocHistograms(object):
histo.Draw("elp") histo.Draw("elp")
canvas.Update() 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 ): def fillHistograms( self, eventNumber, timeStamp , ADCData ):
...@@ -84,4 +112,18 @@ class MarocHistograms(object): ...@@ -84,4 +112,18 @@ class MarocHistograms(object):
self.logger.debug("Histogramming data = \n%s"%( ' , '.join([format(i,'08x') for i in ADCData ]) )) self.logger.debug("Histogramming data = \n%s"%( ' , '.join([format(i,'08x') for i in ADCData ]) ))
for ADCIndex in range(0,len(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 * ...@@ -7,11 +7,13 @@ from PyChipsUser import *
#import threading #import threading
from threading import Thread from threading import Thread
#from multiprocessing import Process as Thread
import time import time
#import Queue #import Queue
from Queue import Queue from Queue import Queue
#from multiprocessing import Queue
import MarocDAQ import MarocDAQ
...@@ -28,6 +30,7 @@ class MarocReadoutThread(Thread): ...@@ -28,6 +30,7 @@ class MarocReadoutThread(Thread):
self.numTriggers = numTriggers self.numTriggers = numTriggers
self.debugLevel = debugLevel self.debugLevel = debugLevel
self.logger = logging.getLogger(__name__) self.logger = logging.getLogger(__name__)
self.lastEventRead = -1
def run(self): def run(self):
...@@ -35,37 +38,49 @@ class MarocReadoutThread(Thread): ...@@ -35,37 +38,49 @@ class MarocReadoutThread(Thread):
self.logger.info( "Starting thread. Event limit = %i" %(self.numTriggers) ) 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" ) 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 exitFlag = False
# Create pointer to MAROC board and set up structures. # Create pointer to MAROC board and set up structures.
marocData = MarocDAQ.MarocDAQ(board,debugLevel) marocData = MarocDAQ.MarocDAQ(board,debugLevel)
while not exitFlag: while not exitFlag:
# Read data from MAROC # Read data from MAROC
events = marocData.readADCData() events = marocData.readADCData()
# fill the queue # fill the queue
for event in events: for event in events:
eventNumber = event[0] eventNumber = event[0]
logger.info("Read event %i",eventNumber)
# Try to detect and recover from buffer over-run
if ( eventNumber > numTriggers): if (eventNumber != self.lastEventRead +1) and (self.lastEventRead != -1) :
exitFlag = True logger.warn("Buffer over-run detected! Event read = %i , previous event = %i . Resetting read and write pointers " %(eventNumber,self.lastEventRead))
logger.info("Setting exitFlag = True") marocData.resetADCPointers()
logger.debug("Pushing data into raw data queue = \n%s"%( ' , '.join([format(i,'08x') for i in event ]) )) self.lastEventRead = -1
rawDataQueue.put(event) break # break out of loop and read another block of data.
# TODO - set exit flag when told to by run control. Start and stop run when told to by run control. self.lastEventRead = eventNumber
poisonPill = [-1] logger.info("Read event %i",eventNumber)
rawDataQueue.put(poisonPill)
logger.info("Fed poison pill to unpacker") if ( eventNumber > numTriggers):
exitFlag = True
logger.info("Setting exitFlag = True")
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]
rawDataQueue.put(poisonPill)
logger.info("Fed poison pill to unpacker")
...@@ -7,11 +7,13 @@ from PyChipsUser import * ...@@ -7,11 +7,13 @@ from PyChipsUser import *
#import threading #import threading
from threading import Thread from threading import Thread
#from multiprocessing import Process as Thread
import time import time
#import Queue #import Queue
from Queue import Queue from Queue import Queue
#from multiprocessing import Queue
import MarocRecording import MarocRecording
......
...@@ -84,7 +84,8 @@ class MarocSC(object): ...@@ -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] # 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 = { 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 # Copy default register values into dictionary
for registerName in self.registers.keys(): for registerName in self.registers.keys():
......
...@@ -12,11 +12,13 @@ from PyChipsUser import * ...@@ -12,11 +12,13 @@ from PyChipsUser import *
#import threading #import threading
from threading import Thread from threading import Thread
#from multiprocessing import Process as Thread
import time import time
#import Queue #import Queue
from Queue import Queue from Queue import Queue
#from multiprocessing import Queue
import array import array
...@@ -126,6 +128,11 @@ def unpack_maroc_data(name, rawDataQueue , recordingDataQueue, histogramDataQueu ...@@ -126,6 +128,11 @@ def unpack_maroc_data(name, rawDataQueue , recordingDataQueue, histogramDataQueu
poisonPill = [-1] poisonPill = [-1]
histogramDataQueue.put(poisonPill) histogramDataQueue.put(poisonPill)
logger.info("Fed poison pill to histogrammer") 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) recordingDataQueue.put(poisonPill)
logger.info("Fed poison pill to data recorder") logger.info("Fed poison pill to data recorder")
...@@ -22,6 +22,7 @@ from PyChipsUser import * ...@@ -22,6 +22,7 @@ from PyChipsUser import *
#import Queue #import Queue
from Queue import Queue from Queue import Queue
#from multiprocessing import Queue
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
marocLogging(logger,logging.DEBUG) marocLogging(logger,logging.DEBUG)
...@@ -54,8 +55,10 @@ firmwareID = board.read("FirmwareId") ...@@ -54,8 +55,10 @@ firmwareID = board.read("FirmwareId")
logger.info("Firmware ID = %s" % (hex(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 # 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() rawDataQueue = Queue()
...@@ -64,15 +67,17 @@ recordingDataQueue = Queue() ...@@ -64,15 +67,17 @@ recordingDataQueue = Queue()
histogramQueueSize = 100 histogramQueueSize = 100
histogramDataQueue = Queue(histogramQueueSize) 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. # 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. # Send configuration to board.
......
...@@ -49,4 +49,5 @@ DAC = 650,450 ...@@ -49,4 +49,5 @@ DAC = 650,450
[registers] [registers]
trigSourceSelect = 13 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