diff --git a/pulse_lib/acquisition/measurement_converter.py b/pulse_lib/acquisition/measurement_converter.py index a146b6ec89e9330b8da06002c3241e0f6bdfe741..76351f6921f484dbcb9cf1a6fb2dc6ca5db9ab87 100644 --- a/pulse_lib/acquisition/measurement_converter.py +++ b/pulse_lib/acquisition/measurement_converter.py @@ -170,6 +170,52 @@ class MeasurementParameter(MultiParameter): self.units += (unit,) self.labels += (label,) + def add_sensor_histogram(self, sensor, bins, range, accepted_only=False): + ''' + Adds histograms for all measurements of sensor. + + Args: + sensor (str): name of sensor in pulse-lib. + bins (int): number of bins in histogram. + range (Tuple[float,float]): upper and lower edge of histogram. + accepted_only (bool): if True only count accepted shots + ''' + for m in self._mc._description.measurements: + if getattr(m, 'acquisition_channel', None) == sensor: + self.add_measurement_histogram(m.name, bins, range, + accepted_only=accepted_only) + + def add_measurement_histogram(self, m_name, bins, range, accepted_only=False): + ''' + Adds histogram for specified measurement. + + Args: + m_name (str): name of measurement in sequence. + bins (int): number of bins in histogram. + range (Tuple[float,float]): upper and lower edge of histogram. + accepted_only (bool): if True only count accepted shots + ''' + def _histogram(data): + if accepted_only: + if 'mask' not in data: + raise Exception('Cannot filter on accepted. Accept mask is not in data.') + d = data[m_name][data['mask'].astype(bool)] + else: + d = data[m_name] + return np.histogram(d, bins=binedges)[0]/d.shape[0] + + binedges = np.linspace(range[0], range[1], bins+1) + bincenters = (binedges[1:] + binedges[:-1])/2 + setpoints = (tuple(bincenters),) + setpoint_names = ('sensor_val',) + self.add_derived_param( + f'{m_name}_hist', + _histogram, + unit='', + setpoints=setpoints, + setpoint_units=('mV',), + setpoint_names=setpoint_names, + setpoint_labels=setpoint_names) def get_raw(self): data = self._source.get_channel_data() diff --git a/pulse_lib/tests/acquire/test_measurement_histogram.py b/pulse_lib/tests/acquire/test_measurement_histogram.py new file mode 100644 index 0000000000000000000000000000000000000000..108097226eec85006b7660f3efbbeb602746a7ce --- /dev/null +++ b/pulse_lib/tests/acquire/test_measurement_histogram.py @@ -0,0 +1,28 @@ + +from pulse_lib.tests.configurations.test_configuration import context + + +#%% +def test1(): + pulse = context.init_pulselib(n_gates=2, n_sensors=2) + + s = pulse.mk_segment() + + s.P1.add_block(0, 20, 100) + s.P2.add_block(0, 20, -100) + s.SD1.acquire(0, 1000, wait=True) + s.SD2.acquire(0, 1000, wait=True, threshold=3000, accept_if=1) + + sequence = pulse.mk_sequence([s]) + sequence.n_rep = 10 + m_param = sequence.get_measurement_param(selectors=False, total_selected=False) + m_param.add_sensor_histogram('SD1', 20, (0.0, 20_000.0)) + m_param.add_sensor_histogram('SD2', 20, (0.0, 20_000.0), accepted_only=True) + context.add_hw_schedule(sequence) + + return context.run('histogram', sequence, m_param) + +#%% + +if __name__ == '__main__': + ds1 = test1()