def __init__(self, **kwargs):
        """
        :Keywords:
            snr : float
                Signal to Noise Ratio (SNR) for the noise process.
                Default=1.0
            noise : bool
                If False, do not setup noise generator. For setup in subclass
                Default=True
        """

        # super
        super(Recorder, self).__init__(**kwargs)

        # members
        self._origin = self.position.copy()
        if self.points is None:
            self.nchan = 1
        else:
            self.nchan = self.points.shape[0]
        self._noise_gen = None
        self._snr = None
        traj = kwargs.get('orientation', N.asarray([0.0, 0.0, 1.0]))
        if traj is True or traj is False:
            traj = [0.0, 0.0, 1.0]
        self._trajectory = unit_vector(traj)
        self._trajectory_pos = None

        # set from kwargs
        self.snr = kwargs.get('snr', 1.0)
        self.trajectory_pos = 0.0
        noise = kwargs.get('noise', True)
        if noise is True:
            self._noise_gen = NoiseGen(mu=N.zeros(self.nchan))
class Recorder(SimObject):
    """multichanneled recorder object with an intrinsic noise process

    If the Recorder has self._points, these correspond to the recorder channels.
    Else there will be only one channel at self.position.
    """

    ## constructor
    def __init__(self, **kwargs):
        """
        :Keywords:
            snr : float
                Signal to Noise Ratio (SNR) for the noise process.
                Default=1.0
            noise : bool
                If False, do not setup noise generator. For setup in subclass
                Default=True
        """

        # super
        super(Recorder, self).__init__(**kwargs)

        # members
        self._origin = self.position.copy()
        if self.points is None:
            self.nchan = 1
        else:
            self.nchan = self.points.shape[0]
        self._noise_gen = None
        self._snr = None
        traj = kwargs.get('orientation', N.asarray([0.0, 0.0, 1.0]))
        if traj is True or traj is False:
            traj = [0.0, 0.0, 1.0]
        self._trajectory = unit_vector(traj)
        self._trajectory_pos = None

        # set from kwargs
        self.snr = kwargs.get('snr', 1.0)
        self.trajectory_pos = 0.0
        noise = kwargs.get('noise', True)
        if noise is True:
            self._noise_gen = NoiseGen(mu=N.zeros(self.nchan))

    ## properties

    def get_origin(self):
        return self._origin
    origin = property(get_origin)

    def get_snr(self):
        return self._snr
    def set_snr(self, value):
        if value <= 0.0:
            raise ValueError('cannot set SNR <= 0.0')
        self._snr = float(value)
    snr = property(get_snr, set_snr)

    def get_trajectory(self):
        return self._trajectory
    def set_trajectory(self, value):
        self._trajectory = value
    trajectory = property(get_trajectory, set_trajectory)

    def get_trajectory_pos(self):
        return self._trajectory_pos
    def set_trajectory_pos(self, value):
        self._trajectory_pos = float(value)
        self.position = self.origin + self._trajectory_pos * self.trajectory
    trajectory_pos = property(get_trajectory_pos, set_trajectory_pos)

    ## methods public

    def simulate(self, nlist=[], frame_size=1):
        """record a multichanneled frame from neurons in range

        :Parameters:
            nlist : list
                List of Neuron instances to record from.
                Default=[]
            frame_size : int
                Size of the frame in samples.
                Default=1
        :Returns:
            list : A list of items for this frame. The first item is the noise
            for this frame. Subsequent items are tuples of waveform and interval
            data for the neurons that have significant (not all zero) waveforms
            in this frame for this recorder.
        """

        # init
        rval = None
        if self._noise_gen is None:
            rval = [N.zeros((frame_size, self.nchan))]
        else:
            rval = [self._noise_gen.query(size=frame_size) / self.snr]

        # for each neuron query waveform and firing data
        for nrn in nlist:
            try:
                rval.extend(nrn.query_for_recorder(self.points[:self.nchan]))
            except BadNeuronQuery:
                continue

        # return
        return tuple(rval)