Beispiel #1
0
class CounterPart(Part):
    """Defines a counter `Attribute` with zero and increment `Method` objects"""
    def __init__(self, name):
        # type: (APartName) -> None
        super(CounterPart, self).__init__(name)
        # TODO: why doesn't this show up in the docs for CounterPart?
        self.counter = NumberMeta("float64",
                                  "The current value of the counter",
                                  tags=[config_tag(),
                                        Widget.TEXTINPUT.tag()
                                        ]).create_attribute_model()
        """Attribute holding the current counter value"""

    def setup(self, registrar):
        # type: (PartRegistrar) -> None
        # Add some Attribute and Methods to the Block
        registrar.add_attribute_model("counter", self.counter,
                                      self.counter.set_value)
        registrar.add_method_model(self.zero)
        registrar.add_method_model(self.increment)

    def zero(self):
        """Zero the counter attribute"""
        self.counter.set_value(0)

    def increment(self):
        """Add one to the counter attribute"""
        self.counter.set_value(self.counter.value + 1)
Beispiel #2
0
    def setup(self, registrar: PartRegistrar) -> None:
        attr = TableMeta.from_table(
            SequencerTable,
            "Sequencer Table",
            writeable=list(
                SequencerTable.call_types)).create_attribute_model()
        self.table_set = MagicMock(side_effect=attr.set_value)
        registrar.add_attribute_model("table", attr, self.table_set)
        for suff, val in (("a", "INENC1.VAL"), ("b", "INENC2.VAL"), ("c",
                                                                     "ZERO")):
            attr = StringMeta("Input").create_attribute_model(val)
            registrar.add_attribute_model(f"pos{suff}", attr)
        attr = StringMeta("Input").create_attribute_model("ZERO")
        registrar.add_attribute_model("bita", attr)

        attr = BooleanMeta("Active", (), True).create_attribute_model(False)
        registrar.add_attribute_model("active", attr, attr.set_value)

        attr = NumberMeta("int16", "repeats",
                          writeable=True).create_attribute_model(1)
        registrar.add_attribute_model("repeats",
                                      attr,
                                      writeable_func=attr.set_value)

        attr = NumberMeta("int16", "prescale",
                          writeable=True).create_attribute_model(0)
        registrar.add_attribute_model("prescale",
                                      attr,
                                      writeable_func=attr.set_value)
 def __init__(self, name, wait=0.0):
     # type: (APartName, AWait) -> None
     super(WaitingPart, self).__init__(name)
     meta = NumberMeta("float64", "How long to wait")
     set_tags(meta, writeable=True)
     self.attr = meta.create_attribute_model(wait)
     self.register_hooked(RunHook, self.run)
Beispiel #4
0
def exposure_attribute(min_exposure: float) -> AttributeModel:
    meta = NumberMeta(
        "float64",
        "The calculated exposure for this run",
        tags=[Widget.TEXTUPDATE.tag()],
        display=Display(precision=6, units="s", limitLow=min_exposure),
    )
    return meta.create_attribute_model()
Beispiel #5
0
 def __init__(self, name):
     # type: (APartName) -> None
     super(CounterPart, self).__init__(name)
     # TODO: why doesn't this show up in the docs for CounterPart?
     self.counter = NumberMeta("float64",
                               "The current value of the counter",
                               tags=[config_tag(),
                                     Widget.TEXTINPUT.tag()
                                     ]).create_attribute_model()
     """Attribute holding the current counter value"""
Beispiel #6
0
 def __init__(
     self,
     mri: AMri,
     config_dir: AConfigDir,
     hostname: AHostname = "localhost",
     port: APort = 8888,
     doc_url_base: ADocUrlBase = DOC_URL_BASE,
     poll_period: APollPeriod = 0.1,
     template_designs: ATemplateDesigns = "",
     initial_design: AInitialDesign = "",
     use_git: AUseGit = True,
     description: ADescription = "",
 ) -> None:
     super().__init__(
         mri=mri,
         config_dir=config_dir,
         template_designs=template_designs,
         initial_design=initial_design,
         use_git=use_git,
         description=description,
     )
     self._poll_period = poll_period
     self._doc_url_base = doc_url_base
     # All the bit_out fields and their values
     # {block_name.field_name: value}
     self._bit_outs: Dict[str, bool] = {}
     # The bit_out field values that need toggling since the last handle
     # {block_name.field_name: value}
     self._bit_out_changes: Dict[str, bool] = {}
     # The fields that busses needs to know about
     # {block_name.field_name[.subfield_name]}
     self._bus_fields: Set[str] = set()
     # The child controllers we have created
     self._child_controllers: Dict[str, PandABlockController] = {}
     # The PandABlock client that does the comms
     self._client = PandABlocksClient(hostname, port, Queue)
     # Filled in on reset
     self._stop_queue = None
     self._poll_spawned = None
     # Poll period reporting
     self.last_poll_period = NumberMeta(
         "float64",
         "The time between the last 2 polls of the hardware",
         tags=[Widget.TEXTUPDATE.tag()],
         display=Display(units="s", precision=3),
     ).create_attribute_model(poll_period)
     self.field_registry.add_attribute_model("lastPollPeriod",
                                             self.last_poll_period)
     # Bus tables
     self.busses: PandABussesPart = self._make_busses()
     self.add_part(self.busses)
 def setup(self, registrar: PartRegistrar) -> None:
     super().setup(registrar)
     # Hooks
     registrar.hook(scanning.hooks.ReportStatusHook, self.on_report_status)
     registrar.hook(scanning.hooks.ValidateHook, self.on_validate)
     registrar.hook(
         scanning.hooks.ConfigureHook,
         self.on_configure,
         self.configure_args_with_exposure,
     )
     registrar.hook(
         scanning.hooks.SeekHook,
         self.on_seek,
         self.configure_args_with_exposure,
     )
     registrar.hook(scanning.hooks.RunHook, self.on_run)
     registrar.hook(scanning.hooks.PostRunArmedHook, self.on_post_run_armed)
     registrar.hook((scanning.hooks.PauseHook, scanning.hooks.AbortHook),
                    self.on_abort)
     # Attributes
     registrar.add_attribute_model("attributesToCapture",
                                   self.extra_attributes,
                                   self.set_extra_attributes)
     # Tell the controller to pass "exposure" and "frames_per_step" to configure
     info = scanning.infos.ConfigureParamsInfo(
         metas=dict(frames_per_step=NumberMeta.from_annotype(
             ADetectorFramesPerStep, writeable=False), ),
         required=[],
         defaults=dict(frames_per_step=1),
     )
     registrar.report(info)
Beispiel #8
0
 def __init__(self,
              pv_prefix: APvPrefix,
              group: ca.util.AGroup = None) -> None:
     super().__init__("sinkPorts")
     self.pvs = [pv_prefix + ":CsPort", pv_prefix + ":CsAxis"]
     self.rbvs = [
         pv_prefix + ":CsPort_RBV",
         pv_prefix + ":CsAxis_RBV",
         pv_prefix + ".OUT",
     ]
     meta = ChoiceMeta("CS Axis")
     builtin.util.set_tags(meta,
                           writeable=True,
                           group=group,
                           sink_port=Port.MOTOR)
     self.cs_attr = meta.create_attribute_model()
     meta = StringMeta("Parent PMAC Port name")
     builtin.util.set_tags(meta, group=group, sink_port=Port.MOTOR)
     self.pmac_attr = meta.create_attribute_model()
     meta = NumberMeta("int32", "Parent PMAC Axis number")
     builtin.util.set_tags(meta, group=group)
     self.axis_num_attr = meta.create_attribute_model()
     # Subscriptions
     self.monitors: List = []
     self.port = None
     self.axis = None
     self.port_choices: List = []
Beispiel #9
0
 def __init__(
     self,
     name: util.APartName,
     description: util.AMetaDescription,
     pv: util.APv = "",
     rbv: util.ARbv = "",
     rbv_suffix: util.ARbvSuffix = "",
     min_delta: util.AMinDelta = 0.05,
     timeout: util.ATimeout = DEFAULT_TIMEOUT,
     sink_port: util.ASinkPort = None,
     widget: util.AWidget = None,
     group: util.AGroup = None,
     config: util.AConfig = True,
     display_from_pv: util.AGetLimits = True,
     throw: util.AThrow = True,
 ) -> None:
     super().__init__(name)
     self.display_from_pv = display_from_pv
     self.caa = util.CAAttribute(
         NumberMeta("float64", description),
         util.catools.DBR_DOUBLE,
         pv,
         rbv,
         rbv_suffix,
         min_delta,
         timeout,
         sink_port,
         widget,
         group,
         config,
         on_connect=self._update_display,
         throw=throw,
     )
Beispiel #10
0
 def __init__(
         self,
         name,  # type: APartName
         description,  # type: AMetaDescription
         writeable=False,  # type: AWriteable
         config=1,  # type: AConfig
         group=None,  # type: AGroup
         widget=None,  # type: AWidget
         value=0.0,  # type: Value
 ):
     # type: (...) -> None
     super(Float64Part, self).__init__(name)
     meta = NumberMeta("float64", description)
     set_tags(meta, writeable, config, group, widget)
     self.attr = meta.create_attribute_model(value)
     self.writeable_func = self.attr.set_value if writeable else None
Beispiel #11
0
 def __init__(
     self,
     name: util.APartName,
     description: util.AMetaDescription,
     pv: util.APv = "",
     rbv: util.ARbv = "",
     rbv_suffix: util.ARbvSuffix = "",
     min_delta: util.AMinDelta = 0.05,
     timeout: util.ATimeout = DEFAULT_TIMEOUT,
     sink_port: util.ASinkPort = None,
     widget: util.AWidget = None,
     group: util.AGroup = None,
     config: util.AConfig = True,
     throw: util.AThrow = True,
 ) -> None:
     super().__init__(name)
     self.caa = util.CAAttribute(
         NumberMeta("int32", description),
         util.catools.DBR_LONG,
         pv,
         rbv,
         rbv_suffix,
         min_delta,
         timeout,
         sink_port,
         widget,
         group,
         config,
         throw=throw,
     )
Beispiel #12
0
 def _make_mux_delay(self, field_name: str) -> None:
     group = self._make_group("inputs")
     meta = NumberMeta(
         "uint8",
         "How many FPGA ticks to delay input",
         tags=[group, Widget.TEXTINPUT.tag()],
     )
     self._make_field_part(field_name + ".DELAY", meta, writeable=True)
Beispiel #13
0
 def __init__(self, name: APartName, mri: AMri) -> None:
     super().__init__(name, mri)
     self.targetSamplesPerFrame = NumberMeta(
         "uint32",
         "Target samples that each frame contains, "
         "0 for maximum, -1 for not controlling it.",
         tags=[Widget.TEXTINPUT.tag()],
     ).create_attribute_model()
Beispiel #14
0
 def _make_scale_offset(self, field_name):
     group = self._make_group("outputs")
     meta = StringMeta("Units for position fields on this block",
                       tags=[group, Widget.TEXTINPUT.tag()])
     self._make_field_part(field_name + ".UNITS", meta, writeable=True)
     meta = NumberMeta("float64",
                       "Scale for block position fields",
                       tags=[group, Widget.TEXTINPUT.tag()])
     self._make_field_part(field_name + ".SCALE", meta, writeable=True)
     meta = NumberMeta("float64",
                       "Offset for block position fields",
                       tags=[group, Widget.TEXTINPUT.tag()])
     self._make_field_part(field_name + ".OFFSET", meta, writeable=True)
     meta = NumberMeta("float64",
                       "Current scaled value of position field",
                       tags=[group, Widget.TEXTUPDATE.tag()])
     self._make_field_part(field_name + ".SCALED", meta, writeable=False)
Beispiel #15
0
 def test_from_dict(self):
     nm = NumberMeta.from_dict(self.serialized)
     assert type(nm) == NumberMeta
     assert nm.description == "desc"
     assert nm.dtype == "float64"
     assert nm.tags == []
     assert not nm.writeable
     assert nm.label == "name"
Beispiel #16
0
 def setup(self, registrar: PartRegistrar) -> None:
     super().setup(registrar)
     # Validate hook for exposure time
     registrar.hook(scanning.hooks.ValidateHook, self.on_validate)
     # Attributes
     registrar.add_attribute_model("exposure", self.exposure)
     # Tell the controller to pass "exposure" and "frames_per_step" to configure
     info = scanning.infos.ConfigureParamsInfo(
         metas=dict(
             exposure=NumberMeta.from_annotype(scanning.hooks.AExposure,
                                               writeable=True),
             frames_per_step=NumberMeta.from_annotype(AFramesPerStep,
                                                      writeable=False),
         ),
         required=[],
         defaults=dict(exposure=0.0, frames_per_step=1),
     )
     registrar.report(info)
Beispiel #17
0
def make_meta(subtyp, description, tags, writeable=True, labels=None):
    if subtyp == "enum":
        meta = ChoiceMeta(description, labels)
    elif subtyp == "bit":
        meta = BooleanMeta(description)
    elif subtyp in ("uint", ""):
        meta = NumberMeta("uint32", description)
    elif subtyp in ("int", "pos"):
        meta = NumberMeta("int32", description)
    elif subtyp == "scalar":
        meta = NumberMeta("float64", description)
    elif subtyp == "lut":
        meta = StringMeta(description)
    else:
        raise ValueError("Unknown subtype %r" % subtyp)
    meta.set_writeable(writeable)
    tags.append(meta.default_widget().tag())
    meta.set_tags(tags)
    return meta
Beispiel #18
0
 def __init__(
     self,
     name: APartName = "minTurnaround",
     gap: AMinTurnaround = None,
     interval: ATurnaroundInterval = None,
 ) -> None:
     super().__init__(name)
     self.gap = NumberMeta(
         "float64",
         "Minimum time for any gaps between non-joined points",
         tags=[Widget.TEXTINPUT.tag(), config_tag()],
         display=Display(precision=6, units="s"),
     ).create_attribute_model(gap)
     self.interval = NumberMeta(
         "float64",
         "Minimum interval between turnaround points",
         tags=[Widget.TEXTINPUT.tag(), config_tag()],
         display=Display(precision=6, units="s"),
     ).create_attribute_model(interval)
Beispiel #19
0
 def __init__(
     self,
     name: APartName,
     mri: AMri,
 ) -> None:
     super().__init__(name, mri, initial_visibility=True)
     # The total number of points we have written
     self.total_points = 0
     self.points_scanned = NumberMeta(
         "int32", "The number of points scanned", tags=[Widget.METER.tag()]
     ).create_attribute_model(0)
Beispiel #20
0
 def setup(self, registrar: PartRegistrar) -> None:
     super().setup(registrar)
     # Attributes
     registrar.add_attribute_model("exposure", self.exposure)
     # Tell the controller to pass "exposure" to configure
     info = scanning.infos.ConfigureParamsInfo(
         metas=dict(exposure=NumberMeta.from_annotype(
             scanning.hooks.AExposure, writeable=True)),
         required=[],
         defaults=dict(exposure=0.0),
     )
     registrar.report(info)
Beispiel #21
0
    def setup(self, registrar: PartRegistrar) -> None:
        super().setup(registrar)
        # Add some Attribute and Methods to the Block
        self.counter = NumberMeta(
            "float64",
            "The current value of the counter",
            tags=[config_tag(), Widget.TEXTINPUT.tag()],
        ).create_attribute_model()
        registrar.add_attribute_model("counter", self.counter,
                                      self.counter.set_value)

        self.delta = NumberMeta(
            "float64",
            "The amount to increment() by",
            tags=[config_tag(), Widget.TEXTINPUT.tag()],
        ).create_attribute_model(initial_value=1)
        registrar.add_attribute_model("delta", self.delta,
                                      self.delta.set_value)

        registrar.add_method_model(self.zero)
        registrar.add_method_model(self.increment)
 def __init__(
     self,
     name: APartName,
     initial_readout_time: AInitialReadoutTime = 0.0,
     initial_frequency_accuracy: AInitialAccuracy = 50.0,
     min_exposure: AMinExposure = 0.0,
 ) -> None:
     super().__init__(name)
     self.readout_time = NumberMeta(
         "float64",
         readout_desc,
         tags=[Widget.TEXTINPUT.tag(), config_tag()],
         display=Display(precision=6, units="s"),
     ).create_attribute_model(initial_readout_time)
     self.frequency_accuracy = NumberMeta(
         "float64",
         frequency_accuracy_desc,
         tags=[Widget.TEXTINPUT.tag(), config_tag()],
         display=Display(precision=3, units="ppm"),
     ).create_attribute_model(initial_frequency_accuracy)
     self.min_exposure = min_exposure
     self.exposure = exposure_attribute(min_exposure)
Beispiel #23
0
 def __init__(
     self,
     name: APartName,
     description: AMetaDescription,
     writeable: AWriteable = False,
     config: AConfig = 1,
     group: AGroup = None,
     widget: AWidget = None,
     value: AValue = 0.0,
     limit_low: ULimitLow = 0,
     limit_high: ULimitHigh = 0,
     precision: UPrecision = 8,
     units: AUnits = "",
 ) -> None:
     super().__init__(name)
     display = Display(
         limitLow=limit_low, limitHigh=limit_high, precision=precision, units=units
     )
     meta = NumberMeta("float64", description, display=display)
     set_tags(meta, writeable, config, group, widget)
     self.attr = meta.create_attribute_model(value)
     self.writeable_func = self.attr.set_value if writeable else None
Beispiel #24
0
 def __init__(
     self,
     name,  # type: APartName
     initial_readout_time=0.0,  # type: AInitialReadoutTime
     initial_frequency_accuracy=50.0  # type: AInitialAccuracy
 ):
     # type: (...) -> None
     super(ExposureDeadtimePart, self).__init__(name)
     self.readout_time = NumberMeta(
         "float64",
         readout_desc,
         tags=[Widget.TEXTINPUT.tag(),
               config_tag()]).create_attribute_model(initial_readout_time)
     self.frequency_accuracy = NumberMeta(
         "float64",
         frequency_accuracy_desc,
         tags=[Widget.TEXTINPUT.tag(), config_tag()
               ]).create_attribute_model(initial_frequency_accuracy)
     # Hooks
     self.register_hooked(scanning.hooks.ReportStatusHook,
                          self.report_status)
     self.register_hooked(scanning.hooks.ValidateHook, self.validate)
Beispiel #25
0
 def setup(self, registrar: PartRegistrar) -> None:
     self.mocks = {}
     self.units = {}
     for suffix in ["step", "delay", "width", "pulses"]:
         # Add an attribute that will be set
         attr = NumberMeta("float64").create_attribute_model()
         mock = MagicMock(side_effect=attr.set_value)
         registrar.add_attribute_model(suffix, attr, mock)
         self.mocks[suffix] = mock
         if suffix != "pulses":
             # Add a units attribute that will be read
             units_attr = StringMeta().create_attribute_model("s")
             registrar.add_attribute_model(suffix + "Units", units_attr)
             self.units[suffix] = units_attr
Beispiel #26
0
class CounterPart(Part):
    """Defines a counter `Attribute` with zero and increment `Method` objects"""

    #: Writeable Attribute holding the current counter value
    counter: Optional[AttributeModel] = None
    #: Writeable Attribute holding the amount to increment() by
    delta: Optional[AttributeModel] = None

    def setup(self, registrar: PartRegistrar) -> None:
        super().setup(registrar)
        # Add some Attribute and Methods to the Block
        self.counter = NumberMeta(
            "float64",
            "The current value of the counter",
            tags=[config_tag(), Widget.TEXTINPUT.tag()],
        ).create_attribute_model()
        registrar.add_attribute_model("counter", self.counter,
                                      self.counter.set_value)

        self.delta = NumberMeta(
            "float64",
            "The amount to increment() by",
            tags=[config_tag(), Widget.TEXTINPUT.tag()],
        ).create_attribute_model(initial_value=1)
        registrar.add_attribute_model("delta", self.delta,
                                      self.delta.set_value)

        registrar.add_method_model(self.zero)
        registrar.add_method_model(self.increment)

    def zero(self):
        """Zero the counter attribute"""
        self.counter.set_value(0)

    def increment(self):
        """Add delta to the counter attribute"""
        self.counter.set_value(self.counter.value + self.delta.value)
Beispiel #27
0
 def _make_time_parts(self, field_name, field_data, writeable):
     description = field_data.description
     if writeable:
         widget = Widget.TEXTINPUT
         group = self._make_group("parameters")
     else:
         widget = Widget.TEXTUPDATE
         group = self._make_group("readbacks")
     meta = NumberMeta("float64", description, [group, widget.tag()])
     # We must change time units before value, so restore value in 2nd
     # iteration
     self._make_field_part(field_name, meta, writeable, iteration=2)
     meta = ChoiceMeta(description + " time units", ["s", "ms", "us"],
                       tags=[group, Widget.COMBO.tag()])
     self._make_field_part(field_name + ".UNITS", meta, writeable=True)
Beispiel #28
0
 def __init__(self,
              name,  # type: util.APartName
              description,  # type: util.AMetaDescription
              pv="",  # type: util.APv
              rbv="",  # type: util.ARbv
              rbv_suffix="",  # type: util.ARbvSuffix
              min_delta=0.05,  # type: util.AMinDelta
              timeout=DEFAULT_TIMEOUT,  # type: util.ATimeout
              sink_port=None,  # type: util.ASinkPort
              widget=None,  # type: util.AWidget
              group=None,  # type: util.AGroup
              config=True,  # type: util.AConfig
              ):
     # type: (...) -> None
     super(CADoublePart, self).__init__(name)
     self.caa = util.CAAttribute(
         NumberMeta("float64", description), util.catools.DBR_DOUBLE, pv,
         rbv, rbv_suffix, min_delta, timeout, sink_port, widget, group,
         config)
Beispiel #29
0
    def __init__(self, name: APartName, mri: AMri) -> None:
        super().__init__(name, mri, stateful=False, initial_visibility=True)
        self.runner_config = None
        self.context: Optional[AContext] = None
        self.scan_sets: Dict[str, Scan] = {}

        self.runner_state = StringMeta(
            "Runner state",
            tags=Widget.TEXTUPDATE.tag()).create_attribute_model("Idle")
        self.runner_status_message = StringMeta(
            "Runner status message",
            tags=Widget.TEXTUPDATE.tag()).create_attribute_model("Idle")
        self.scan_file = StringMeta(
            "Path to input scan file",
            tags=[config_tag(),
                  Widget.TEXTINPUT.tag()]).create_attribute_model()
        self.scans_configured = NumberMeta(
            "int64",
            "Number of configured scans",
            tags=Widget.TEXTUPDATE.tag()).create_attribute_model()
        self.current_scan_set = StringMeta(
            "Current scan set",
            tags=Widget.TEXTUPDATE.tag()).create_attribute_model()
        self.scans_completed = NumberMeta(
            "int64", "Number of scans completed",
            tags=Widget.TEXTUPDATE.tag()).create_attribute_model()
        self.scan_successes = NumberMeta("int64",
                                         "Successful scans",
                                         tags=[Widget.TEXTUPDATE.tag()
                                               ]).create_attribute_model()
        self.scan_failures = NumberMeta("int64",
                                        "Failed scans",
                                        tags=[Widget.TEXTUPDATE.tag()
                                              ]).create_attribute_model()
        self.output_directory = StringMeta(
            "Root output directory (will create a sub-directory inside)",
            tags=[config_tag(), Widget.TEXTINPUT.tag()],
        ).create_attribute_model()
 def __init__(
     self,
     name,  # type: builtin.parts.APartName
     mri,  # type: builtin.parts.AMri
     initial_min_turnaround=0.0  # type: AMinTurnaround
 ):
     # type: (...) -> None
     super(PmacTrajectoryPart, self).__init__(name,
                                              mri,
                                              initial_visibility=True)
     # Axis information stored from validate
     self.axis_mapping = None  # type: Dict[str, MotorInfo]
     # Lookup of the completed_step value for each point
     self.completed_steps_lookup = []  # type: List[int]
     # If we are currently loading then block loading more points
     self.loading = False
     # Where we have generated into profile
     self.end_index = 0
     # Where we should stop loading points
     self.steps_up_to = 0
     # Profile points that haven't been sent yet
     # {time_array/velocity_mode/trajectory/user_programs: [elements]}
     self.profile = {}
     # Stored generator for positions
     self.generator = None  # type: CompoundGenerator
     # Attribute info
     self.min_turnaround = NumberMeta(
         "float64",
         "Min time for any gaps between frames",
         tags=[Widget.TEXTINPUT.tag(),
               config_tag()]).create_attribute_model(initial_min_turnaround)
     # Hooks
     self.register_hooked(scanning.hooks.ValidateHook, self.validate)
     self.register_hooked(
         (scanning.hooks.ConfigureHook, scanning.hooks.PostRunArmedHook,
          scanning.hooks.SeekHook), self.configure)
     self.register_hooked(
         (scanning.hooks.RunHook, scanning.hooks.ResumeHook), self.run)
     self.register_hooked(
         (scanning.hooks.AbortHook, scanning.hooks.PauseHook), self.abort)