def stopRecording(): """ Stop recording to disk. If already not recording, this will raise AlreadyError. If streaming was enabled, this will persist after a short blip in the stream. """ if not isRecording(): raise AlreadyError else: wasStreaming = isStreaming() cmds = [] cmd = DC.ControlCommand(type=DC.ControlCommand.ACQUIRE) cmd.acquire.enable = False cmds.append(cmd) if wasStreaming: # turn streaming back on again cmd = DC.ControlCommand(type=DC.ControlCommand.FORWARD) cmd.forward.sample_type = DC.BOARD_SUBSAMPLE cmd.forward.force_daq_reset = True aton = socket.inet_aton(config.defaultForwardAddr) cmd.forward.dest_udp_addr4 = struct.unpack('!l', aton)[0] cmd.forward.dest_udp_port = config.defaultForwardPort cmd.forward.enable = True cmds.append(cmd) resps = _controlCmdWrapper(cmds)
def startRecording(): """ Start recording (acquiring) to disk. Willow only supports contiguous recordings that start at beginning of disk. If already recording, this will raise AlreadyError. If already streaming, this will work, but expect a blip in the stream. """ if isRecording(): raise AlreadyError else: wasStreaming = isStreaming() cmds = [] if wasStreaming: # temporarily turn off streaming cmd = DC.ControlCommand(type=DC.ControlCommand.FORWARD) cmd.forward.enable = False cmds.append(cmd) cmd = DC.ControlCommand(type=DC.ControlCommand.ACQUIRE) cmd.acquire.exp_cookie = long(time.time()) cmd.acquire.start_sample = 0 cmd.acquire.enable = True cmds.append(cmd) if wasStreaming: # turn streaming back on again cmd = DC.ControlCommand(type=DC.ControlCommand.FORWARD) cmd.forward.sample_type = DC.BOARD_SUBSAMPLE cmd.forward.force_daq_reset = False aton = socket.inet_aton(config.defaultForwardAddr) cmd.forward.dest_udp_addr4 = struct.unpack('!l', aton)[0] cmd.forward.dest_udp_port = config.defaultForwardPort cmd.forward.enable = True cmds.append(cmd) resps = _controlCmdWrapper(cmds)
def doTransfer(filename, sampleRange=None): """ Perform a transfer (aka save_stored), save to filename (HDF5 format). Returns a tuple (success, nsamples) where success is False is a timeout occurred, True otherwise. If sampleRange is specified, then only transfer BSI's from within that range. If sampleRange is not specified or NoneType, transfer the entire experiment. WARNING: make sure to check that the DAQ's "Current Board Sample Number" register is nonzero (e.g. by using getDaqBSI) before attempting a transfer with sampleRange=None, otherwise this will fail and the daemon will crash (which is a bug). Only works from an idle state - raises StateChangeError otherwise. """ if isStreaming() or isRecording(): raise StateChangeError else: cmd = DC.ControlCommand(type=DC.ControlCommand.STORE) if sampleRange: if _isValidSampleRange(sampleRange): startSample = sampleRange[0] nsamples = sampleRange[1] - sampleRange[0] cmd.store.start_sample = startSample cmd.store.nsamples = nsamples else: raise hwifError(3, message='sampleRange %s not valid' % repr(sampleRange)) else: cmd.store.start_sample = 0 # leave nsamples missing, which indicates whole experiment cmd.store.path = filename resp = _controlCmdWrapper(cmd) if resp.store.status == DC.ControlResStore.DONE: return True, resp.store.nsamples elif resp.store.status == DC.ControlResStore.TIMEOUT: return False, resp.store.nsamples
def stopStreaming(): """ Stop streaming, both from datanode to daemon, and from daemon to proto2bytes """ if not isStreaming(): raise AlreadyError else: cmds = [] cmd = DC.ControlCommand(type=DC.ControlCommand.FORWARD) cmd.forward.enable = False cmds.append(cmd) if not isRecording(): cmd = DC.ControlCommand(type=DC.ControlCommand.ACQUIRE) cmd.acquire.enable = False cmds.append(cmd) resps = _controlCmdWrapper(cmds)
def pingDatanode(): """ ping the datanode returns nothing mainly used to test for hwifErrors, as in checkVitals() """ cmd = DC.ControlCommand(type=DC.ControlCommand.PING_DNODE) resp = _controlCmdWrapper(cmd)
def startStreaming_boardsamples(): """ Start streaming boardsamples. Useful for running the DAQ during impedance testing while setting zcheck params. Although, there may be a more direct way to accomplish this (new recipe?) """ if isStreaming(): raise AlreadyError else: cmd = DC.ControlCommand(type=DC.ControlCommand.FORWARD) cmd.forward.sample_type = DC.BOARD_SAMPLE cmd.forward.force_daq_reset = not isRecording( ) # if recording, then DAQ is already running aton = socket.inet_aton(config.defaultForwardAddr) cmd.forward.dest_udp_addr4 = struct.unpack('!l', aton)[0] cmd.forward.dest_udp_port = config.defaultForwardPort cmd.forward.enable = True resp = _controlCmdWrapper(cmd)
def startStreaming_subsamples(): """ Start streaming subsamples. Appropriate for streaming via proto2bytes. Make sure to call setSubsamples_byChip() before starting streaming. """ if isStreaming(): raise AlreadyError else: cmd = DC.ControlCommand(type=DC.ControlCommand.FORWARD) cmd.forward.sample_type = DC.BOARD_SUBSAMPLE cmd.forward.force_daq_reset = not isRecording( ) # if recording, then DAQ is already running aton = socket.inet_aton(config.defaultForwardAddr) cmd.forward.dest_udp_addr4 = struct.unpack('!l', aton)[0] cmd.forward.dest_udp_port = config.defaultForwardPort cmd.forward.enable = True resp = _controlCmdWrapper(cmd)
def takeSnapshot(nsamples, filename): """ Takes a snapshot (aka save_stream) of length nsamples, and saves it to filename, in HDF5 format. This will work whether you're streaming, recording, both or neither. Returns the actual number of samples captures, as reported by the daemon. Due to UDP packet drops, this may be less than the number of samples requested. """ cmds = [] if isStreaming(): sampleType = getSampleType() if sampleType == 'boardsample': cmd = DC.ControlCommand(type=DC.ControlCommand.STORE) cmd.store.path = filename cmd.store.nsamples = nsamples cmds.append(cmd) elif sampleType == 'subsample': #TODO implement a work-around for this raise StateChangeError('Pause streaming before taking snapshot.') else: print 'unrecognized sample type received!' elif isRecording(): # if not streaming, but recording... cmd = DC.ControlCommand(type=DC.ControlCommand.STORE) cmd.store.path = filename cmd.store.nsamples = nsamples cmds.append(cmd) #### # need this to turn off daq->udp, otherwise state gets broken cmd = DC.ControlCommand(type=DC.ControlCommand.FORWARD) cmd.forward.enable = False cmds.append(cmd) else: # if idle... cmd = DC.ControlCommand(type=DC.ControlCommand.FORWARD) cmd.forward.sample_type = DC.BOARD_SAMPLE cmd.forward.force_daq_reset = True aton = socket.inet_aton(config.defaultForwardAddr ) # TODO should this be its own exception? cmd.forward.dest_udp_addr4 = struct.unpack('!l', aton)[0] cmd.forward.dest_udp_port = config.defaultForwardPort cmd.forward.enable = True cmds.append(cmd) #### cmd = DC.ControlCommand(type=DC.ControlCommand.STORE) cmd.store.path = filename cmd.store.nsamples = nsamples cmds.append(cmd) #### cmd = DC.ControlCommand(type=DC.ControlCommand.ACQUIRE) cmd.acquire.enable = False cmds.append(cmd) resps = _controlCmdWrapper(cmds) for resp in resps: if resp.type == DC.ControlResponse.STORE_FINISHED: if resp.store.status == DC.ControlResStore.DONE: return resp.store.nsamples elif resp.store.status == DC.ControlResStore.PKTDROP: return resp.store.nsamples else: # this shouldn't happen, but.. raise hwifError(3, message='ControlResStore Status: %d' % resp.store.status)