Exemplo n.º 1
0
    def analyte_create_object(self, resource, is_input, container_repo,
                              process_type):
        """
        Creates an Analyte from the rest resource. By default, the container
        is created from the related container resource, except if one
        already exists in the container map. This way, there will be created
        only one container object for each id
        """
        # Map UDFs (which may be using different names in different Clarity setups)
        # to a key-value list with well-defined key names:
        if resource.id in self.domain_map:
            return self.domain_map[resource.id]

        udfs = None
        if not is_input:
            # Get the process-output section, output_generation_type is either PerInput for regular analytes or
            # PerAllInputs for pools
            per_input_analytes = [
                process_output
                for process_output in process_type.process_outputs
                if process_output.artifact_type == "Analyte"
            ]
            process_output = utils.single_or_default(per_input_analytes)
            if process_output:
                udfs = UdfMapping.expand_udfs(resource, process_output)

        if udfs is None:
            udfs = resource.udf

        udf_map = UdfMapping(udfs)

        well = self.well_create_object(resource, container_repo, is_input)

        # TODO: sample should be put in a lazy property, and all samples in a step should be
        # loaded in one batch
        samples = [
            self.sample_create_object(sample) for sample in resource.samples
        ]

        is_control = False
        # TODO: This code principally belongs to the genologics layer, but
        # 'control-type' does not exist there
        if resource.root.find("control-type") is not None:
            is_control = True
        # TODO: A better way to decide if analyte is output of a previous step?
        is_from_original = (resource.id.find("2-") != 0)
        analyte = Analyte(api_resource=resource,
                          is_input=is_input,
                          id=resource.id,
                          samples=samples,
                          name=resource.name,
                          well=well,
                          is_control=is_control,
                          udf_map=udf_map,
                          is_from_original=is_from_original)
        analyte.api_resource = resource
        analyte.reagent_labels = resource.reagent_labels
        self._after_object_created(analyte, resource)
        self.domain_map[resource.id] = analyte
        return analyte
Exemplo n.º 2
0
    def result_file_create_object(self, resource, is_input, container_repo,
                                  process_type):
        """
        Creates a `ResultFile` from the REST resource object.
        The container is fetched from the container_repo.
        """
        if not is_input:
            # We expect the process_type to define one PerInput ResultFile
            process_output = utils.single([
                process_output
                for process_output in process_type.process_outputs
                if process_output.output_generation_type == "PerInput"
                and process_output.artifact_type == "ResultFile"
            ])
        udfs = UdfMapping.expand_udfs(resource, process_output)
        udf_map = UdfMapping(udfs)

        well = self.well_create_object(resource, container_repo, is_input)

        # TODO: sample should be put in a lazy property, and all samples in a step should be
        # loaded in one batch
        samples = [
            self.sample_create_object(sample) for sample in resource.samples
        ]
        ret = ResultFile(api_resource=resource,
                         is_input=is_input,
                         id=resource.id,
                         samples=samples,
                         name=resource.name,
                         well=well,
                         udf_map=udf_map)
        return ret
Exemplo n.º 3
0
    def create_from_rest_resource(resource, process_type=None):
        name = resource.name
        process_output = utils.single([
            process_output for process_output in process_type.process_outputs
            if process_output.output_generation_type == "PerAllInputs"
            and process_output.artifact_type == "ResultFile"
        ])
        udfs = UdfMapping.expand_udfs(resource, process_output)
        udf_map = UdfMapping(udfs)

        return SharedResultFile(api_resource=resource,
                                id=resource.id,
                                name=name,
                                udf_map=udf_map,
                                files=resource.files)
    def test_udf_mapping_dictionary_like(self):
        mapping = UdfMapping({"Custom #1": 10, "Custom #2": 20})

        self.assertTrue("Custom #1" in mapping)
        self.assertTrue("Custom #2" in mapping)
        self.assertTrue("udf_custom_1" in mapping)
        self.assertTrue("udf_custom_2" in mapping)
Exemplo n.º 5
0
def fake_result_file(artifact_id=None,
                     name=None,
                     container_id=None,
                     well_key=None,
                     is_input=None,
                     udfs=None,
                     **kwargs):
    """
    :param artifact_id: Artifact name
    :param name: Artifact name
    :param container_id: Container ID
    :param well_key: Location of the artifact in the container, e.g. A:1
    :param is_input: True if this is an input artifact, false if not. TODO: Does that ever make sense for result files?
    :param udfs: Mapping of UDFs as they would appear in Clarity (e.g. {"Concentration": 10})
    :param kwargs: Mapping of UDFs that use legacy names (will be refactored). Ignored if udfs is used.
    """
    container = fake_container(container_id=container_id)
    pos = ContainerPosition.create(well_key)
    well = Well(pos, container)
    api_resource = MagicMock()
    if udfs is None:
        udfs = {TEST_UDF_MAP[key]: value for key, value in kwargs.items()}
    udf_map = UdfMapping(udfs)
    ret = ResultFile(api_resource=api_resource,
                     is_input=is_input,
                     id=artifact_id,
                     samples=None,
                     udf_map=udf_map,
                     name=name,
                     well=well)

    if container:
        container.set_well(well.position, artifact=ret)
    return ret
Exemplo n.º 6
0
def fake_shared_result_file(artifact_id=None, name=None, udfs=None):
    udf_map = UdfMapping(udfs)
    api_resource = MagicMock()
    return SharedResultFile(api_resource=api_resource,
                            id=artifact_id,
                            name=name,
                            udf_map=udf_map)
Exemplo n.º 7
0
    def create_from_rest_resource(resource):
        udf_map = UdfMapping(resource.udf)

        # TODO: Move to mapper!
        from clarity_ext.service.process_service import ProcessService
        process_service = ProcessService()
        ui_link = process_service.ui_link_process(resource)
        ret = Process(resource, resource.id, resource.technician, udf_map,
                      ui_link)
        return ret
Exemplo n.º 8
0
    def create_from_rest_resource(resource, process_type=None):
        name = resource.name
        process_output = utils.single([process_output for process_output in process_type.process_outputs
                                       if process_output.output_generation_type == "PerAllInputs" and
                                       process_output.artifact_type == "ResultFile"])
        udfs = UdfMapping.expand_udfs(resource, process_output)
        udf_map = UdfMapping(udfs)

        return SharedResultFile(api_resource=resource, id=resource.id, name=name, udf_map=udf_map,
                files=resource.files)
Exemplo n.º 9
0
    def analyte_create_object(self, resource, is_input, container_repo, process_type):
        """
        Creates an Analyte from the rest resource. By default, the container
        is created from the related container resource, except if one
        already exists in the container map. This way, there will be created
        only one container object for each id
        """
        # Map UDFs (which may be using different names in different Clarity setups)
        # to a key-value list with well-defined key names:
        if resource.id in self.domain_map:
            return self.domain_map[resource.id]

        udfs = None
        if not is_input:
            # Get the process-output section, output_generation_type is either PerInput for regular analytes or
            # PerAllInputs for pools
            per_input_analytes = [process_output for process_output
                                  in process_type.process_outputs
                                  if process_output.artifact_type == "Analyte"]
            process_output = utils.single_or_default(per_input_analytes)
            if process_output:
                udfs = UdfMapping.expand_udfs(resource, process_output)

        if udfs is None:
            udfs = resource.udf

        udf_map = UdfMapping(udfs)

        well = self.well_create_object(resource, container_repo, is_input)

        # TODO: sample should be put in a lazy property, and all samples in a step should be
        # loaded in one batch
        samples = [self.sample_create_object(
            sample) for sample in resource.samples]

        is_control = False
        # TODO: This code principally belongs to the genologics layer, but
        # 'control-type' does not exist there
        if resource.root.find("control-type") is not None:
            is_control = True
        # TODO: A better way to decide if analyte is output of a previous step?
        is_from_original = (resource.id.find("2-") != 0)
        analyte = Analyte(api_resource=resource, is_input=is_input, id=resource.id,
                          samples=samples, name=resource.name,
                          well=well, is_control=is_control,
                          udf_map=udf_map,
                          is_from_original=is_from_original)
        analyte.api_resource = resource
        analyte.reagent_labels = resource.reagent_labels
        self._after_object_created(analyte, resource)
        self.domain_map[resource.id] = analyte
        return analyte
Exemplo n.º 10
0
    def test_udf_mapping(self):
        """
        Asserts that we can create a UdfMapping and use the getter
        """
        mapping = UdfMapping()

        # Add key/values to the mapping:
        mapping.add("% Total", 10)

        # We should now be able to access the field by either the original value
        # or the Python name `udf_total`
        self.assertTrue(mapping.unwrap("% Total").value, 10)
        self.assertTrue(mapping.unwrap("udf_total").value, 10)

        mapping.unwrap("% Total").value = 20
        self.assertTrue(mapping.unwrap("% Total").is_dirty())
Exemplo n.º 11
0
    def test_udf_mapping(self):
        """
        Asserts that we can create a UdfMapping and use the getter
        """
        mapping = UdfMapping()

        # Add key/values to the mapping:
        mapping.add("% Total", 10)

        # We should now be able to access the field by either the original value
        # or the Python name `udf_total`
        self.assertTrue(mapping.unwrap("% Total").value, 10)
        self.assertTrue(mapping.unwrap("udf_total").value, 10)

        mapping.unwrap("% Total").value = 20
        self.assertTrue(mapping.unwrap("% Total").is_dirty())
Exemplo n.º 12
0
def fake_analyte(container_id=None,
                 artifact_id=None,
                 sample_ids=None,
                 analyte_name=None,
                 well_key=None,
                 is_input=None,
                 is_control=False,
                 api_resource=None,
                 udfs=None,
                 **kwargs):
    """
    Creates a fake Analyte domain object

    :container_id: The ID of the Container
    :artifact_id: The ID of the Artifact
    :sample_id: The ID of the Sample
    :analyte_name: The name of the Analyte
    :well_key: The locator key for the well, e.g. "A1"
    :is_input: True if the analyte is an input analyte, False otherwise.
    :udfs: A map of udfs in the name that appears in Clarity.
    :kwargs: UDFs, where the udfs must be in the test udf mapping. Ignored if udfs is provided.
    """
    if udfs is None:
        udfs = {TEST_UDF_MAP[key]: value for key, value in kwargs.items()}
    # TODO: Always have an api_resource, remove from signature
    api_resource = MagicMock()
    api_resource.udf = udfs
    udf_map = UdfMapping(udfs)
    container = fake_container(container_id)
    pos = ContainerPosition.create(well_key)
    well = Well(pos, container)
    if not isinstance(sample_ids, list):
        sample_ids = [sample_ids]
    samples = [Sample(id, id, MagicMock()) for id in sample_ids]
    analyte = Analyte(api_resource=api_resource,
                      is_input=is_input,
                      name=analyte_name,
                      well=well,
                      is_control=is_control,
                      samples=samples,
                      udf_map=udf_map)
    analyte.id = artifact_id
    analyte.generation_type = Artifact.PER_INPUT
    well.artifact = analyte
    return analyte
Exemplo n.º 13
0
    def result_file_create_object(self, resource, is_input, container_repo, process_type):
        """
        Creates a `ResultFile` from the REST resource object.
        The container is fetched from the container_repo.
        """
        if not is_input:
            # We expect the process_type to define one PerInput ResultFile
            process_output = utils.single([process_output for process_output in process_type.process_outputs
                                           if process_output.output_generation_type == "PerInput" and
                                           process_output.artifact_type == "ResultFile"])
        udfs = UdfMapping.expand_udfs(resource, process_output)
        udf_map = UdfMapping(udfs)

        well = self.well_create_object(resource, container_repo, is_input)

        # TODO: sample should be put in a lazy property, and all samples in a step should be
        # loaded in one batch
        samples = [self.sample_create_object(
            sample) for sample in resource.samples]
        ret = ResultFile(api_resource=resource, is_input=is_input,
                         id=resource.id, samples=samples, name=resource.name, well=well,
                         udf_map=udf_map)
        return ret
Exemplo n.º 14
0
 def sample_create_object(self, resource):
     project = Project(resource.project.name) if resource.project else None
     udf_map = UdfMapping(resource.udf)
     sample = Sample(resource.id, resource.name, project, udf_map)
     self._after_object_created(sample, resource)
     return sample
Exemplo n.º 15
0
 def _get_unique_udf_mapping():
     original = {"% Total": 10, "Conc.": 0.5}
     return UdfMapping(original)
Exemplo n.º 16
0
 def _get_non_unique_udf_mapping():
     original = {"% Total": 10, "# Total": 20}
     return UdfMapping(original)