def format_field(self, value, spec):
     if spec.endswith('n'):  # 'n' for number
         precision = 2
         if spec.startswith('.', 0, -1):
             precision = int(spec[1:-1])
         if is_finite_scalar(value):
             factor = 1
             abs_val = abs(value)
             for i in range(precision):
                 no_decimals = int(abs_val * factor + 0.5)
                 scaled = abs_val * factor
                 if is_close(scaled, no_decimals):
                     precision = i
                     break
                 factor *= 10
             fmt = f'{{:.{ precision }f}}'
             result = fmt.format(value)
             return result
         elif hasattr(value, 'format'):
             return value.format(format_spec="{0:%s}" % spec, formatter=self)
         else:
             return str(value)
     return super().format_field(value, spec)
    def dispense(self,
                 volume=None,
                 location=None,
                 rate=1.0,
                 full_dispense: bool = False,
                 top_clearance=None,
                 bottom_clearance=None,
                 manual_liquid_volume_allowance=None):
        if not helpers.is_number(volume):  # recapitulate super
            if volume and not location:
                location = volume
            volume = self._working_volume - self.current_volume
        location = location if location else self.previous_placeable
        well, _ = well_vector(location)

        if top_clearance is None:
            if tls.dispense_params_transfer:
                top_clearance = tls.dispense_params_transfer.top_clearance_transfer
            if top_clearance is None:
                top_clearance = self.config.dispense.top_clearance
        if bottom_clearance is None:
            if tls.dispense_params_transfer:
                bottom_clearance = tls.dispense_params_transfer.bottom_clearance_transfer
            if bottom_clearance is None:
                bottom_clearance = self.config.dispense.bottom_clearance
        if manual_liquid_volume_allowance is None:
            if tls.dispense_params_transfer:
                manual_liquid_volume_allowance = tls.dispense_params_transfer.manual_manufacture_tolerance_transfer
            if manual_liquid_volume_allowance is None:
                manual_liquid_volume_allowance = self.config.dispense.manual_liquid_volume_allowance

        if is_close(volume, self.current_volume
                    ):  # avoid finicky floating-point precision issues
            volume = self.current_volume
        location = self._adjust_location_to_liquid_top(
            location=location,
            aspirate_volume=None,
            top_clearance=top_clearance,
            bottom_clearance=bottom_clearance,
            manual_liquid_volume_allowance=manual_liquid_volume_allowance)

        with DispenseParams():
            tls.dispense_params.full_dispense_from_dispense = full_dispense

            def call_super():
                super(EnhancedPipette, self).dispense(volume=volume,
                                                      location=location,
                                                      rate=rate)

            self._update_pose_tree_in_place(call_super)

            if tls.dispense_params.fully_dispensed:
                assert self.current_volume == 0
                if self.current_volume == 0:
                    pass  # nothing to do: the next self._position_for_aspirate will reposition for us: 'if pipette is currently empty, ensure the plunger is at "bottom"'
                else:
                    raise NotImplementedError

            # track volume
            well, __ = well_vector(location)
            well.liquid_volume.dispense(volume)
Beispiel #3
0
    def dispense(
            self,
            volume=None,
            location=None,
            rate=1.0,
            # remainder are added params
            full_dispense: bool = False,
            top_clearance=None,
            bottom_clearance=None,
            manual_liquid_volume_allowance=None):
        # figure out where we're dispensing to
        # recapitulate super
        if isinstance(location, WellV2):
            if 'fixedTrash' in quirks_from_any_parent(location):
                loc = location.top()
            else:
                point, well = location.bottom()
                loc = types.Location(
                    point +
                    types.Point(0, 0, self.well_bottom_clearance.dispense),
                    well)
            self.move_to(loc)
        elif isinstance(location, types.Location):
            loc = location
            self.move_to(location)
        elif location is not None:
            raise TypeError(
                'location should be a Well or Location, but it is {}'.format(
                    location))
        elif self._ctx.location_cache:
            loc = self._ctx.location_cache
        else:
            raise RuntimeError(
                "If dispense is called without an explicit location, another method that moves to a location (such as move_to or aspirate) must previously have been called so the robot knows where it is."
            )

        location = loc  # no need for new variable
        assert isinstance(location, types.Location)
        point, well = location

        if top_clearance is None:
            if tls.dispense_params_transfer:
                top_clearance = tls.dispense_params_transfer.top_clearance_transfer
            if top_clearance is None:
                top_clearance = self.well_top_clearance.dispense
        if bottom_clearance is None:
            if tls.dispense_params_transfer:
                bottom_clearance = tls.dispense_params_transfer.bottom_clearance_transfer
            if bottom_clearance is None:
                bottom_clearance = self.well_bottom_clearance.dispense
        if manual_liquid_volume_allowance is None:
            if tls.dispense_params_transfer:
                manual_liquid_volume_allowance = tls.dispense_params_transfer.manual_manufacture_tolerance_transfer
            if manual_liquid_volume_allowance is None:
                manual_liquid_volume_allowance = self.config.dispense.manual_liquid_volume_allowance

        if is_close(volume, self.current_volume
                    ):  # avoid finicky floating-point precision issues
            volume = self.current_volume
        location = self._adjust_location_to_liquid_top(
            location=location,
            aspirate_volume=None,
            top_clearance=top_clearance,
            bottom_clearance=bottom_clearance,
            manual_liquid_volume_allowance=manual_liquid_volume_allowance)

        with DispenseParams():
            tls.dispense_params.full_dispense_from_dispense = full_dispense

            def call_super():
                super(EnhancedPipette, self).dispense(volume=volume,
                                                      location=location,
                                                      rate=rate)

            self.use_self_while(call_super)

            if tls.dispense_params.fully_dispensed:
                assert self.current_volume == 0
                if self.current_volume == 0:
                    pass  # nothing to do: the next self._position_for_aspirate will reposition for us: 'if pipette is currently empty, ensure the plunger is at "bottom"'
                else:
                    raise NotImplementedError

            # track volume
            well.liquid_volume.dispense(volume)
 def do_layer(y_layer):
     return y_layer <= y_max or is_close(y_layer, y_max)
 def test(v, scale):
     return not is_close(int(v * scale + 0.5), 0)