def setup_experiment(self, info): circuit = join(get_config("RCX_ROOT"), "positive-behavior-stage1") self.iface_behavior = self.process.load_circuit(circuit, "RZ6") self.buffer_signal = self.iface_behavior.get_buffer("signal", "w") self.buffer_TTL = self.iface_behavior.get_buffer("TTL", "r", block_size=24, src_type="int8", dest_type="int8") self.buffer_mic = self.iface_behavior.get_buffer("mic", "r") self.model.data.spout_TTL.fs = self.buffer_TTL.fs self.model.data.override_TTL.fs = self.buffer_TTL.fs self.model.data.pump_TTL.fs = self.buffer_TTL.fs self.model.data.signal_TTL.fs = self.buffer_TTL.fs self.model.data.free_run_TTL.fs = self.buffer_TTL.fs self.model.data.microphone.fs = self.buffer_mic.fs targets = [ self.model.data.spout_TTL, self.model.data.override_TTL, self.model.data.pump_TTL, self.model.data.signal_TTL, self.model.data.free_run_TTL, ] self.pipeline_TTL = deinterleave_bits(targets) self.iface_pump.set_trigger(start="rising", stop="falling") self.iface_pump.set_direction("infuse") self.iface_pump.set_volume(0)
def setup_physiology(self): # Load the circuit circuit = join(get_config('RCX_ROOT'), 'physiology') self.iface_physiology = self.process.load_circuit(circuit, 'RZ5') # Initialize the buffers that will be spooling the data self.buffer_raw = self.iface_physiology.get_buffer('craw', 'r', src_type='float32', dest_type='float32', channels=CHANNELS, block_size=1048) self.buffer_filt = self.iface_physiology.get_buffer('cfilt', 'r', src_type='int16', dest_type='float32', channels=CHANNELS, block_size=1048) self.buffer_ts = self.iface_physiology.get_buffer('trig/', 'r', src_type='int32', dest_type='int32', block_size=1) self.buffer_ts_start = self.iface_physiology.get_buffer('trig/', 'r', src_type='int32', dest_type='int32', block_size=1) self.buffer_ts_end = self.iface_physiology.get_buffer('trig\\', 'r', src_type='int32', dest_type='int32', block_size=1) self.buffer_ttl = self.iface_physiology.get_buffer('TTL', 'r', src_type='int8', dest_type='int8', block_size=1) for i in range(CHANNELS): name = 'spike{}'.format(i+1) buffer = self.iface_physiology.get_buffer(name, 'r', block_size=SPIKE_SNIPPET_SIZE+2) self.buffer_spikes.append(buffer)
def setup_experiment(self, info): filename = 'positive-behavior-training-contmask-v4' circuit = path.join(get_config('RCX_ROOT'), filename) self.iface_behavior = self.process.load_circuit(circuit, 'RZ6') self.buffer_masker = self.iface_behavior.get_buffer('masker', 'w') self.buffer_target = self.iface_behavior.get_buffer('target', 'w') self.buffer_TTL = self.iface_behavior.get_buffer('TTL', 'r', block_size=24, src_type='int8', dest_type='int8') self.buffer_mic = self.iface_behavior.get_buffer('mic', 'r') self.model.data.spout_TTL.fs = self.buffer_TTL.fs self.model.data.override_TTL.fs = self.buffer_TTL.fs self.model.data.pump_TTL.fs = self.buffer_TTL.fs self.model.data.signal_TTL.fs = self.buffer_TTL.fs self.model.data.free_run_TTL.fs = self.buffer_TTL.fs self.model.data.microphone.fs = self.buffer_mic.fs targets = [self.model.data.spout_TTL, self.model.data.override_TTL, self.model.data.pump_TTL, self.model.data.signal_TTL, self.model.data.free_run_TTL ] self.pipeline_TTL = deinterleave_bits(targets) self.iface_pump.set_trigger(start='rising', stop='falling') self.iface_pump.set_direction('infuse') self.iface_pump.set_volume(0)
def profile_experiment(args): import cProfile profile_data_file = join(get_config('TEMP_ROOT'), 'profile.dmp') cProfile.runctx('test_experiment(args)', globals(), {'args': args}, filename=profile_data_file) # Once experiment is done, print out some statistics import pstats p = pstats.Stats(profile_data_file) p.strip_dirs().sort_stats('cumulative').print_stats(50)
def get_temp_mic_node(): filename = path.join(get_config('TEMP_ROOT'), 'microphone.h5') log.debug('saving microphone data to %s', filename) tempfile = tables.openFile(filename, 'a') # If the file already exists from a prior experiment, then we should # remove the existing microphone node. if 'microphone' in tempfile.root: tempfile.root.microphone._f_remove() return tempfile.root
def _setup_circuit(self): # AversiveFMController needs to change the initialization sequence a # little (i.e. it needs to use different microcode and the microcode # does not contain int and trial buffers). circuit = join(get_config('RCX_ROOT'), 'aversive-behavior-FMAM') self.iface_behavior = self.process.load_circuit(circuit, 'RZ6') self.buffer_TTL = self.iface_behavior.get_buffer('TTL', 'r', src_type='int8', dest_type='int8', block_size=24) self.buffer_contact = self.iface_behavior.get_buffer('contact', 'r', src_type='int8', dest_type='float32', block_size=24) self.buffer_spout_start = self.iface_behavior.get_buffer('spout/', 'r', src_type='int32', block_size=1) self.buffer_spout_end = self.iface_behavior.get_buffer('spout\\', 'r', src_type='int32', block_size=1)
def setup_experiment(self, info): circuit = join(get_config('RCX_ROOT'), 'positive-behavior-v2') self.iface_behavior = self.process.load_circuit(circuit, 'RZ6') self.buffer_out = self.iface_behavior.get_buffer('out', 'w') self.buffer_TTL1 = self.iface_behavior.get_buffer('TTL', 'r', src_type='int8', dest_type='int8', block_size=24) self.buffer_TTL2 = self.iface_behavior.get_buffer('TTL2', 'r', src_type='int8', dest_type='int8', block_size=24) self.buffer_poke_start = self.iface_behavior.get_buffer('poke_all/', 'r', src_type='int32', dest_type='int32', block_size=1) self.buffer_poke_end = self.iface_behavior.get_buffer('poke_all\\', 'r', src_type='int32', dest_type='int32', block_size=1) # microphone self.buffer_mic = self.iface_behavior.get_buffer('mic', 'r') self.model.data.microphone.fs = self.buffer_mic.fs self.fs_conversion = self.iface_behavior.get_tag('TTL_d') # Stored in TTL1 self.model.data.spout_TTL.fs = self.buffer_TTL1.fs self.model.data.poke_TTL.fs = self.buffer_TTL1.fs self.model.data.signal_TTL.fs = self.buffer_TTL1.fs self.model.data.reaction_TTL.fs = self.buffer_TTL1.fs self.model.data.response_TTL.fs = self.buffer_TTL1.fs self.model.data.reward_TTL.fs = self.buffer_TTL1.fs # Stored in TTL2 self.model.data.TO_TTL.fs = self.buffer_TTL2.fs # Timestamp data self.model.data.trial_epoch.fs = self.iface_behavior.fs self.model.data.signal_epoch.fs = self.iface_behavior.fs self.model.data.poke_epoch.fs = self.iface_behavior.fs self.model.data.all_poke_epoch.fs = self.iface_behavior.fs self.model.data.response_ts.fs = self.iface_behavior.fs targets1 = [self.model.data.poke_TTL, self.model.data.spout_TTL, self.model.data.reaction_TTL, self.model.data.signal_TTL, self.model.data.response_TTL, self.model.data.reward_TTL, ] targets2 = [None, self.model.data.TO_TTL] self.pipeline_TTL1 = deinterleave_bits(targets1) self.pipeline_TTL2 = deinterleave_bits(targets2) # Configure the pump self.iface_pump.set_trigger(start='rising', stop=None) self.iface_pump.set_direction('infuse')
def _setup_shock(self): # First, we need to load the circuit we need to control the shocker. # We currently use DAC channel 12 of the RZ5 to control shock level; # however, the RZ5 will already have a circuit loaded if we're using it # for physiology. The physiology circuit is already configured to # control the shocker. However, if we are not acquiring physiology, we # need to load a circuit that allows us to control the shocker. if not self.model.spool_physiology: circuit = join(get_config('RCX_ROOT'), 'shock-controller') self.iface_shock = self.process.load_circuit(circuit, 'RZ5') else: # This assumes that iface_physiology has already been initialized. # In the current abstract_experiment_controller, setup_physiology is # called before setup_experiment. self.physiology_handler is a # reference to the PhysiologyController object. self.iface_shock = self.physiology_handler.iface_physiology
import numpy as np from enable.api import ColorTrait from chaco.api import AbstractOverlay from traits.api import Instance, Array, Int from enable import markers from cns import get_config colors = get_config("PAIRED_COLORS_RGB_NORM") # The keys are values defined by UMS2000. As long as the users has not modified # the default labels available, they will map to the label in the comment next # to each entry cluster_type_marker = { 1: (3, markers.CIRCLE_MARKER), # in process 2: (7, markers.INVERTED_TRIANGLE_MARKER), # good unit 3: (7, markers.TRIANGLE_MARKER), # multi-unit 4: (1, markers.DOT_MARKER), # garbage 5: (3, markers.DOT_MARKER), # needs outlier removal } class ExtractedSpikeOverlay(AbstractOverlay): """ Supports overlaying the spike times on a multichannel view. The component must be a subclass of MultiChannelPlot. clusters One entry for each timestamp indicating the cluster that event belongs to
def setup_experiment(self, info): circuit = path.join(get_config('RCX_ROOT'), 'positive-behavior-contmask-v4') self.iface_behavior = self.process.load_circuit(circuit, 'RZ6') self.buffer_target = self.iface_behavior.get_buffer('target', 'w') self.buffer_masker = self.iface_behavior.get_buffer('masker', 'w') self.buffer_TTL1 = self.iface_behavior.get_buffer('TTL', 'r', src_type='int8', dest_type='int8', block_size=24) self.buffer_TTL2 = self.iface_behavior.get_buffer('TTL2', 'r', src_type='int8', dest_type='int8', block_size=24) self.buffer_poke_start = self.iface_behavior.get_buffer('poke_all/', 'r', src_type='int32', dest_type='int32', block_size=1) self.buffer_poke_end = self.iface_behavior.get_buffer('poke_all\\', 'r', src_type='int32', dest_type='int32', block_size=1) # microphone self.buffer_mic = self.iface_behavior.get_buffer('mic', 'r') self.model.data.microphone.fs = self.buffer_mic.fs self.fs_conversion = self.iface_behavior.get_tag('TTL_d') # Stored in TTL1 self.model.data.spout_TTL.fs = self.buffer_TTL1.fs self.model.data.poke_TTL.fs = self.buffer_TTL1.fs self.model.data.signal_TTL.fs = self.buffer_TTL1.fs self.model.data.reaction_TTL.fs = self.buffer_TTL1.fs self.model.data.response_TTL.fs = self.buffer_TTL1.fs self.model.data.reward_TTL.fs = self.buffer_TTL1.fs # Stored in TTL2 self.model.data.TO_TTL.fs = self.buffer_TTL2.fs # Timestamp data self.model.data.trial_epoch.fs = self.iface_behavior.fs self.model.data.signal_epoch.fs = self.iface_behavior.fs self.model.data.poke_epoch.fs = self.iface_behavior.fs self.model.data.all_poke_epoch.fs = self.iface_behavior.fs self.model.data.response_ts.fs = self.iface_behavior.fs targets1 = [self.model.data.poke_TTL, self.model.data.spout_TTL, self.model.data.reaction_TTL, self.model.data.signal_TTL, self.model.data.response_TTL, self.model.data.reward_TTL, ] # If the target is set to None, this means that we aren't interested in # capturing the value of that specific bit. Nothing is stored in the # first bit of the TTL_2 data; however, we store the timeout TTL in the # second bit. targets2 = [None, self.model.data.TO_TTL] # deinterleave_bits is the Python complement of the RPvds FromBits # component that breaks down the integer into its individual bits. # Targets are the destination channel (which map to the underlying HDF5 # array) for each bit. e.g. the value of the first bit gets sent to # targets1[0] (which is the poke_TTL). deinterleave_bits is a # "pipeline" function that automatically performs its function each time # new data arrives and hands the result off to the targets. The targets # recieve this data and store it in the HDF5 array and notify the GUI # that new data has arrived and should be plotted. self.pipeline_TTL1 = deinterleave_bits(targets1) self.pipeline_TTL2 = deinterleave_bits(targets2) # Configure the pump self.iface_pump.set_trigger(start='rising', stop=None) self.iface_pump.set_direction('infuse')
def trigger_next(self): # This function is *required* to be called. This basically calls the # logic (defined in AbstractExperimentController) which clears the # current value of all parameters and recomputes them (this is important # in between trials). self.invalidate_context() # This must be called before the start of every trial to load (or # evaluate if the parameter is an expression) the values of each # parameter. Note this method will also check to see if the value of a # parameter has changed since the last trial. If so, the corresponding # set_parametername method will be called with the new value as an # argument. self.evaluate_pending_expressions() # For all variables declared as context=True, you can get the current # value via self.get_current_value(). This gives the # abstract_experiment_controller a chance to compute the values of any # parameters that are defined by expressions first. repeat_fa = self.get_current_value('repeat_fa') hw_att = self.get_current_value('hw_att') go_probability = self.get_current_value('go_probability') speaker = self.get_current_value('speaker') if speaker == 'primary': cal = self.cal_primary else: cal = self.cal_secondary # Determine whether the animal false alarmed by checking the spout and # nogo data. The last value in the "self.model.data.yes_seq" (which is # a list) will be True if he went to the spout. The last value in # self.model.data.nogo_seq will be True if it was a NOGO or NOGO_REPEAT # trial. try: spout = self.model.data.yes_seq[-1] nogo = self.model.data.nogo_seq[-1] except IndexError: spout = False nogo = False # First, decide if it's a GO, GO_REMIND, NOGO or NOGO_REPEAT if len(self.model.data.trial_log) == 0: # This is the very first trial ttype = 'GO_REMIND' settings = self.go_remind elif self.remind_requested: # When the user clicks on the "remind" button, it sets the # remind_requested attribute on the experiment controller to True. ttype = 'GO_REMIND' settings = self.go_remind elif nogo and spout and repeat_fa: # The animal false alarmed and the user wishes to repeat the trial # if the animal false alarms ttype = 'NOGO_REPEAT' settings = self.nogo_parameters.pop() elif self.random_generator.uniform() < go_probability: ttype = 'GO' settings = self.go_parameters.pop() else: ttype = 'NOGO' settings = self.nogo_parameters.pop() # Each time we pop() a parameter, it is removed from the list and # returned # "unpack" our list into individual variables F, E, FC, ML, TL, TokenNo, TargetNo = settings #masker_file = r'E:\programs\ANTJE CMR\CMR\stimuli\M{}{}{}{}.stim'.format(int(F), int(E), int(FC), int(TokenNo)) target_file = path.join(get_config('SOUND_PATH'), 'CMR\stimuli\T{}{}.stim') target_file = target_file.format(int(FC), int(TargetNo)) #target_file = r'e:\Experimental_Software\sounds\CMR\stimuli\T{}{}.stim'.format(int(FC), int(TargetNo)) #masker = np.fromfile(masker_file, dtype=np.float32) target = np.fromfile(target_file, dtype=np.float32) # This method will return the theoretical SPL of the speaker assuming # you are playing a tone at the specified frequency and voltage (i.e. # Vrms) dBSPL_RMS1 = cal.get_spl(frequencies=1e3, voltage=1) #self.some_trial_variable = dBSPL_RMS1 # Scale waveforms so that we get desired stimulus level assuming 0 dB of # attenuation #masker = 10**((ML-dBSPL_RMS1)/20)*masker target = 10**((TL-dBSPL_RMS1)/20)*target #stimulus = target + masker stimulus = target stimulus = stimulus * 10**(hw_att/20) # Set the flag in the RPvds circuit that indicates which output to send # the waveform to if speaker == 'primary': self.iface_behavior.set_tag('speaker', 0) elif speaker == 'secondary': self.iface_behavior.set_tag('speaker', 1) self.buffer_target.set(stimulus) # Be sure that the trial type is added to the list of context variables # that will be saved to the trial_log file. self.set_current_value('ttype', ttype) # Boolean flag in the circuit that indicates whether or not the current # trial is a go. This ensures that a reward is not delivered on NOGO # trials. if ttype.startswith('GO'): self.iface_behavior.set_tag('go?', 1) else: self.iface_behavior.set_tag('go?', 0) self.set_current_value('target_level', TL) #self.set_current_value('masker_level',ML) #self.set_current_value('masker_level',ML) ML = self.get_current_value('masker_level') self.set_current_value('TMR',TL-ML) self.set_current_value('target_number',TargetNo) #self.set_current_value('masker_number',TokenNo) #self.set_current_value('masker_envelope',E) #self.set_current_value('masker_flanker',F) self.set_current_value('center_frequency',FC) # This is a "handshake" that lets the RPvds circuit know that we are # done with preparations for the next trial (e.g. uploading the stimulus # waveform). The RPvds circuit will not proceed with the next trial # until it receives a "SoftTrig1" (in TDT parlance) log.debug('Sending the trial-ready trigger to the RPvds circuit') self.iface_behavior.trigger(1)
import numpy as np from enable.api import ColorTrait from chaco.api import AbstractOverlay from traits.api import Instance, Array, Int from enable import markers from cns import get_config colors = get_config('PAIRED_COLORS_RGB_NORM') # The keys are values defined by UMS2000. As long as the users has not modified # the default labels available, they will map to the label in the comment next # to each entry cluster_type_marker = { 1: (3, markers.CIRCLE_MARKER), # in process 2: (7, markers.INVERTED_TRIANGLE_MARKER), # good unit 3: (7, markers.TRIANGLE_MARKER), # multi-unit 4: (1, markers.DOT_MARKER), # garbage 5: (3, markers.DOT_MARKER), # needs outlier removal } class ExtractedSpikeOverlay(AbstractOverlay): ''' Supports overlaying the spike times on a multichannel view. The component must be a subclass of MultiChannelPlot. clusters One entry for each timestamp indicating the cluster that event belongs to cluster_ids List of all cluster IDs
def prepare_experiment(args, store_node, create_child=True): ''' Given the arguments passed in via the command-line, configure the Experiment, Controller, Data and Paradigm class accordingly and return an instance of the model and controller class. ''' # The HDF5 file that is used for the data store_file = store_node._v_file # If the user did not specify a list of parameters that the data should be # grouped into before analysis (i.e. for computing the hit and false alarm # fractions), then use the parameters specified via rove as the analysis # parameters. if len(args.analyze) == 0: args.analyze = args.rove[:] # Load the experiment from the launchers folder. args.type should be the # name of the corresponding file in the launchers folder (without the .py # extension) module = get_experiment(args.type) # Pull out the classes paradigm_class = module.Paradigm experiment_class = module.Experiment controller_class = module.Controller data_class = module.Data node_name = module.node_name # Create the experiment and data nodes. Hint! This is where you would # change the default pathname for the experiment if you wished. if create_child: name = node_name + '_' + datetime.now().strftime(time_fmt) exp_node = store_file.createGroup(store_node, name) else: exp_node = store_node # Where the data is stored data_node = store_file.createGroup(exp_node, 'data') # Configure the TrialSetting/trial_setting_editor objects to contain the # parameters we wish to control in the experiment trial_setting.add_parameters(args.rove, paradigm_class, args.repeats) if args.att: # The user wants to specify values in terms of dB attenuation rather # than a calibrated dB SPL standard. Prepare the calibration # accordingly. cal1 = calibration.Attenuation() cal2 = calibration.Attenuation() else: if args.cal is not None: cal1_filename, cal2_filename = args.cal else: cal1_filename = get_config('CAL_PRIMARY') cal2_filename = get_config('CAL_SECONDARY') if cal1_filename is None: raise IOError, 'Unable to find a calibration file for the ' \ 'primary speaker' if cal2_filename is None: raise IOError, 'Unable to find a calibration file for the ' \ 'secondary speaker' cal1 = calibration.load_mat_cal(cal1_filename, args.equalized) log.debug('Loaded calibration file %s for primary', cal1_filename) cal2 = calibration.load_mat_cal(cal2_filename, args.equalized) log.debug('Loaded calibration file %s for secondary', cal2_filename) controller_args = { 'cal_primary': cal1, 'cal_secondary': cal2, 'address': args.address, } log.debug('store_node: %s', store_node) log.debug('data_node: %s', data_node) log.debug('exp_node: %s', exp_node) # Prepare the classes. This really is a lot of boilerplate to link up # parameters with paradigms, etc, to facilitate analysis paradigm = paradigm_class() data = data_class(store_node=data_node, save_microphone=args.save_microphone) data.parameters = args.analyze model = experiment_class( store_node=store_node, experiment_node=exp_node, data_node=data_node, data=data, paradigm=paradigm, spool_physiology=args.physiology, ) if args.analyze: model.plot_index = args.analyze[0] model.plot_group = args.analyze[1:] controller = controller_class(**controller_args) return model, controller
from traits.api import Instance, Int, on_trait_change, \ Dict, HasTraits, Any, List, Str, Enum, Property from traitsui.api import VGroup, Item, EnumEditor, SetEditor, HGroup from cns.chaco_exts.helpers import add_default_grids from chaco.api import DataRange1D, LinearMapper, \ PlotAxis, LogMapper, ArrayDataSource, \ OverlayPlotContainer, LinePlot, ScatterPlot from traitsui.api import TabularEditor from traitsui.tabular_adapter import TabularAdapter from cns import get_config CHACO_AXES_PADDING = get_config('CHACO_AXES_PADDING') PAIRED_COLORS_NORM = get_config('PAIRED_COLORS_RGB_NORM') class ParInfoAdapter(TabularAdapter): color_map = Dict parameter_text = Property def _get_parameter_text(self): return ', '.join('{}'.format(p) for p in self._get_parameters()) def _get_parameters(self): return [self.item[p] for p in self.object.parameters] def _get_bg_color(self): try:
def ref_cal(duration=1, averages=2, ref_freq=1e3, ref_level=93.8, gain=20, fft=False, mode='conv'): ''' Calibrates measuring microphone against a known reference (e.g. a pistonphone). Typically this is the B&K microphone, but certainly could be any microphone that is felt to produce a flat frequency response across the range of frequencies of interest. TODO: Update this so it incorporates the actual B&K calibration file (where do we get this?). level Output of reference in dB SPL frequency Frequency of reference in Hz verbose Returns signal and FFT so it can be plotted ''' circuit_path = join(get_config('RCX_ROOT'), 'play_record.rcx') circuit = DSPCircuit(circuit_path, 'RZ6') circuit.start(1) samples = circuit.convert(duration, 's', 'nPow2') # Important, rec_delay must be at least 1 or the circuit will not work circuit.set_tags(play_duration=0, rec_duration=samples, rec_delay=1) mic_buffer = circuit.get_buffer('mic', 'r') mic_data = mic_buffer.acquire_samples(1, samples, 1) print rms(mic_data) print tone_frequency(circuit.fs, mic_data[0].ravel(), 1e3) from pylab import plot, show plot(mic_data[0].ravel()[:5e3]) show() return print mic_data.shape if circuit.get_tag('clipped'): print 'Clipping occured' for m in mic_data: #rms = np.mean(m.ravel()**2)**0.5 magnitude, phase = tone_frequency(circuit.fs, m, 1e3) print magnitude/dbspltopa(ref_level+gain) #plot(mic_data[0].ravel()) #show() return mic_data #print mic_data.shape return # Do the calibration! #result = tone_power(device, samples, averages=averages, freq=ref_freq, # fft=fft, mode=mode) log.debug('Measured %.2f Vrms at %.2f Hz from the pistonphone' % \ (result[0], ref_freq)) sens = result[0] / dbtopa(ref_level) debug_mesg = 'Using the pistonphone reference of %.2f dB SPL, ' + \ 'microphone sensitivity is %.4f Vrms/Pa' log.debug(debug_mesg % (ref_level, sens)) # Phase is meaningless since we have little control over the pistonphone, so # we do not return this, just microphone sensitivity. if fft: return sens, result[-1] else: return sens
from enable.api import Component, ComponentEditor, Window from traits.api import HasTraits, Instance, Button, Any from traitsui.api import Item, Group, View, Controller from pyface.timer.api import Timer from chaco.api import (LinearMapper, DataRange1D, OverlayPlotContainer, PlotAxis) from chaco.tools.api import ZoomTool, PanTool from tdt import DSPCircuit from cns import get_config from cns.chaco_exts.helpers import add_default_grids from cns.chaco_exts.tools.window_tool import WindowTool from cns.channel import FileSnippetChannel from cns.data.h5_utils import get_temp_file RCX_ROOT = get_config('RCX_ROOT') class Demo(HasTraits): traits_view = View( Item('handler.button'), Item('handler.container', editor=ComponentEditor(size=(400,400))), resizable=True) class DemoController(Controller): iface = Any timer = Any snippet_source = Any snippet_store = Any plot = Any
from traits.api import HasTraits, Float, Enum, Property, cached_property from traitsui.api import View, Item, VGroup, HGroup from cns import get_config from evaluate import Expression SYRINGE_DATA = get_config('SYRINGE_DATA') SYRINGE_DEFAULT = get_config('SYRINGE_DEFAULT') class PumpParadigmMixin(HasTraits): kw = {'context': True, 'store': 'attribute', 'log': True} pump_rate = Expression(0.5, label='Pump rate (ml/min)', **kw) pump_rate_delta = Float(0.025, label='Pump rate delta (ml)', **kw) pump_syringe = Enum(SYRINGE_DEFAULT, sorted(SYRINGE_DATA.keys()), label='Syringe', ignore=True, **kw) pump_syringe_diameter = Property(label='Syringe diameter (mm)', depends_on='pump_syringe', **kw) @cached_property def _get_pump_syringe_diameter(self): return SYRINGE_DATA[self.pump_syringe] # Note that we have defined two views here, a simple view and a more # detailed view. When including this mixin class, you can choose which view # is used. detailed_pump_group = VGroup( HGroup( 'pump_rate', 'pump_rate_delta',
from chaco.tools.api import ZoomTool from cns.chaco_exts.tools.window_tool import WindowTool from cns.chaco_exts.helpers import add_default_grids, add_time_axis from cns.chaco_exts.channel_data_range import ChannelDataRange from cns.chaco_exts.extremes_multi_channel_plot import ExtremesMultiChannelPlot from cns.chaco_exts.ttl_plot import TTLPlot from cns.chaco_exts.epoch_plot import EpochPlot from cns.chaco_exts.channel_range_tool import MultiChannelRangeTool from cns.chaco_exts.channel_number_overlay import ChannelNumberOverlay from cns.chaco_exts.snippet_channel_plot import SnippetChannelPlot from cns import get_config from cns.chaco_exts.spike_overlay import SpikeOverlay from cns.chaco_exts.threshold_overlay import ThresholdOverlay CHANNELS = get_config('PHYSIOLOGY_CHANNELS') VOLTAGE_SCALE = 1e3 scale_formatter = lambda x: "{:.2f}".format(x*VOLTAGE_SCALE) from traitsui.menu import MenuBar, Menu, ActionGroup, Action def create_menubar(): actions = ActionGroup( Action(name='Load settings', action='load_settings'), Action(name='Save settings as', action='saveas_settings'), Action(name='Restore defaults', action='reset_settings'), ) menu = Menu(actions, name='&Physiology') return MenuBar(menu) def ptt(event_times, trig_times):
from traits.api import (Instance, Any, List, on_trait_change, Enum, Dict) from traitsui.api import Controller from pyface.timer.api import Timer from cns import get_config from os.path import join from cns.pipeline import deinterleave_bits CHANNELS = get_config('PHYSIOLOGY_CHANNELS') PHYSIOLOGY_WILDCARD = get_config('PHYSIOLOGY_WILDCARD') SPIKE_SNIPPET_SIZE = get_config('PHYSIOLOGY_SPIKE_SNIPPET_SIZE') from .utils import load_instance, dump_instance class PhysiologyController(Controller): buffer_ = Any iface_physiology = Any buffer_raw = Any buffer_proc = Any buffer_ts = Any buffer_ttl = Any physiology_ttl_pipeline = Any buffer_spikes = List(Any) state = Enum('master', 'client') process = Instance('tdt.DSPProject') timer = Instance(Timer) parent = Any
import tables from tempfile import mkdtemp from os import path from cns import get_config from traits.api import HasTraits, Instance, List, Any from cns.channel import (FileMultiChannel, FileChannel, FileSnippetChannel, FileTimeseries, FileEpoch) import numpy as np CHANNELS = get_config('PHYSIOLOGY_CHANNELS') SNIPPET_SIZE = get_config('PHYSIOLOGY_SPIKE_SNIPPET_SIZE') class PhysiologyData(HasTraits): store_node = Any ############################################################################# # Permanent data ############################################################################# # Raw (permanent) physiology data that will be stored in the data file that # is retained at the end of the experiment. raw = Instance(FileMultiChannel) sweep = Instance(FileChannel) ts = Instance(FileTimeseries) epoch = Instance(FileEpoch) def _sweep_default(self): return FileChannel(node=self.store_node, name='sweep', dtype=np.bool, use_checksum=True)
from experiments.cl_controller_mixin import CLControllerMixin from experiments.cl_paradigm_mixin import CLParadigmMixin from experiments.cl_experiment_mixin import CLExperimentMixin from experiments.aversive_cl_data_mixin import AversiveCLDataMixin from experiments.pump_controller_mixin import PumpControllerMixin from experiments.pump_paradigm_mixin import PumpParadigmMixin from experiments.pump_data_mixin import PumpDataMixin from cns import get_config import logging log = logging.getLogger(__name__) MAX_VRMS = get_config('MAX_SPEAKER_DAC_VOLTAGE') class Controller( CLControllerMixin, PumpControllerMixin, AbstractAversiveController): # Scaling factor used for the waveform. Must call it "dt" because the # superclass already defines a waveform_sf that is overwritten by the # superclass trigger_next method. kw = {'context': True, 'log': True, 'immediate': True} dt_waveform_sf = Float(np.nan, label='DT scaling factor', **kw) dt_waveform_error = Bool(False, label='DT waveform error?', **kw) def initial_setting(self): return self.nogo_setting()
import os from os.path import join from importlib import import_module from glob import glob from traits.api import Any, Trait, TraitError from experiments import trial_setting from cns import calibration import logging log = logging.getLogger(__name__) from cns import get_config from datetime import datetime time_fmt = get_config('TIME_FORMAT') class ExperimentLauncher(CohortViewHandler): args = Any last_paradigm = Trait(None, Any) def init(self, info): if not self.load_file(info): sys.exit() def launch_experiment(self, info, selected): ''' Runs specified experiment type. On successful completion of an experiment, marks the animal as processed and saves the last paradigm used. If the experiment is launched but not run, changes to the
def _iface_audio_default(self): circuit = join(get_config('RCX_ROOT'), 'basic_audio') return self.process.load_circuit(circuit, 'RZ6')
from cns.chaco_exts.ttl_plot import TTLPlot from cns.chaco_exts.timeseries_plot import TimeseriesPlot from cns.chaco_exts.epoch_plot import EpochPlot from cns.chaco_exts.helpers import add_default_grids, add_time_axis from abstract_experiment import AbstractExperiment import logging log = logging.getLogger(__name__) from traitsui.api import TabularEditor from traitsui.tabular_adapter import TabularAdapter from traits.api import * from cns import get_config COLORS = get_config('EXPERIMENT_COLORS') class TrialLogAdapter(TabularAdapter): # List of tuples (column_name, field ) columns = [ ('P', 'parameter'), ('Time', 'time'), ('Score', 'contact_score'), ] parameter_width = Float(75) contact_score_width = Float(50) reaction_width = Float(25) response_width = Float(25) speaker_width = Float(25) time_width = Float(65)
from traits.api import (HasTraits, Instance, List, Float, on_trait_change) from traitsui.api import Item, HGroup from chaco.api import (OverlayPlotContainer, DataRange1D, PlotAxis, ScatterPlot, LinearMapper, ArrayDataSource, LinePlot) from chaco.tools.api import ZoomTool from enable.api import ComponentEditor import numpy as np from chaco.function_data_source import FunctionDataSource from cns import get_config from .maximum_likelihood import p_yes SIZE = (400, 400) CHACO_AXES_PADDING = get_config('CHACO_AXES_PADDING') numpoints = 500 TRACKS = 2 def _xfunc(low, high): dx = (high - low) / numpoints real_low = np.ceil(low/dx) * dx real_high = np.ceil(high/dx) * dx return np.linspace(real_low, real_high, numpoints) class _MLDataSource(FunctionDataSource): a = Float(0) m = Float(0) k = Float(0)
def __getitem__(self, key): if key not in self._parameters: raise KeyError, key return getattr(self, key) def __len__(self): return len(self._parameters) def __iter__(self): return iter(self._parameters) from traitsui.api import TabularEditor from traitsui.tabular_adapter import TabularAdapter from cns import get_config color_names = get_config('COLOR_NAMES') class TrialSettingAdapter(TabularAdapter): default_value = TrialSetting(ttype='GO') def _get_bg_color(self): ttype = self.item.ttype if ttype == 'NOGO': return color_names['light red'] elif ttype == 'GO_REMIND': return color_names['dark green'] elif ttype == 'GO': return color_names['light green'] trial_setting_editor = TabularEditor(
label='Paradigm' ), VGroup( Include('dt_group'), Include('speaker_group'), label='Sound' ) ) class Data(PositiveData, MLDataMixin, PumpDataMixin): pass class Experiment(AbstractPositiveExperiment, MLExperimentMixin): data = Instance(Data, ()) paradigm = Instance(Paradigm, ()) node_name = 'PositiveDTCLExperiment' if __name__ == '__main__': import tables from os.path import join from cns import get_config filename = join(get_config('TEMP_ROOT'), 'test_experiment.hd5') file = tables.openFile(filename, 'w') from experiments.trial_setting import add_parameters add_parameters(['test']) data = Data(store_node=file.root) experiment = Experiment(data=data) experiment.configure_traits()