def update_descriptors(self): logger.debug("Updating Plotter %s descriptors based on input descriptor %s", self.filter_name, self.sink.descriptor) self.stream = self.sink.input_streams[0] self.descriptor = self.sink.descriptor try: self.time_pts = self.descriptor.axes[self.descriptor.axis_num("time")].points self.record_length = len(self.time_pts) except ValueError: raise ValueError("Single shot filter sink does not appear to have a time axis!") self.num_averages = len(self.sink.descriptor.axes[self.descriptor.axis_num("averages")].points) self.num_segments = len(self.sink.descriptor.axes[self.descriptor.axis_num("segment")].points) self.ground_data = np.zeros((self.record_length, self.num_averages), dtype=np.complex) self.excited_data = np.zeros((self.record_length, self.num_averages), dtype=np.complex) self.total_points = self.num_segments*self.record_length*self.num_averages # Total points BEFORE sweep axes output_descriptor = DataStreamDescriptor() output_descriptor.axes = [_ for _ in self.descriptor.axes if type(_) is SweepAxis] output_descriptor._exp_src = self.sink.descriptor._exp_src output_descriptor.dtype = np.complex128 if len(output_descriptor.axes) == 0: output_descriptor.add_axis(DataAxis("Fidelity", [1])) for os in self.fidelity.output_streams: os.set_descriptor(output_descriptor) os.end_connector.update_descriptors()
def update_descriptors(self): logger.debug( 'Updating Channelizer "%s" descriptors based on input descriptor: %s.', self.name, self.sink.descriptor) # extract record time sampling self.time_pts = self.sink.descriptor.axes[-1].points self.record_length = len(self.time_pts) self.time_step = self.time_pts[1] - self.time_pts[0] logger.debug("Channelizer time_step = {}".format(self.time_step)) # We will be decimating along a time axis, which is always # going to be the last axis given the way we usually take data. # TODO: perform this function along a named axis rather than a numbered axis # in case something about this changes. # update output descriptors decimated_descriptor = DataStreamDescriptor() decimated_descriptor.axes = self.sink.descriptor.axes[:] decimated_descriptor.axes[-1] = deepcopy(self.sink.descriptor.axes[-1]) decimated_descriptor.axes[-1].points = self.sink.descriptor.axes[ -1].points[self.decimation_factor.value - 1::self.decimation_factor.value] decimated_descriptor.axes[ -1].original_points = decimated_descriptor.axes[-1].points decimated_descriptor._exp_src = self.sink.descriptor._exp_src decimated_descriptor.dtype = np.complex64 self.output_descriptor = decimated_descriptor for os in self.source.output_streams: os.set_descriptor(decimated_descriptor) if os.end_connector is not None: os.end_connector.update_descriptors()
def update_descriptors(self): if not self.simple_kernel and self.kernel.value is None: raise ValueError("Integrator was passed kernel None") logger.debug( 'Updating KernelIntegrator "%s" descriptors based on input descriptor: %s.', self.name, self.sink.descriptor) record_length = self.sink.descriptor.axes[-1].num_points() if self.simple_kernel.value: time_pts = self.sink.descriptor.axes[-1].points time_step = time_pts[1] - time_pts[0] kernel = np.zeros(record_length, dtype=np.complex128) sample_start = int(self.box_car_start.value / time_step) sample_stop = int(self.box_car_stop.value / time_step) + 1 kernel[sample_start:sample_stop] = 1.0 # add modulation kernel *= np.exp(2j * np.pi * self.frequency.value * time_step * time_pts) elif os.path.exists( os.path.join(config.KernelDir, self.kernel.value + '.txt')): kernel = np.loadtxt( os.path.join(config.KernelDir, self.kernel.value + '.txt'), dtype=complex, converters={ 0: lambda s: complex(s.decode().replace('+-', '-')) }) else: try: kernel = eval(self.kernel.value.encode('unicode_escape')) except: raise ValueError( 'Kernel invalid. Provide a file name or an expression to evaluate' ) # pad or truncate the kernel to match the record length if kernel.size < record_length: self.aligned_kernel = np.append( kernel, np.zeros(record_length - kernel.size, dtype=np.complex128)) else: self.aligned_kernel = np.resize(kernel, record_length) # Integrator reduces and removes axis on output stream # update output descriptors output_descriptor = DataStreamDescriptor() # TODO: handle reduction to single point output_descriptor.axes = self.sink.descriptor.axes[:-1] output_descriptor._exp_src = self.sink.descriptor._exp_src output_descriptor.dtype = np.complex128 for ost in self.source.output_streams: ost.set_descriptor(output_descriptor) ost.end_connector.update_descriptors()
def update_descriptors(self): if not self.kernel_type: raise ValueError("Integrator was passed kernel None") logger.debug( 'Updating WindowIntegrator "%s" descriptors based on input descriptor: %s.', self.name, self.sink.descriptor) record_length = self.sink.descriptor.axes[-1].num_points() time_pts = self.sink.descriptor.axes[-1].points time_step = time_pts[1] - time_pts[0] kernel = np.zeros(record_length, dtype=np.complex128) sample_start = int(self.box_car_start.value / time_step) sample_stop = int(self.box_car_stop.value / time_step) + 1 if self.kernel_type == 'boxcar': kernel[sample_start:sample_stop] = 1.0 elif self.kernel_type == 'chebwin': # create a Dolph-Chebyshev window with 100 dB attenuation kernel[sample_start:sample_stop] = \ chebwin(sample_start-sample_stop, at=100) elif self.kernel_type == 'blackman': kernel[sample_start:sample_stop] = \ blackman(sample_start-sample_stop) elif self.kernel_type == 'slepian': # create a Slepian window with 0.2 bandwidth kernel[sample_start:sample_stop] = \ slepian(sample_start-sample_stop, width=0.2) # add modulation kernel *= np.exp(2j * np.pi * self.frequency.value * time_step * time_pts) # pad or truncate the kernel to match the record length if kernel.size < record_length: self.aligned_kernel = np.append( kernel, np.zeros(record_length - kernel.size, dtype=np.complex128)) else: self.aligned_kernel = np.resize(kernel, record_length) # Integrator reduces and removes axis on output stream # update output descriptors output_descriptor = DataStreamDescriptor() # TODO: handle reduction to single point output_descriptor.axes = self.sink.descriptor.axes[:-1] output_descriptor._exp_src = self.sink.descriptor._exp_src output_descriptor.dtype = np.complex128 for os in self.source.output_streams: os.set_descriptor(output_descriptor) os.end_connector.update_descriptors()
def update_descriptors(self): if not self.simple_kernel and self.kernel.value is None: raise ValueError("Integrator was passed kernel None") logger.debug( 'Updating KernelIntegrator "%s" descriptors based on input descriptor: %s.', self.name, self.sink.descriptor) record_length = self.sink.descriptor.axes[-1].num_points() if self.simple_kernel.value: time_pts = self.sink.descriptor.axes[-1].points time_step = time_pts[1] - time_pts[0] kernel = np.zeros(record_length, dtype=np.complex128) sample_start = int(self.box_car_start.value / time_step) sample_stop = int(self.box_car_stop.value / time_step) + 1 kernel[sample_start:sample_stop] = 1.0 # add modulation kernel *= np.exp(2j * np.pi * self.frequency.value * time_step * time_pts) else: kernel = eval(self.kernel.value.encode('unicode_escape')) # pad or truncate the kernel to match the record length if kernel.size < record_length: self.aligned_kernel = np.append( kernel, np.zeros(record_length - kernel.size, dtype=np.complex128)) else: self.aligned_kernel = np.resize(kernel, record_length) # Integrator reduces and removes axis on output stream # update output descriptors output_descriptor = DataStreamDescriptor() # TODO: handle reduction to single point output_descriptor.axes = self.sink.descriptor.axes[:-1] output_descriptor._exp_src = self.sink.descriptor._exp_src output_descriptor.dtype = np.complex128 for os in self.source.output_streams: os.set_descriptor(output_descriptor) os.end_connector.update_descriptors()
def update_descriptors(self): logger.debug( "Updating Plotter %s descriptors based on input descriptor %s", self.name, self.sink.descriptor) self.stream = self.sink.input_streams[0] self.descriptor = self.sink.descriptor try: self.time_pts = self.descriptor.axes[self.descriptor.axis_num( "time")].points self.record_length = len(self.time_pts) except ValueError: raise ValueError( "Single shot filter sink does not appear to have a time axis!") try: rr_num = self.descriptor.axis_num("round_robins") except ValueError: pass if self.descriptor.axes[rr_num].num_points() > 1: raise ValueError( "Round robins for single shot filter should be set to 1!") self.num_segments = len(self.sink.descriptor.axes[ self.descriptor.axis_num("segment")].points) self.ground_data = np.zeros( (self.record_length, self.num_segments // 2), dtype=np.complex) self.excited_data = np.zeros( (self.record_length, self.num_segments // 2), dtype=np.complex) output_descriptor = DataStreamDescriptor() output_descriptor.axes = [ _ for _ in self.descriptor.axes if type(_) is SweepAxis ] output_descriptor._exp_src = self.sink.descriptor._exp_src output_descriptor.dtype = np.complex128 for os in self.fidelity.output_streams: os.set_descriptor(output_descriptor) os.end_connector.update_descriptors()
def update_descriptors(self): logger.debug( 'Updating Channelizer "%s" descriptors based on input descriptor: %s.', self.name, self.sink.descriptor) # extract record time sampling time_pts = self.sink.descriptor.axes[-1].points self.record_length = len(time_pts) self.time_step = time_pts[1] - time_pts[0] logger.debug("Channelizer time_step = {}".format(self.time_step)) # convert bandwidth normalized to Nyquist interval n_bandwidth = self.bandwidth.value * self.time_step * 2 n_frequency = self.frequency.value * self.time_step * 2 # arbitrarily decide on three stage filter pipeline # 1. first stage decimating filter on real data # 2. second stage decimating filter on mixed product to boost n_bandwidth # 3. final channel selecting filter at n_bandwidth/2 # anecdotally don't decimate more than a factor of eight for stability self.decim_factors = [1] * 3 self.filters = [None] * 3 # first stage decimating filter # maximize first stage decimation: # * minimize subsequent stages time taken # * filter and decimate while signal is still real # * first stage decimation cannot be too large or then 2omega signal from mixing will alias d1 = 1 while (d1 < 8) and (2 * n_frequency <= 0.8 / d1) and (d1 < self.decimation_factor.value): d1 *= 2 n_bandwidth *= 2 n_frequency *= 2 if d1 > 1: # create an anti-aliasing filter # pass-band to 0.8 * decimation factor; anecdotally single precision needs order <= 4 for stability b, a = scipy.signal.cheby1(4, 3, 0.8 / d1) b = np.float32(b) a = np.float32(a) self.decim_factors[0] = d1 self.filters[0] = (b, a) # store decimated reference for mix down ref = np.exp(2j * np.pi * self.frequency.value * time_pts[::d1], dtype=np.complex64) self.reference_r = np.real(ref) self.reference_i = np.imag(ref) # second stage filter to bring n_bandwidth/2 up # decimation cannot be too large or will impinge on channel bandwidth (keep n_bandwidth/2 <= 0.8) d2 = 1 while (d2 < 8) and ((d1 * d2) < self.decimation_factor.value) and ( n_bandwidth / 2 <= 0.8): d2 *= 2 n_bandwidth *= 2 n_frequency *= 2 if d2 > 1: # create an anti-aliasing filter # pass-band to 0.8 * decimation factor; anecdotally single precision needs order <= 4 for stability b, a = scipy.signal.cheby1(4, 3, 0.8 / d2) b = np.float32(b) a = np.float32(a) self.decim_factors[1] = d2 self.filters[1] = (b, a) # final channel selection filter if n_bandwidth < 0.1: raise ValueError( "Insufficient decimation to achieve stable filter") b, a = scipy.signal.cheby1(4, 3, n_bandwidth / 2) b = np.float32(b) a = np.float32(a) self.decim_factors[2] = self.decimation_factor.value // (d1 * d2) self.filters[2] = (b, a) # update output descriptors decimated_descriptor = DataStreamDescriptor() decimated_descriptor.axes = self.sink.descriptor.axes[:] decimated_descriptor.axes[-1] = deepcopy(self.sink.descriptor.axes[-1]) decimated_descriptor.axes[-1].points = self.sink.descriptor.axes[ -1].points[self.decimation_factor.value - 1::self.decimation_factor.value] decimated_descriptor.axes[ -1].original_points = decimated_descriptor.axes[-1].points decimated_descriptor.exp_src = self.sink.descriptor.exp_src decimated_descriptor.dtype = np.complex64 for os in self.source.output_streams: os.set_descriptor(decimated_descriptor) if os.end_connector is not None: os.end_connector.update_descriptors()