def test_build_waveform_none(self):
        wfs = [DummyWaveform(duration=1.1, defined_channels={'A'}), DummyWaveform(duration=1.1, defined_channels={'B'})]

        sts = [DummyPulseTemplate(duration='t1', defined_channels={'A'}, waveform=wfs[0]),
               DummyPulseTemplate(duration='t1', defined_channels={'B'}, waveform=wfs[1]),
               DummyPulseTemplate(duration='t1', defined_channels={'C'}, waveform=None)]

        pt = AtomicMultiChannelPulseTemplate(*sts, parameter_constraints=['a < b'])

        parameters = dict(a=2.2, b=1.1, c=3.3)
        channel_mapping = dict(A=6)
        with self.assertRaises(ParameterConstraintViolation):
            # parameter constraints are checked before channel mapping is applied
            pt.build_waveform(parameters, channel_mapping=dict())

        parameters['a'] = 0.5
        wf = pt.build_waveform(parameters, channel_mapping=channel_mapping)
        self.assertIs(wf['A'], wfs[0])
        self.assertIs(wf['B'], wfs[1])

        sts[1].waveform = None
        wf = pt.build_waveform(parameters, channel_mapping=channel_mapping)
        self.assertIs(wf, wfs[0])

        sts[0].waveform = None
        wf = pt.build_waveform(parameters, channel_mapping=channel_mapping)
        self.assertIsNone(wf)
    def test_build_waveform(self):
        wfs = [
            DummyWaveform(duration=1.1, defined_channels={'A'}),
            DummyWaveform(duration=1.1, defined_channels={'B'})
        ]

        sts = [
            DummyPulseTemplate(duration='t1',
                               defined_channels={'A'},
                               parameter_names={'a', 'b'},
                               measurement_names={'A', 'C'},
                               waveform=wfs[0]),
            DummyPulseTemplate(duration='t1',
                               defined_channels={'B'},
                               parameter_names={'a', 'c'},
                               measurement_names={'A', 'B'},
                               waveform=wfs[1])
        ]

        pt = AtomicMultiChannelPulseTemplate(*sts,
                                             parameter_constraints=['a < b'])

        parameters = dict(a=2.2, b=1.1, c=3.3)
        channel_mapping = dict()
        with self.assertRaises(ParameterConstraintViolation):
            pt.build_waveform(parameters, channel_mapping=dict())

        parameters['a'] = 0.5
        wf = pt.build_waveform(parameters, channel_mapping=channel_mapping)
        self.assertEqual(wf['A'], wfs[0])
        self.assertEqual(wf['B'], wfs[1])

        for st in sts:
            self.assertEqual(st.build_waveform_calls,
                             [(parameters, channel_mapping)])
            self.assertIs(parameters, st.build_waveform_calls[0][0])
            self.assertIs(channel_mapping, st.build_waveform_calls[0][1])
    def test_instantiation_duration_check(self):
        subtemplates = [
            DummyPulseTemplate(parameter_names={'p1'},
                               measurement_names={'m1'},
                               defined_channels={'c1'},
                               duration='t_1',
                               waveform=DummyWaveform(duration=3,
                                                      defined_channels={'c1'
                                                                        })),
            DummyPulseTemplate(parameter_names={'p2'},
                               measurement_names={'m2'},
                               defined_channels={'c2'},
                               duration='t_2',
                               waveform=DummyWaveform(duration=3,
                                                      defined_channels={'c2'
                                                                        })),
            DummyPulseTemplate(parameter_names={'p3'},
                               measurement_names={'m3'},
                               defined_channels={'c3'},
                               duration='t_3',
                               waveform=DummyWaveform(duration=4,
                                                      defined_channels={'c3'}))
        ]

        with self.assertRaisesRegex(ValueError, 'duration equality'):
            AtomicMultiChannelPulseTemplate(*subtemplates)

        amcpt = AtomicMultiChannelPulseTemplate(*subtemplates, duration=True)
        self.assertIs(amcpt.duration, subtemplates[0].duration)

        with self.assertRaisesRegex(ValueError, 'duration'):
            amcpt.build_waveform(
                parameters=dict(t_1=3, t_2=3, t_3=3),
                channel_mapping={ch: ch
                                 for ch in 'c1 c2 c3'.split()})

        subtemplates[2].waveform = None
        amcpt.build_waveform(
            parameters=dict(t_1=3, t_2=3, t_3=3),
            channel_mapping={ch: ch
                             for ch in 'c1 c2 c3'.split()})

        amcpt = AtomicMultiChannelPulseTemplate(*subtemplates, duration='t_0')
        with self.assertRaisesRegex(ValueError, 'duration'):
            amcpt.build_waveform(
                parameters=dict(t_1=3, t_2=3, t_3=3, t_0=4),
                channel_mapping={ch: ch
                                 for ch in 'c1 c2 c3'.split()})
        with self.assertRaisesRegex(ValueError, 'duration'):
            amcpt.build_waveform(
                parameters=dict(t_1=3 + 1e-9, t_2=3, t_3=3, t_0=4),
                channel_mapping={ch: ch
                                 for ch in 'c1 c2 c3'.split()})
        amcpt.build_waveform(
            parameters=dict(t_1=3, t_2=3, t_3=3, t_0=3),
            channel_mapping={ch: ch
                             for ch in 'c1 c2 c3'.split()})
        amcpt.build_waveform(
            parameters=dict(t_1=3 + 1e-11, t_2=3, t_3=3, t_0=3),
            channel_mapping={ch: ch
                             for ch in 'c1 c2 c3'.split()})