async def _get_model_by_id_or_alias(model_id, token):
    try:
        model_id = UUID(model_id)
        model_project = ModelProject.from_uuid(str(model_id), kg_client, api="nexus")
    except ValueError:
        model_alias = str(model_id)
        model_project = ModelProject.from_alias(model_alias, kg_client, api="nexus")
    if not model_project:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Model with ID or alias '{model_id}' not found.",
        )
    # todo: fairgraph should accept UUID object as well as str
    await _check_model_access(model_project, token)
    return model_project
Ejemplo n.º 2
0
 def test_list_kgquery(self, kg_client):
     models = ModelProject.list(kg_client,
                                api="query",
                                scope="latest",
                                size=10,
                                resolved=True)
     assert len(models) == 10
Ejemplo n.º 3
0
def check_if_alias_is_already_taken(name):

    print('comparing with KG database [...]')
    client = KGClient(token,
                      nexus_endpoint="https://nexus.humanbrainproject.org/v0")
    MODELS = ModelProject.list(client, size=10000)
    NAMES = [project.name for project in MODELS]
    if name in NAMES:
        i0 = int(np.argwhere(np.array(NAMES, dtype=str) == name))
        if type(MODELS[i0].authors) is list:
            author_list = ''
            for nn in list(MODELS[i0].authors):
                author_list += nn.resolve(client).full_name + '; '
        else:
            author_list = MODELS[i0].authors.resolve(client).full_name
        print('/!\ --> The alias "%s"' % name,
              'is redundant with the following entry:')
        print(''' 
- Description:
        %s
- Author(s):
        %s
        ''' % (MODELS[i0].resolve(client).description[:200]+'  [...]  '+\
               MODELS[i0].resolve(client).description[-200:],
               author_list))
    else:
        print('--> The alias "%s"' % name, 'is valid')
Ejemplo n.º 4
0
 def test_list_kgquery_with_filter(self, kg_client):
     models = ModelProject.list(kg_client,
                                api="query",
                                scope="latest",
                                size=10,
                                resolved=True,
                                species="Rattus norvegicus")
     assert len(models) == 2
Ejemplo n.º 5
0
async def update_model(
        model_id: UUID,
        model_patch: ScientificModelPatch,
        token: HTTPAuthorizationCredentials = Depends(auth),
):
    # if payload contains a project_id, check permissions for that id
    if model_patch.project_id and not (await is_collab_member(
            model_patch.project_id, token.credentials)
                                       or await is_admin(token.credentials)):
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail=
            f"This account is not a member of Collab #{model_patch.project_id}",
        )
    # retrieve stored model
    model_project = ModelProject.from_uuid(str(model_id),
                                           kg_client,
                                           api="nexus")
    stored_model = ScientificModel.from_kg_object(model_project, kg_client)
    # if retrieved project_id is different to payload id, check permissions for that id
    if stored_model.project_id != model_patch.project_id and not (
            await is_collab_member(stored_model.project_id, token.credentials)
            or await is_admin(token.credentials)):
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail=
            f"Access to this model is restricted to members of Collab #{stored_model.project_id}",
        )
    # if alias changed, check uniqueness of new alias
    if (model_patch.alias and model_patch.alias != stored_model.alias
            and model_alias_exists(model_patch.alias, kg_client)):
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail=
            f"Another model with alias '{model_patch.alias}' already exists.",
        )
    # todo: if model id provided in payload, check it matches the model_id parameter
    # todo: if model uri provided in payload, check it matches the id

    # here we are updating the pydantic model `stored_model`, then recreating the kg objects
    # from this. It might be more efficient to directly update `model_project`.
    # todo: profile both possible implementations
    update_data = model_patch.dict(exclude_unset=True)
    for field, value in update_data.items():
        if field in ("author", "owner"):
            update_data[field] = [Person(**p) for p in update_data[field]]
    updated_model = stored_model.copy(update=update_data)
    kg_objects = updated_model.to_kg_objects()
    for obj in kg_objects:
        obj.save(kg_client)
    model_project = kg_objects[-1]
    assert isinstance(model_project, ModelProject)
    return ScientificModel.from_kg_object(model_project, kg_client)
Ejemplo n.º 6
0
 def test_existence_query(self, kg_client):
     obj = ModelProject(name="foo",
                        owners=Person("Holmes", "Sherlock"),
                        authors=Person("Holmes", "Sherlock"),
                        description="",
                        private=True,
                        date_created=datetime(2000, 1, 1))
     expected = {
         "op":
         "and",
         "value": [{
             "path": "schema:name",
             "op": "eq",
             "value": "foo"
         }, {
             "path": "schema:dateCreated",
             "op": "eq",
             "value": "2000-01-01T00:00:00"
         }]
     }
     generated = obj._build_existence_query(api="nexus")
     assert expected == generated
def _are_model_instance_version_unique_kg(instance_json, kg_client):
    """
    Check if versions of model instance are unique
    :param instance_json: datas of instance
    :type instance_json: dict
    :returns: response
    :rtype: boolean
    """
    new_version_name = instance_json['version']
    model_project = ModelProject.from_uuid(instance_json['model_id'], kg_client)
    if model_project.instances:
        all_instances_versions_name = [inst.resolve(kg_client).version for inst in as_list(model_project.instances)]
        if new_version_name in all_instances_versions_name:
            return False
    return True
Ejemplo n.º 8
0
async def delete_model_instance(
    model_id: UUID,
    model_instance_id: UUID,
    token: HTTPAuthorizationCredentials = Depends(auth)):
    # todo: handle non-existent UUID
    model_project = ModelProject.from_uuid(str(model_id),
                                           kg_client,
                                           api="nexus")
    if not (await is_collab_member(model_project.collab_id, token.credentials)
            or await is_admin(token.credentials)):
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail=
            f"Access to this model is restricted to members of Collab #{model_project.collab_id}",
        )
    await _delete_model_instance(model_instance_id, model_project)
Ejemplo n.º 9
0
async def delete_model(model_id: UUID,
                       token: HTTPAuthorizationCredentials = Depends(auth)):
    # todo: handle non-existent UUID
    model_project = ModelProject.from_uuid(str(model_id),
                                           kg_client,
                                           api="nexus")
    if not (await is_collab_member(model_project.collab_id, token.credentials)
            or await is_admin(token.credentials)):
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail=
            f"Access to this model is restricted to members of Collab #{model_project.collab_id}",
        )
    model_project.delete(kg_client)
    for model_instance in as_list(model_project.instances):
        # todo: we should possibly also delete emodels, modelscripts, morphologies,
        # but need to check they're not shared with other instances
        model_instance.delete(kg_client)
 def is_valid(self):
     # check alias is unique
     if "alias" in self.data and self.data["alias"]:
         if self.obj and self.obj.alias == self.data["alias"]:
             return True
         logger.debug("Checking for model with same alias")
         model_with_same_alias = ModelProject.from_alias(
             self.data["alias"], self.client)
         if bool(model_with_same_alias):
             self.errors.append(
                 "Another model with this alias already exists.")
             return False
     if "private" in self.data:
         if not isinstance(self.data["private"], bool):
             self.errors.append("'private' must be a boolean")
             return False
     if "author" not in self.data or not self.data["author"]:
         self.errors.append("This field may not be blank.")
         return False
     return True  # todo
    def save(self):
        # todo: Create/update EModel, MEModel and Morphology where model_scope is "single cell"
        if self.obj is None:  # create
            model_project = ModelProject.from_uuid(self.data["model_id"],
                                                   self.client,
                                                   api="nexus")
            script = ModelScript(name="ModelScript for {} @ {}".format(
                model_project.name, self.data["version"]),
                                 code_format=self.data.get("code_format"),
                                 code_location=self.data["source"],
                                 license=self.data.get("license"))
            script.save(self.client)

            if model_project.model_of and model_project.model_of.label == "single cell" and "morphology" in self.data:
                e_model = EModel(name="EModel for {} @ {}".format(
                    model_project.name, self.data["version"]),
                                 brain_region=model_project.brain_region,
                                 species=model_project.species,
                                 model_of=None,
                                 main_script=None,
                                 release=None)
                e_model.save(self.client)
                morph = Morphology(name="Morphology for {} @ {}".format(
                    model_project.name, self.data["version"]),
                                   cell_type=model_project.celltype,
                                   morphology_file=self.data["morphology"])
                morph.save(self.client)
                minst = MEModel(name="ModelInstance for {} @ {}".format(
                    model_project.name, self.data["version"]),
                                description=self.data.get("description", ""),
                                brain_region=model_project.brain_region,
                                species=model_project.species,
                                model_of=None,
                                main_script=script,
                                e_model=e_model,
                                morphology=morph,
                                version=self.data["version"],
                                parameters=self.data.get("parameters"),
                                timestamp=datetime.now(),
                                release=None)
            else:
                minst = ModelInstance(name="ModelInstance for {} @ {}".format(
                    model_project.name, self.data["version"]),
                                      description=self.data.get(
                                          "description", ""),
                                      brain_region=model_project.brain_region,
                                      species=model_project.species,
                                      model_of=None,
                                      main_script=script,
                                      version=self.data["version"],
                                      parameters=self.data.get("parameters"),
                                      timestamp=datetime.now(),
                                      release=None)
            minst.save(self.client)
            self.obj = minst

            if model_project.instances:
                if not isinstance(model_project.instances, list):
                    model_project.instances = [model_project.instances]
                model_project.instances.append(minst)
            else:
                model_project.instances = [minst]
            model_project.save(self.client)

        else:  # update
            instance_changed = False
            script_changed = False
            morphology_changed = False

            def resolve_obj(obj):
                if isinstance(obj, KGProxy):
                    return obj.resolve(self.client, api="nexus")
                else:
                    return obj

            if "name" in self.data:
                self.obj.name = self.data["name"]
                # todo: also update e_model and morphology
                instance_changed = True
            if "description" in self.data:
                self.obj.description = self.data.get("description", "")
                instance_changed = True
            if "version" in self.data:
                self.obj.version = self.data["version"]
                instance_changed = True
            if "parameters" in self.data:
                self.obj.parameters = self.data.get("parameters")
                instance_changed = True
            if "code_format" in self.data:
                self.obj.main_script = resolve_obj(self.obj.main_script)
                self.obj.main_script.code_format = self.data.get("code_format")
                script_changed = True
            if "source" in self.data:
                self.obj.main_script = resolve_obj(self.obj.main_script)
                self.obj.main_script.code_location = self.data["source"]
                script_changed = True
            if "license" in self.data:
                self.obj.main_script = resolve_obj(self.obj.main_script)
                self.obj.main_script.license = self.data.get("license")
                script_changed = True
            if "morphology" in self.data and self.data[
                    "morphology"] is not None:
                self.obj.morphology = resolve_obj(self.obj.morphology)
                self.obj.morphology.morphology_file = self.data["morphology"]
                morphology_changed = True
            logger.debug("Morphology changed: {}".format(morphology_changed))
            logger.debug("Script changed: {}".format(script_changed))
            logger.debug("Instance changed: {}".format(instance_changed))
            if morphology_changed:
                self.obj.morphology.save(self.client)
            if script_changed:
                self.obj.main_script.save(self.client)
            if instance_changed:
                self.obj.save(self.client)

        return self.obj
Ejemplo n.º 12
0
 def test_list_nexus_with_filter(self, kg_client):
     models = ModelProject.list(kg_client,
                                api="nexus",
                                size=10,
                                species="Rattus norvegicus")
     assert len(models) == 6
Ejemplo n.º 13
0
 def test_count_kgquery(self, kg_client):
     count = ModelProject.count(kg_client, api='query')
     assert count == 351
Ejemplo n.º 14
0
 def test_count_nexus(self, kg_client):
     count = ModelProject.count(kg_client, api='nexus')
     assert count == 351
def model_alias_exists(alias, client):
    if alias:
        model_with_same_alias = ModelProject.from_alias(alias, client, api="nexus")
        return bool(model_with_same_alias)
    return False
class ScientificModelKGSerializer(BaseKGSerializer):
    def is_valid(self):
        # check alias is unique
        if "alias" in self.data and self.data["alias"]:
            if self.obj and self.obj.alias == self.data["alias"]:
                return True
            logger.debug("Checking for model with same alias")
            model_with_same_alias = ModelProject.from_alias(self.data["alias"],
                                                            self.client,
                                                            api="nexus")
            if bool(model_with_same_alias):
                self.errors.append(
                    "Another model with this alias already exists.")
                return False
        if "private" in self.data:
            if not isinstance(self.data["private"], bool):
                self.errors.append("'private' must be a boolean")
                return False
        if "author" not in self.data or not self.data["author"]:
            self.errors.append("This field may not be blank.")
            return False
        return True  # todo

    def save(self, allow_update=True):
        if self.obj is None:  # create
            for key in ("author", "owner"):
                if isinstance(self.data[key], dict):
                    self.data[key] = [self.data[key]]
            self.obj = ModelProject(
                self.data["name"],
                [
                    Person(p["family_name"], p["given_name"],
                           p.get("email", None))
                    for p in as_list(self.data["owner"])
                ],
                [
                    Person(p["family_name"], p["given_name"],
                           p.get("email", None))
                    for p in as_list(self.data["author"])
                ],  # need to update person representation in clients,
                self.data.get("description"),
                datetime.now(),
                self.data.get("private", True),
                self.context["collab_id"],
                self.data.get("alias"),
                Organization(self.data["organization"]) if self.data.get(
                    "organization", False) else None,
                pla_components=None,
                brain_region=self._get_ontology_obj(BrainRegion,
                                                    "brain_region"),
                species=self._get_ontology_obj(Species, "species"),
                celltype=self._get_ontology_obj(CellType, "cell_type"),
                abstraction_level=self._get_ontology_obj(
                    AbstractionLevel, "abstraction_level"),
                model_of=self._get_ontology_obj(ModelScope, "model_scope"),
                old_uuid=self.data.get("old_uuid"),
                images=self.data.get("images"))
        else:  # update
            if "name" in self.data:
                self.obj.name = self.data["name"]
            if "alias" in self.data:
                self.obj.alias = self.data["alias"]
            if "author" in self.data:
                self.obj.authors = [
                    Person(p["family_name"], p["given_name"],
                           p.get("email", None))
                    for p in as_list(self.data["author"])
                ]  # need to update person representation in clients
            if "owner" in self.data:
                self.obj.owners = [
                    Person(p["family_name"], p["given_name"],
                           p.get("email", None))
                    for p in as_list(self.data["owner"])
                ]  # need to update person representation in clients
            if "app" in self.data:
                self.obj.collab_id = self.data["app"]["collab_id"]
            if "organization" in self.data and self.data[
                    "organization"] is not None:
                self.obj.organization = Organization(self.data["organization"])
            if "private" in self.data:
                self.obj.private = self.data["private"]
            if "cell_type" in self.data:
                self.obj.celltype = self._get_ontology_obj(
                    CellType, "cell_type")
            if "model_scope" in self.data:
                self.obj.model_of = self._get_ontology_obj(
                    ModelScope, "model_scope")
            if "abstraction_level" in self.data:
                self.obj.abstraction_level = self._get_ontology_obj(
                    AbstractionLevel, "abstraction_level")
            if "brain_region" in self.data:
                self.obj.brain_region = self._get_ontology_obj(
                    BrainRegion, "brain_region")
            if "species" in self.data:
                self.obj.species = self._get_ontology_obj(Species, "species")
            if "description" in self.data:
                self.obj.description = self.data["description"]
            if "old_uuid" in self.data:
                self.obj.old_uuid = self.data["old_uuid"]
            if "images" in self.data:
                self.obj.images = self.data["images"]

        # now save people, organization, model. No easy way to make this atomic, I don't think.
        for person in chain(as_list(self.obj.authors),
                            as_list(self.obj.owners)):
            if not isinstance(person, KGProxy):
                # no need to save if we have a proxy object, as
                # that means the person hasn't been updated
                person.save(self.client)
        if self.obj.organization and not isinstance(self.obj.organization,
                                                    KGProxy):
            self.obj.organization.save(self.client)
        self.obj.save(self.client)
        return self.obj

    def serialize(self, model):
        # todo: rewrite all this using KG Query API, to avoid doing all the individual resolves.
        def serialize_person(p):
            if isinstance(p, KGProxy):
                pr = p.resolve(self.client, api="nexus")
            else:
                pr = p
            return {"given_name": pr.given_name, "family_name": pr.family_name}

        data = {
            'id':
            model.uuid,  # extract uuid from uri?
            'uri':
            model.id,
            'name':
            model.name,
            'alias':
            model.alias,
            'author': [serialize_person(au) for au in as_list(model.authors)],
            'owner': [serialize_person(ow) for ow in as_list(model.owners)],
            'app': {
                'collab_id': model.collab_id
            },
            'organization':
            model.organization.resolve(self.client, api="nexus").name
            if model.organization else None,
            'private':
            model.private,
            'cell_type':
            model.celltype.label if model.celltype else None,
            'model_scope':
            model.model_of.label if model.model_of else None,
            'abstraction_level':
            model.abstraction_level.label if model.abstraction_level else None,
            'brain_region':
            model.brain_region.label if model.brain_region else None,
            'species':
            model.species.label if model.species else None,
            'description':
            model.description,
            'images':
            model.images,
            'old_uuid':
            model.old_uuid,
            'instances': [],
            #"raw_data": model.instance.data
        }
        for instance in as_list(model.instances):
            instance = instance.resolve(self.client, api="nexus")
            if not instance:  # if we have a stale reference to a deprecated instance
                continue
            main_script = instance.main_script.resolve(self.client,
                                                       api="nexus")
            instance_data = {
                "id":
                instance.uuid,
                "uri":
                instance.id,
                #"old_uuid": instance.old_uuid
                "version":
                instance.version,
                "description":
                instance.description or '',
                "parameters":
                instance.parameters or '',
                "code_format":
                '',
                "source":
                '',
                "license":
                '',
                "hash":
                '',
                "timestamp":
                instance.timestamp.isoformat() if instance.timestamp else None
            }
            if main_script:
                instance_data.update({
                    "code_format": main_script.code_format or '',
                    "source": main_script.code_location or '',
                    "license": main_script.license or '',
                })
            if hasattr(instance, "morphology"):
                morph = instance.morphology.resolve(self.client, api="nexus")
                instance_data["morphology"] = morph.morphology_file
            data['instances'].append(instance_data)
        return data
Ejemplo n.º 17
0
def load_model_instances(show_ignore=False,
                         size=100000,
                         scope='inferred',
                         verbose=False,
                         api='nexus'):

    client = KGClient(os.environ["HBP_token"])
    
    MODEL_INSTANCES = []

    models = ModelProject.list(client,
                               api=api,
                               scope=scope,
                               size=size)
        
    for model in models:

        if verbose:
            print('\n##########################################')
            print('------ %s ------' % model.name)
        minst = template.copy()
        minst['name'] = model.name

        minst['owner'] = get_author_details(model.owners.resolve(client))
        if type(model.authors) is list:
            minst['author(s)'] = [get_author_details(auth.resolve(client)) for auth in model.authors]
        else:
            minst['author(s)'] = [get_author_details(model.authors.resolve(client))]

        try:
            minst['authors_str'] = model.authors_str(client)
        except TypeError:
            minst['authors_str'] = ''
            for a in minst['author(s)']:
                minst['authors_str'] += a['family_name']+', '+a['given_name']+';' 

        minst['description'] = model.description
        minst['private'] = model.private
        minst['collab_id'] = model.collab_id
        minst['alias'] = model.alias

        for key, quant in zip(['brain_region', 'species', 'cell_type', 'abstraction_level', 'model_scope'],
                              [model.brain_region, model.species, model.celltype, model.abstraction_level, model.model_of]):
            if quant is not None:
                minst[key] = (quant.label, '')
            elif verbose:
                print('[!!] "%s" missing for %s ' % (key, model.name))
        for key, quant in zip(['organization'],
                              [model.organization]):
            if quant is not None:
                minst[key] = (quant.resolve(client).name, '')
            elif verbose:
                print('[!!] "%s" missing for %s ' % (key, model.name))

        if type(model.instances) is list:
            for modelI in model.instances:
                MODEL_INSTANCES.append(minst)
                # pprint.pprint(MODEL_INSTANCES[-1])
                # print('')
                add_version_details_to_model(MODEL_INSTANCES[-1], modelI.resolve(client), client, verbose=verbose)
        elif type(model.instances) is KGProxy:
            modelI = model.instances
            MODEL_INSTANCES.append(minst.copy())
            add_version_details_to_model(MODEL_INSTANCES[-1], modelI.resolve(client), client, verbose=verbose)
        elif show_ignore:
            print('Ignoring %s @ %s' % (model.name, model.date_created))
            pass # we don't care about models without specific version

        
    DATES = np.array([time.mktime(minst['date_created'].timetuple()) for minst in MODEL_INSTANCES])

    return [MODEL_INSTANCES[i] for i in np.argsort(DATES)[::-1]]
Ejemplo n.º 18
0
async def query_models(
        alias: List[str] = Query(
            None,
            description="A list of model aliases (short names) to search for"),
        id: List[UUID] = Query(
            None, description="A list of specific model IDs to search for"),
        name: List[str] = Query(None,
                                description="Model name(s) to search for"),
        brain_region: List[BrainRegion] = Query(
            None,
            description=
            "Find models intended to represent this/these brain region(s)"),
        species: List[Species] = Query(
            None,
            description="Find models intended to represent this/these species"
        ),
        cell_type: List[CellType] = Query(
            None, description="Find models of this/these cell type(s)"),
        model_scope: ModelScope = Query(
            None, description="Find models with a certain scope"),
        abstraction_level: AbstractionLevel = Query(
            None, description="Find models with a certain abstraction level"),
        author: List[str] = Query(
            None, description="Find models by author (family name)"),
        owner: List[str] = Query(
            None, description="Find models by owner (family name)"),
        organization: List[str] = Query(
            None, description="Find models by organization"),
        project_id: List[str] = Query(
            None,
            description="Find models belonging to a specific project/projects"
        ),
        private: bool = Query(
            None, description="Limit the search to public or private models"),
        summary: bool = Query(
            False,
            description="Return only summary information about each model"),
        size: int = Query(100, description="Maximum number of responses"),
        from_index: int = Query(
            0, description="Index of the first response returned"),
        # from header
        token: HTTPAuthorizationCredentials = Depends(auth),
):
    """
    Search the model catalog for specific models (identitified by their unique ID or by a short name / alias),
    and/or search by attributes of the models (e.g. the cell types being modelled, the type of model, the model author).
    """

    # If project_id is provided:
    #     - private = None: both public and private models from that project (collab), if the user is a member
    #     - private = True: only private models from that project, if that user is a member
    #     - private = False: only public models from that project
    # If project_id is not provided:
    #     - private = None: only public models, from all projects
    #     - private = True: 400? error "To see private models, you must specify the project/collab"
    #     - private = False: only public models, from all projects

    if private:
        if project_id:
            for collab_id in project_id:
                if not await is_collab_member(collab_id, token.credentials):
                    raise HTTPException(
                        status_code=status.HTTP_403_FORBIDDEN,
                        detail="You are not a member of project #{collab_id}",
                    )
        else:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=
                "To see private models, you must specify the project/collab id",
            )

    # get the values of of the Enums
    if brain_region:
        brain_region = [item.value for item in brain_region]
    if species:
        species = [item.value for item in species]
    if cell_type:
        cell_type = [item.value for item in cell_type]
    if model_scope:
        model_scope = model_scope.value
    if abstraction_level:
        abstraction_level = abstraction_level.value

    filter_query, context = build_model_project_filters(
        alias,
        id,
        name,
        brain_region,
        species,
        cell_type,
        model_scope,
        abstraction_level,
        author,
        owner,
        organization,
        project_id,
        private,
    )
    if len(filter_query["value"]) > 0:
        logger.info(
            "Searching for ModelProject with the following query: {}".format(
                filter_query))
        # note that from_index is not currently supported by KGQuery.resolve
        model_projects = KGQuery(ModelProject, {
            "nexus": filter_query
        }, context).resolve(kg_client, api="nexus", size=size)
    else:
        model_projects = ModelProject.list(kg_client,
                                           api="nexus",
                                           size=size,
                                           from_index=from_index)
    if summary:
        cls = ScientificModelSummary
    else:
        cls = ScientificModel
    return [
        cls.from_kg_object(model_project, kg_client)
        for model_project in as_list(model_projects)
    ]
    def save(self, allow_update=True):
        if self.obj is None:  # create
            for key in ("author", "owner"):
                if isinstance(self.data[key], dict):
                    self.data[key] = [self.data[key]]
            self.obj = ModelProject(
                self.data["name"],
                [
                    Person(p["family_name"], p["given_name"],
                           p.get("email", None))
                    for p in as_list(self.data["owner"])
                ],
                [
                    Person(p["family_name"], p["given_name"],
                           p.get("email", None))
                    for p in as_list(self.data["author"])
                ],  # need to update person representation in clients,
                self.data.get("description"),
                datetime.now(),
                self.data.get("private", True),
                self.context["collab_id"],
                self.data.get("alias"),
                Organization(self.data["organization"]) if self.data.get(
                    "organization", False) else None,
                pla_components=None,
                brain_region=self._get_ontology_obj(BrainRegion,
                                                    "brain_region"),
                species=self._get_ontology_obj(Species, "species"),
                celltype=self._get_ontology_obj(CellType, "cell_type"),
                abstraction_level=self._get_ontology_obj(
                    AbstractionLevel, "abstraction_level"),
                model_of=self._get_ontology_obj(ModelScope, "model_scope"),
                old_uuid=self.data.get("old_uuid"),
                images=self.data.get("images"))
        else:  # update
            if "name" in self.data:
                self.obj.name = self.data["name"]
            if "alias" in self.data:
                self.obj.alias = self.data["alias"]
            if "author" in self.data:
                self.obj.authors = [
                    Person(p["family_name"], p["given_name"],
                           p.get("email", None))
                    for p in as_list(self.data["author"])
                ]  # need to update person representation in clients
            if "owner" in self.data:
                self.obj.owners = [
                    Person(p["family_name"], p["given_name"],
                           p.get("email", None))
                    for p in as_list(self.data["owner"])
                ]  # need to update person representation in clients
            if "app" in self.data:
                self.obj.collab_id = self.data["app"]["collab_id"]
            if "organization" in self.data and self.data[
                    "organization"] is not None:
                self.obj.organization = Organization(self.data["organization"])
            if "private" in self.data:
                self.obj.private = self.data["private"]
            if "cell_type" in self.data:
                self.obj.celltype = self._get_ontology_obj(
                    CellType, "cell_type")
            if "model_scope" in self.data:
                self.obj.model_of = self._get_ontology_obj(
                    ModelScope, "model_scope")
            if "abstraction_level" in self.data:
                self.obj.abstraction_level = self._get_ontology_obj(
                    AbstractionLevel, "abstraction_level")
            if "brain_region" in self.data:
                self.obj.brain_region = self._get_ontology_obj(
                    BrainRegion, "brain_region")
            if "species" in self.data:
                self.obj.species = self._get_ontology_obj(Species, "species")
            if "description" in self.data:
                self.obj.description = self.data["description"]
            if "old_uuid" in self.data:
                self.obj.old_uuid = self.data["old_uuid"]
            if "images" in self.data:
                self.obj.images = self.data["images"]

        # now save people, organization, model. No easy way to make this atomic, I don't think.
        for person in chain(as_list(self.obj.authors),
                            as_list(self.obj.owners)):
            if not isinstance(person, KGProxy):
                # no need to save if we have a proxy object, as
                # that means the person hasn't been updated
                person.save(self.client)
        if self.obj.organization and not isinstance(self.obj.organization,
                                                    KGProxy):
            self.obj.organization.save(self.client)
        self.obj.save(self.client)
        return self.obj
Ejemplo n.º 20
0
        assert len(name) > 6

        bundle = FileBundle(identifier=hashlib.md5(script.code_location.encode('utf-8')).hexdigest(),
                            name=name,
                            description=model_instance.description,
                            url=script.code_location,
                            #usageNotes,
                            modelInstance=model_release)  # check this is showing in KG editor
        print(bundle)
        bundle.save(client)


if __name__ == "__main__":
    client = KGClient(token, nexus_endpoint="https://nexus.humanbrainproject.org/v0")

    projects = ModelProject.list(client, size=10000)
    single_cell_projects = [p for p in projects if p.model_of and p.model_of.label == "single cell" and "emodel" not in p.name]
    single_cell_no_memodel = [p for p in single_cell_projects if "CA1_pyr" not in p.name and "CA1_int" not in p.name]

    #for model_project in ModelProject.list(client, size=10000):
    for model_project in single_cell_no_memodel:
        #if model_project.model_of and "network" in model_project.model_of.label:
        #if model_project.model_of and "single cell" not in model_project.model_of.label:
        if True:
            contributors = get_uniminds_person_list(model_project.authors, client)
            custodians = get_uniminds_person_list(model_project.owners, client)

            for model_instance in as_list(model_project.instances):
                model_instance = model_instance.resolve(client)
                script = model_instance.main_script.resolve(client)
                release = create_or_update_model_release(model_project, model_instance, contributors, custodians, script, client)
    def migrate_models(self):

        models = ScientificModel.objects.all()

        for model in models:
            authors = self._get_people_from_Persons_table(model.author)
            for author in authors:
                author.save(NAR_client)
            owners = self._get_people_from_Persons_table(model.owner)
            for owner in owners:
                owner.save(NAR_client)
            if len(owners) == 0:
                owners = authors[-1:]
            if len(owners) > 1:
                owners = owners[
                    0]  # temporary, need to fix schema to remove maxCount: 1
            organization = self.get_organization(model.organization)
            brain_region = self.get_parameters("brain_region",
                                               model.brain_region)
            species = self.get_parameters("species", model.species)
            cell_type = self.get_parameters("cell_type", model.cell_type)
            abstraction_level = self.get_parameters("abstraction_level",
                                                    model.abstraction_level)
            model_scope = self.get_parameters("model_scope", model.model_scope)

            model_project = ModelProject(
                name=model.name,
                owners=owners,
                authors=authors,
                description=model.description,
                date_created=model.creation_date,
                private=model.private,
                collab_id=model.app.collab_id,
                alias=model.alias,
                organization=organization,
                pla_components=model.pla_components,
                brain_region=brain_region,
                species=species,
                celltype=cell_type,
                abstraction_level=abstraction_level,
                model_of=model_scope,  # to fix
                images=[{
                    "url": im.url,
                    "caption": im.caption
                } for im in model.images.all()],
                old_uuid=str(model.id))

            #print ("--authors",model_project.authors)
            #print ("--organization",model_project.organization)
            #print ("--brain_region",model_project.brain_region)
            #print ("--species",model_project.species)

            try:
                model_project.save(NAR_client)
            except Exception as err:
                if "internal server error" in err.response.text:
                    logger.error(err)
                else:
                    raise
            else:
                logger.info("ModelProject saved: %s", model_project)
                print(model_project)

        # models_with_parents = ScientificModel.objects.filter(parents__isnull=False)
        # for model in models_with_parents:
        #     mp = ModelProject.by_name(model.name, NAR_client)
        #     for parent_obj in model.parents.all():
        #         parent_kg = ModelProject.by_name(parent_obj.name, NAR_client)
        #         mp.parents = as_list(mp.parents) + [parent_kg]
        #     mp.save(NAR_client)
        return ''
Ejemplo n.º 22
0
def test_all():
    ModelProject.set_strict_mode(False)  # check: will this interfere with other tests?
    MEModel.set_strict_mode(False)

    ## Get a list of possible filter terms

    for cls in (Species, CellType, BrainRegion, AbstractionLevel, ModelScope):
        print("\nPossible values of {}:\n  - ".format(cls.__name__))
        print("\n  - ".join(cls.iri_map.keys()))

    ## Find models of hippocampus pyramidal neurons

    models = ModelProject.list(client,
                            brain_region="hippocampus",
                            model_of="single cell",
                            species="Rattus norvegicus")
    len(models)
    columns = ("name", "brain_region", "celltype", "authors")

    data = []
    for model in models:
        row = {}
        for attr in columns:
            value = getattr(model, attr)
            if hasattr(value, "label"):
                row[attr] = value.label
            elif attr == "authors":
                row[attr] = ", ".join("{au.given_name} {au.family_name}".format(au=obj.resolve(client))
                                    for obj in as_list(value))
            else:
                row[attr] = value
        data.append(row)

    df = pd.DataFrame(data=data, columns=columns)  #.sort_values(by=['name'], kind="mergesort")
    dfStyler = df.style.set_properties(**{'text-align': 'left'})
    dfStyler.set_table_styles([dict(selector='th', props=[('text-align', 'left')])])


    # Exploring a single model

    # take the last model from the list above, and show its versions
    example_model = models[-1]
    example_model.instances

    # take the last version (not necessarily the most recent)
    instance = as_list(example_model.instances)[-1].resolve(client)
    instance
    instance.timestamp.isoformat()

    code = instance.main_script.resolve(client)
    code.code_format
    code.code_location

    morph = instance.morphology.resolve(client)
    morph.morphology_file

    def print_model_information(index):
        model = models[index]
        instance = as_list(model.instances)[-1].resolve(client)
        code = instance.main_script.resolve(client)
        morph = instance.morphology.resolve(client)
        print(instance.name, instance.timestamp.isoformat())
        print(code.code_location)
        print(morph.morphology_file)

    print_model_information(99)

    # not all models have morphologies, I'm not sure if this is expected or not.
    # Here is a list of models with morphologies
    for model in models:
        for instance in as_list(model.instances):
            instance = instance.resolve(client)
            morph_file = instance.morphology.resolve(client).morphology_file
            if morph_file:
                print(instance.name, morph_file)