Пример #1
0
        def connected(start):
            log.debug(start)
            blob = data_sgd.neurons_connectivity(start)#, limit=9999)
            edges = blob['edges']
            neurons = {}
            types = {}
            rows = []
            start_type = None
            sc = OntId(start).curie
            for e in edges:
                s, p, o = e['sub'], e['pred'], e['obj']
                if p == 'operand':
                    continue

                if s.startswith('_:'):
                    if s not in neurons:
                        neurons[s] = []
                        types[s] = {}
                otp = OntTerm(p)
                oto = OntTerm(o)
                neurons[s].append((otp, oto))
                if o == sc:
                    start_type = otp

                if oto not in types[s]:
                    types[s][oto] = []

                types[s][oto].append(otp)

            for v in neurons.values():
                v.sort()

            return OntTerm(start), start_type, neurons, types
Пример #2
0
    def route_dynamic(path):
        args = dict(request.args)
        if 'direction' in args:
            direction = args.pop('direction')
        else:
            direction = 'OUTGOING'  # should always be outgoing here since we can't specify?

        if 'format' in args:
            format_ = args.pop('format')
        else:
            format_ = None

        try:
            j = sgd.dispatch(path, **args)
        except rHTTPError as e:
            log.exception(e)
            abort(e.response.status_code)  # DO NOT PASS ALONG THE MESSAGE
        except ValueError as e:
            log.exception(e)
            abort(404)

        if j is None or 'edges' not in j or not j['edges']:
            log.error(pformat(j))
            log.debug(sgd._last_url)
            return abort(400)

        prov = [
            hfn.titletag(f'Dynamic query result for {path}'),
            f'<meta name="date" content="{UTCNOWISO()}">',
            f'<link rel="http://www.w3.org/ns/prov#wasGeneratedBy" href="{wgb}">',
            '<meta name="representation" content="SciGraph">',
            f'<link rel="http://www.w3.org/ns/prov#wasDerivedFrom" href="{sgd._last_url}">'
        ]

        kwargs = {'json': cleanBad(j), 'html_head': prov}
        tree, extras = creatTree(*Query(None, None, direction, None), **kwargs)
        #print(extras.hierarhcy)
        #print(tree)
        if format_ is not None:
            if format_ == 'table':
                #breakpoint()
                def nowrap(class_, tag=''):
                    return (f'{tag}.{class_}' '{ white-space: nowrap; }')

                ots = [
                    OntTerm(n) for n in flatten_tree(extras.hierarchy)
                    if 'CYCLE' not in n
                ]
                #rows = [[ot.label, ot.asId().atag(), ot.definition] for ot in ots]
                rows = [[ot.label,
                         hfn.atag(ot.iri, ot.curie), ot.definition]
                        for ot in ots]

                return hfn.htmldoc(hfn.render_table(rows, 'label', 'curie',
                                                    'definition'),
                                   styles=(hfn.table_style,
                                           nowrap('col-label', 'td')))

        return hfn.htmldoc(extras.html, other=prov, styles=hfn.tree_styles)
Пример #3
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # PLEASE DO NOT PUT PMIDs as external ids!!!
        # FIXME idlib PMID(thing) urg the regex state machine is so simple ;_;
        if self.id.startswith('PMID:'):
            log.warning('PMIDs should never be External IDs!')
            self._term = fake
            self.s = OntId(self.id).URIRef
            return

        self._term = OntTerm(self.id)
        self.s = self._term.URIRef
Пример #4
0
 def query_scigraph_for_curies(self, label: str, prefixes:List[str] = ['UBERON', 'ILX']) -> list:
     curies = []
     # return []
     # for prefix in prefixes:
     # BUG: prefixes cant be used because it gives random errors if the prefix isn't exact
     for prefix in prefixes:
         neighbors = [v.OntTerm for v in OntTerm.query(label=label.strip(), prefix=prefix)]
         if not neighbors:
             continue
         for neighbor in neighbors:
             oid = OntId(neighbor)
             curies.append(oid.curie)
     return curies
Пример #5
0
def res_stats(res):
    hrm = [(o, n['id']) for o, r in res for n in r['nodes']]           
    hrmt = len(hrm)
    ntotal = len(set(hrm))
    assert hrmt == ntotal
    nunique = len(set(t for o, t in hrm))
    dupes = [(t, c) for t, c in Counter([t for o, t in hrm]).most_common() if c > 1]
    ndupes = len(dupes)
    total_extra = sum(c for t, c in dupes) - ndupes
    many = [(c, OntTerm(t)) for t, c in dupes if c > 2]       
    # the extra 7142 terms are the result of 6695 terms that
    # appear more than once across multiple organs
    breakpoint()
def get_curies_from_scigraph_label_query(label: str,
                                         prefixes: List[str] = [
                                             'UBERON', 'ILX', 'PAXRAT'
                                         ]) -> list:
    curies = set()
    for prefix in prefixes:
        # TODO: if not stipped the label will return nothing. Seems to be trailing spaces
        neighbors = [
            v.OntTerm
            for v in OntTerm.query(label=label.strip(), prefix=prefix)
        ]
        if not neighbors:
            continue
        for neighbor in neighbors:
            curies.add(OntId(neighbor).curie)
    return list(curies)
Пример #7
0
    def route_sparc_dynamic(path):
        args = dict(request.args)
        if 'direction' in args:
            direction = args.pop('direction')
        else:
            direction = 'OUTGOING'  # should always be outgoing here since we can't specify?

        if 'format' in args:
            format_ = args.pop('format')
        else:
            format_ = None

        j = data_sgd.dispatch(path, **args)
        #breakpoint()
        if not j['edges']:
            log.error(pprint(j))
            return abort(400)

        kwargs = {'json': j}
        tree, extras = creatTree(*Query(None, None, direction, None), **kwargs)
        #print(extras.hierarhcy)
        print(tree)
        if format_ is not None:
            if format_ == 'table':
                #breakpoint()
                def nowrap(class_, tag=''):
                    return (f'{tag}.{class_}' '{ white-space: nowrap; }')

                ots = [
                    OntTerm(n) for n in flatten_tree(extras.hierarchy)
                    if 'CYCLE' not in n
                ]
                #rows = [[ot.label, ot.asId().atag(), ot.definition] for ot in ots]
                rows = [[ot.label,
                         hfn.atag(ot.iri, ot.curie), ot.definition]
                        for ot in ots]

                return htmldoc(hfn.render_table(rows, 'label', 'curie',
                                                'definition'),
                               styles=(hfn.table_style,
                                       nowrap('col-label', 'td')))

        return htmldoc(extras.html, styles=hfn.tree_styles)
Пример #8
0
def server(api_key=None, verbose=False):
    # data endpoint
    #_dataBP = 'https://sparc.olympiangods.org/scigraph'
    _dataBP = 'http://sparc-data.scicrunch.io:9000/scigraph'
    scigraphd = moduleDirect(_dataBP, 'scigraphd')
    data_sgd = scigraphd.Dynamic(cache=True, verbose=True, do_error=True)
    data_sgd._basePath = _dataBP
    data_sgc = scigraphd.Cypher(cache=True, verbose=True)
    data_sgc._basePath = _dataBP

    f = Path(__file__).resolve()
    working_dir = get_working_dir(__file__)
    resources = auth.get_path('resources')
    if working_dir:
        git_dir = working_dir / '.git'
    else:
        git_dir = Path('/dev/null')

    try:
        if working_dir is not None:
            ref = subprocess.check_output(['git',
                                           '--git-dir', git_dir.as_posix(),
                                           '--work-tree', working_dir.as_posix(),
                                           'rev-parse', 'HEAD'],
                                          stderr=subprocess.DEVNULL).decode().rstrip()
        else:
            ver = __version__
            if '+' in ver:
                ref = ver.split('+', 1)[-1]
            else:
                ref = ver

    except subprocess.CalledProcessError:
        ref = 'master' # 'NO-REPO-AT-MOST-TODO-GET-LATEST-HASH'

    wasGeneratedBy = ('https://github.com/tgbugs/pyontutils/blob/'
                      f'{ref}/pyontutils/{f.name}'
                      '#L{line}')
    line = getSourceLine(render)
    wgb = wasGeneratedBy.format(line=line)

    importchain = ImportChain(sgg=sgg, sgc=sgc, wasGeneratedBy=wasGeneratedBy)
    importchain.make_html()  # run this once, restart services on a new release

    loop = asyncio.get_event_loop()
    app = Flask('ontology tree service')
    app.config['loop'] = loop

    # gsheets = GoogleSheets()
    sparc_view = open_custom_sparc_view_yml()
    # sparc_view_raw = open_custom_sparc_view_yml(False)

    log.info('starting index load')

    uot_terms = [OntTerm(t) for t in uot]
    uot_lookup = {t.label:t for t in uot_terms}
    uot_ordered = sorted(t.label for t in uot_terms)

    basename = 'trees'

    @app.route(f'/{basename}', methods=['GET'])
    @app.route(f'/{basename}/', methods=['GET'])
    def route_():
        d = url_for('route_docs')
        e = url_for('route_examples')
        i = url_for('route_import_chain')
        return hfn.htmldoc(hfn.atag(d, 'Docs'),
                       '<br>',
                       hfn.atag(e, 'Examples'),
                       '<br>',
                       hfn.atag(i, 'Import chain'),
                       title='NIF ontology hierarchies')

    @app.route(f'/{basename}/docs', methods=['GET'])
    def route_docs():
        return redirect('https://github.com/SciCrunch/NIF-Ontology/blob/master/docs')  # TODO

    @app.route(f'/{basename}/examples', methods=['GET'])
    def route_examples():
        links = hfn.render_table(
            [[name,
              hfn.atag(url_for("route_query", pred=pred, root=root) + (args[0] if args else ''),
                   f'../query/{pred}/{root}{args[0] if args else ""}')]
             for name, pred, root, *args in examples],
            'Root class',
            '../query/{predicate-curie}/{root-curie}?direction=INCOMING&depth=10&branch=master&local=false',
            halign='left')

        flinks = hfn.render_table(
            [[name,
              hfn.atag(url_for("route_filequery", pred=pred, root=root, file=file) + (args[0] if args else ''),
                       f'../query/{pred}/{root}/{file}{args[0] if args else ""}')]
             for name, pred, root, file, *args in file_examples],
            'Root class',
            '../query/{predicate-curie}/{root-curie}/{ontology-filepath}?direction=INCOMING&depth=10&branch=master&restriction=false',
            halign='left')

        dlinks = hfn.render_table(
            [[name,
              hfn.atag(url_for("route_dynamic", path=path) + (querystring if querystring else ''),
                       f'../query/dynamic/{path}{querystring if querystring else ""}')]
             for name, path, querystring in dynamic_examples],
            'Root class',
            '../query/dynamic/{path}?direction=OUTGOING&dynamic=query&args=here',
            halign='left')

        return hfn.htmldoc(links, flinks, dlinks, title='Example hierarchy queries')

    @app.route(f'/{basename}/sparc/demos/isan2019/neuron-connectivity', methods=['GET'])
    def route_sparc_demos_isan2019_neuron_connectivity():
        def connected(start):
            log.debug(start)
            blob = data_sgd.neurons_connectivity(start)#, limit=9999)
            edges = blob['edges']
            neurons = {}
            types = {}
            rows = []
            start_type = None
            sc = OntId(start).curie
            for e in edges:
                s, p, o = e['sub'], e['pred'], e['obj']
                if p == 'operand':
                    continue

                if s.startswith('_:'):
                    if s not in neurons:
                        neurons[s] = []
                        types[s] = {}
                otp = OntTerm(p)
                oto = OntTerm(o)
                neurons[s].append((otp, oto))
                if o == sc:
                    start_type = otp

                if oto not in types[s]:
                    types[s][oto] = []

                types[s][oto].append(otp)

            for v in neurons.values():
                v.sort()

            return OntTerm(start), start_type, neurons, types

        hrm = [connected(t) for t in set(test_terms)]
        header =['Start', 'Start Type', 'Neuron', 'Relation', 'Target']
        rows = []
        for start, start_type, neurons, types in sorted(hrm):
            start = start.atag()
            start_type = start_type.atag() if start_type is not None else ''
            for i, v in enumerate(neurons.values(), 1):
                neuron = i
                for p, o in v:
                    relation = p.atag()
                    target = o.atag()
                    row = start, start_type, neuron, relation, target
                    rows.append(row)

                rows.append(['|'] + [' '] * 4)

        h = hfn.htmldoc(hfn.render_table(rows, *header), title='neuron connectivity')
        return h

    @app.route(f'/{basename}/sparc/demos/isan2019/flatmap-queries', methods=['GET'])
    def route_sparc_demos_isan2019_flatmap_queries():
        # lift up to load from an external source at some point
        # from pyontutils.core import OntResPath
        # orp = OntResPath('annotations.ttl')
        # [i for i in sorted(set(OntId(e) for t in orp.graph for e in t)) if i.prefix in ('UBERON', 'FMA', 'ILX')]
        query = """
      MATCH (blank)-
      [entrytype:ilxtr:hasSomaLocatedIn|ilxtr:hasAxonLocatedIn|ilxtr:hasDendriteLocatedIn|ilxtr:hasPresynapticTerminalsIn]
      ->(location:Class{{iri: "{iri}"}})
      WITH entrytype, location, blank
      MATCH (phenotype)<-[predicate]-(blank)<-[:equivalentClass]-(neuron)
      WHERE NOT (phenotype.iri =~ ".*_:.*")
      RETURN location, entrytype.iri, neuron.iri, predicate.iri, phenotype
        """

        def fetch(iri, limit=10):
            q = query.format(iri=iri)
            log.debug(q)
            blob = data_sgc.execute(q, limit, 'application/json')
            # oh boy
            # if there are less results than the limit scigraph segfaults
            # and returns nothing
            return blob

        hrm = [fetch(oid) for oid in test_terms]

        return hfn.htmldoc(hfn.render_table([[1, 2]],'oh', 'no'),
                           title='Simulated flatmap query results',
        )

    @app.route(f'/{basename}/sparc/demos/apinat', methods=['GET'])
    @app.route(f'/{basename}/sparc/demos/apinat/', methods=['GET'])
    def route_sparc_demos_apinat():
        return 'apinat'

    @app.route(f'/{basename}/sparc/connectivity/query', methods=['GET'])
    def route_sparc_connectivity_query():
        kwargs = request.args
        log.debug(kwargs)
        script = """
        var ele = document.getElementById('model-selector')
        ele.onselect
        """

        return hfn.htmldoc(hfn.render_form(
            [[('Model',), {}],
             [None, None],
             [
                 #('Kidney', 'Defensive breathing',),  # TODO autopopulate
                 ('Urinary Omega Tree',),
              {'id':'model-selector', 'name': 'model'}]],  # FIXME auto via js?

            # FIXME must switch start and stop per model (argh)
            # or hide/show depending on which model is selected
            [[('start',), {}],
             [None, None],
             [
                 #('one', 'two', 'three'),  # TODO auto populate
                 uot_ordered,
              {'name': 'start'}]],  # FIXME auto via js?

            [[('end',), {}],
             [None, None],
             [
                 #('one', 'two', 'three'),  # TODO auto populate
                 uot_ordered,
              {'name': 'end'}]],  # FIXME auto via js?

            [[tuple(), {}],
             [tuple(), {'type': 'submit', 'value': 'Query'}],
             [None, None]]  # FIXME auto via js?
            , action='view', method='POST'
        ),
            scripts=(script,),
            title='Connectivity query')

    @app.route(f'/{basename}/sparc/connectivity/view', methods=['POST'])
    def route_sparc_connectivity_view():
        kwargs = request.args
        log.debug(kwargs)
        # FIXME error handling for bad data
        model = request.form['model']
        start = request.form['start']
        end = request.form['end']
        sid = uot_lookup[start].curie
        eid = uot_lookup[end].curie
        #start = 'UBERON:0005157'
        #end = 'UBERON:0001255'
        return redirect(f'/{basename}/sparc/dynamic/shortestSimple?start_id={sid}'
                        f'&end_id={eid}&direction=INCOMING&format=table')  # TODO
        #return hfn.htmldoc(title='Connectivity view')

    @app.route(f'/{basename}/sparc/simple/dynamic/<path:path>', methods=['GET'])
    def route_sparc_simple_dynamic(path):
        return sparc_dynamic(data_sgd, data_sgc, path, wgb, simplify)

    @app.route(f'/{basename}/sparc/dynamic/<path:path>', methods=['GET'])
    def route_sparc_dynamic(path):
        return sparc_dynamic(data_sgd, data_sgc, path, wgb)

    @app.route(f'/{basename}/dynamic/<path:path>', methods=['GET'])
    def route_dynamic(path):
        args = dict(request.args)
        if 'direction' in args:
            direction = args.pop('direction')
        else:
            direction = 'OUTGOING'  # should always be outgoing here since we can't specify?

        if 'format' in args:
            format_ = args.pop('format')
        else:
            format_ = None

        try:
            j = sgd.dispatch(path, **args)
        except rHTTPError as e:
            log.exception(e)
            abort(e.response.status_code)  # DO NOT PASS ALONG THE MESSAGE
        except ValueError as e:
            log.exception(e)
            abort(404)

        if j is None or 'edges' not in j or not j['edges']:
            log.error(pformat(j))
            log.debug(sgd._last_url)
            return abort(400)

        prov = [hfn.titletag(f'Dynamic query result for {path}'),
                f'<meta name="date" content="{UTCNOWISO()}">',
                f'<link rel="http://www.w3.org/ns/prov#wasGeneratedBy" href="{wgb}">',
                '<meta name="representation" content="SciGraph">',
                f'<link rel="http://www.w3.org/ns/prov#wasDerivedFrom" href="{sgd._last_url}">']

        kwargs = {'json': cleanBad(j),
                  'html_head': prov}
        tree, extras = creatTree(*Query(None, None, direction, None), **kwargs)
        #print(extras.hierarhcy)
        #print(tree)
        if format_ is not None:
            if format_ == 'table':
                #breakpoint()
                def nowrap(class_, tag=''):
                    return (f'{tag}.{class_}'
                            '{ white-space: nowrap; }')

                ots = [OntTerm(n) for n in flatten_tree(extras.hierarchy) if 'CYCLE' not in n]
                #rows = [[ot.label, ot.asId().atag(), ot.definition] for ot in ots]
                rows = [[ot.label, hfn.atag(ot.iri, ot.curie), ot.definition] for ot in ots]

                return hfn.htmldoc(hfn.render_table(rows, 'label', 'curie', 'definition'),
                                   styles=(hfn.table_style, nowrap('col-label', 'td')))

        return hfn.htmldoc(extras.html,
                           other=prov,
                           styles=hfn.tree_styles)

    @app.route(f'/{basename}/imports/chain', methods=['GET'])
    def route_import_chain():
        return importchain.html

    @app.route(f'/{basename}/query/<pred>/<root>', methods=['GET'])
    def route_query(pred, root):
        kwargs = getArgs(request)
        kwargs['wgb'] = wgb
        maybe_abort = sanitize(pred, kwargs)
        if maybe_abort is not None:
            return maybe_abort
        if verbose:
            kwargs['verbose'] = verbose
            log.debug(str(kwargs))
        return render(pred, root, **kwargs)

    @app.route(f'/{basename}/query/<pred>/http:/<path:iri>', methods=['GET'])  # one / due to nginx
    @app.route(f'/{basename}/query/<pred>/https:/<path:iri>', methods=['GET'])  # just in case
    def route_iriquery(pred, iri):  # TODO maybe in the future
        root = 'http://' + iri  # for now we have to normalize down can check request in future
        if verbose:
            log.debug(f'ROOOOT {root}')
        kwargs = getArgs(request)
        kwargs['wgb'] = wgb
        maybe_abort = sanitize(pred, kwargs)
        if maybe_abort is not None:
            return maybe_abort
        if verbose:
            kwargs['verbose'] = verbose
            log.debug(str(kwargs))
        return render(pred, root, **kwargs)

    @app.route(f'/{basename}/query/<pred>/<root>/<path:file>', methods=['GET'])
    def route_filequery(pred, root, file):
        kwargs = getArgs(request)
        kwargs['local_filepath'] = file
        kwargs['wgb'] = wgb
        maybe_abort = sanitize(pred, kwargs)
        if maybe_abort is not None:
            return maybe_abort
        if verbose:
            kwargs['verbose'] = verbose
            log.debug(str(kwargs))
        try:
            return render(pred, root, **kwargs)
        except HTTPError:
            return abort(404, 'Unknown ontology file.')  # TODO 'Unknown git branch.'

    @app.route(f'/{basename}/sparc/view/<tier1>', methods=['GET'])
    @app.route(f'/{basename}/sparc/view/<tier1>/', methods=['GET'])
    @app.route(f'/{basename}/sparc/view/<tier1>/<tier2>', methods=['GET'])
    @app.route(f'/{basename}/sparc/view/<tier1>/<tier2>/', methods=['GET'])
    def route_sparc_view_query(tier1, tier2=None):
        journey = sparc_view
        if tier1 not in journey:
            return abort(404)

        journey = journey[tier1]
        if tier2 is not None:
            if tier2 not in journey:
                return abort(404)
            journey = journey[tier2]

        hyp_rows = hyperlink_tree(journey)

        return hfn.htmldoc(
            hfn.render_table(hyp_rows),
            title = 'Terms for ' + (tier2 if tier2 is not None else tier1),
            metas = ({'name':'date', 'content':time()},),
        )

    @app.route(f'/{basename}/sparc/view', methods=['GET'])
    @app.route(f'/{basename}/sparc/view/', methods=['GET'])
    def route_sparc_view():
        hyp_rows = []
        spaces = hfn.nbsp * 8
        for tier1, tier2_on in sorted(sparc_view.items()):
            url = url_for('route_sparc_view_query', tier1=tier1)
            tier1_row = tier1.split(YML_DELIMITER)
            tier1_row += tier2_on['CURIES']
            tagged_tier1_row = tag_row(tier1_row, url)
            hyp_rows.append(tagged_tier1_row)
            if not tier2_on:
                continue
            # BUG: Will break what we want if more is added to spinal cord
            if len(tier2_on.keys()) > 15:
                continue
            if tier1_row[0] == 'Nerve roots of spinal cord segments':
                continue
            for tier2, tier3_on in tier2_on.items():
                if tier2 == 'CURIES':
                    continue
                url = url_for('route_sparc_view_query', tier1=tier1, tier2=tier2)
                tier2_row = tier2.split(YML_DELIMITER)
                tier2_row += tier3_on['CURIES']
                tagged_tier2_row = tag_row(row=tier2_row, url=url, tier_level=1)
                if len(list(sparc_view[tier1_row[0]][tier2_row[0]].keys())) == 1:
                    tagged_tier2_row[0] = spaces+tier2_row[0]
                hyp_rows.append(tagged_tier2_row)
        return hfn.htmldoc(
            hfn.render_table(hyp_rows),
            title= 'Main Page Sparc',
            styles= ["p {margin: 0px; padding: 0px;}"],
            metas= ({'name':'date', 'content':time()},),
        )

    @app.route(f'/{basename}/sparc/index', methods=['GET'])
    @app.route(f'/{basename}/sparc/index/', methods=['GET'])
    def route_sparc_index():
        hyp_rows = hyperlink_tree(sparc_view)
        return hfn.htmldoc(
            hfn.render_table(hyp_rows),
            title = 'SPARC Anatomical terms index',
            metas = ({'name':'date', 'content':time()},),
        )

    @app.route(f'/{basename}/sparc', methods=['GET'])
    @app.route(f'/{basename}/sparc/', methods=['GET'])
    def route_sparc():
        # FIXME TODO route to compiled
        p = Path('/var/www/ontology/trees/sparc/sawg.html')
        if p.exists():
            return send_from_directory(p.parent.as_posix(), p.name)

        log.critical(f'{resources}/sawg.org has not been published')
        return send_from_directory(resources.as_posix(), 'sawg.org')
        #return hfn.htmldoc(
            #atag(url_for('route_sparc_view'), 'Terms by region or atlas'), '<br>',
            #atag(url_for('route_sparc_index'), 'Index'),
            #title='SPARC Anatomical terms', styles=["p {margin: 0px; padding: 0px;}"],
            #metas = ({'name':'date', 'content':time()},),
        #)

    return app
Пример #9
0
def sparc_dynamic(data_sgd, data_sgc, path, wgb, process=lambda coll, blob: blob):
    args = dict(request.args)
    if 'direction' in args:
        direction = args.pop('direction')
    else:
        direction = 'OUTGOING'  # should always be outgoing here since we can't specify?

    if 'format' in args:
        format_ = args.pop('format')
    else:
        format_ = None

    if 'apinat' in path:  # FIXME bad hardcoded hack
        _old_get = data_sgd._get
        try:
            data_sgd._get = data_sgd._normal_get
            j = data_sgd.dispatch(path, **args)
        except ValueError as e:
            log.exception(e)
            abort(404)
        except rHTTPError as e:
            log.exception(e)
            abort(e.response.status_code)  # DO NOT PASS ALONG THE MESSAGE
        finally:
            data_sgd._get = _old_get
    else:
        try:
            j = data_sgd.dispatch(path, **args)
        except rHTTPError as e:
            log.exception(e)
            abort(e.response.status_code)  # DO NOT PASS ALONG THE MESSAGE
        except ValueError as e:
            log.exception(e)
            abort(404)

    j = process(collapse_apinat, j)

    if j is None or 'edges' not in j:
        log.error(pformat(j))
        return abort(400)

    elif not j['edges']:
        return node_list(j['nodes'])  # FIXME ... really should error?

    if path.endswith('housing-lyphs'):  # FIXME hack
        root = 'NLX:154731'
        #direction = 'INCOMING'
    else:
        root = None

    prov = [
        hfn.titletag(f'Dynamic query result for {path}'),
        f'<meta name="date" content="{UTCNOWISO()}">',
        f'<link rel="http://www.w3.org/ns/prov#wasGeneratedBy" href="{wgb}">',
        '<meta name="representation" content="SciGraph">',
        ('<link rel="http://www.w3.org/ns/prov#wasDerivedFrom" '
         f'href="{data_sgd._last_url}">')]

    kwargs = {'json': cleanBad(j),
                'html_head': prov,
                'prefixes': data_sgc.getCuries(),  # FIXME efficiency
    }
    tree, extras = creatTree(*Query(root, None, direction, None), **kwargs)
    #print(extras.hierarhcy)
    #print(tree)
    if format_ is not None:
        if format_ == 'table':
            #breakpoint()
            def nowrap(class_, tag=''):
                return (f'{tag}.{class_}'
                        '{ white-space: nowrap; }')

            ots = [OntTerm(n)
                   for n in flatten_tree(extras.hierarchy)
                   if 'CYCLE' not in n]
            #rows = [[ot.label, ot.asId().atag(), ot.definition] for ot in ots]
            rows = [[ot.label, hfn.atag(ot.iri, ot.curie), ot.definition]
                    for ot in ots]

            return hfn.htmldoc(hfn.render_table(rows, 'label', 'curie', 'definition'),
                               styles=(hfn.table_style, nowrap('col-label', 'td')))

    return hfn.htmldoc(extras.html,
                       other=prov,
                       styles=hfn.tree_styles)
Пример #10
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self._term = OntTerm(self.id)
     self.s = self._term.URIRef
def main():
    sparc_terms = convert_view_text_to_dict()
    print('Linearizing graph')
    sparc_terms_unpaired = list(linearize_graph(sparc_terms))
    print('Adding ids to terms list')
    sparc_terms_paired = pair_terms(sparc_terms_unpaired)
    # embed()
    avoid_in_bl = [
        'Gross anatomy',
        'Internal anatomy',
        'Segmental Anatomy',
        'Atlas Nomenclature',
        'Allen Mouse Brainstem',
        'Paxinos Rar Brainstem'
        'Berman Cat Brainstem',
        'Nerves (also includes Cranial)',
        'UBERON',
    ]

    accepted_prefixes_for_bl = [
        'UBERON',
        'PAXRAT',
    ]

    print('Building sparc terms list txt')
    sparc_terms_text, sparc_terms_bl = '', []
    for term in sparc_terms_paired:
        sparc_terms_text += ' ' * 4 * term.tier_level + '\t'.join(
            [term.label] + term.curies) + '\n'
        if not term.curies and term.label.strip() not in avoid_in_bl:
            sparc_terms_bl.append(term.label)

    # Labels with no ID
    # Slow as heck
    print(
        f'Building list for terms with no IDs with len:{len(sparc_terms_bl)}')
    for i, bl_term in enumerate(sparc_terms_bl):
        neighbors = OntTerm.search(bl_term.split(' ')[0])
        for neighbor in neighbors:
            if set(neighbor.split(' ')) == set(bl_term.split(' ')):
                # if neighbor.curie.split(':')[0] in accepted_prefixes_for_bl:
                view_text_bl[i] += '\t' + neighbor.curie

    # Original IDs with wrong label
    print('Building list for terms with wrong IDs')
    sparc_terms_with_bad_ids = []
    for term in sparc_terms_unpaired:
        for curie in term.curies:
            onts = OntTerm.query(curie=curie)
            if not onts:
                continue
            for ont in onts:
                if term.label.lower().strip() != ont.label.lower().strip():
                    sparc_terms_with_bad_ids.append({
                        **vars(term), 'searched_label':
                        ont.label
                    })

    # embed()
    with open(resources / 'sparc_terms_populated3.txt', 'w') as outfile:
        outfile.write(sparc_terms_text)
    with open(resources / 'sparc_terms_unpopulated_terms3.txt',
              'w') as outfile:
        outfile.write('\n'.join(sorted(sparc_terms_bl)))
    with open(resources / 'sparc_terms_with_bad_ids3.json', 'w') as outfile:
        json.dump(sparc_terms_with_bad_ids, outfile, indent=4)
Пример #12
0
#   methods helper (subset of the larger ontology to speed up development)
###

restHasValue = Restriction(None, owl.hasValue)

filename = 'methods-helper'
prefixes = None
OntCuries['HBP_MEM'] = 'http://www.hbp.FIXME.org/hbp_measurement_methods/'
#OntCuries['HBP_MEM'] = 'http://www.hbp.FIXME.org/hbp_measurement_methods/'
#imports = NIFTTL['nif_backend.ttl'],
imports = methods_core.iri,
comment = 'helper for methods development'
_repo = True
debug = True

triples = ((tech.injection, owl.equivalentClass, OntTerm('BIRNLEX:2135')), )

triples += (  # protocols
    oc(prot.CLARITY, ilxtr.protocol),
    oc(prot.deepSequencing, ilxtr.protocol),
    oc(prot.sangerSequencing, ilxtr.protocol),
    oc(prot.shotgunSequencing, ilxtr.protocol),
    oc(prot.fMRI, ilxtr.protocol),
    oc(prot.dwMRI, ilxtr.protocol),
    oc(prot.DTI, ilxtr.protocol),
)

triples += (  # information entity

    # information entities
    oc(ilxtr.informationEntity),
Пример #13
0
def server(api_key=None, verbose=False):
    f = Path(__file__).resolve()
    working_dir = get_working_dir(__file__)
    if working_dir:
        git_dir = working_dir / '.git'
    else:
        git_dir = Path('/dev/null')

    try:
        commit = subprocess.check_output(
            [
                'git', '--git-dir',
                git_dir.as_posix(), '--work-tree',
                working_dir.as_posix(), 'rev-parse', 'HEAD'
            ],
            stderr=subprocess.DEVNULL).decode().rstrip()
    except subprocess.CalledProcessError:
        commit = 'master'  # 'NO-REPO-AT-MOST-TODO-GET-LATEST-HASH'
    wasGeneratedBy = ('https://github.com/tgbugs/pyontutils/blob/'
                      f'{commit}/pyontutils/{f.name}'
                      '#L{line}')
    line = getSourceLine(render)
    wgb = wasGeneratedBy.format(line=line)

    importchain = ImportChain(wasGeneratedBy=wasGeneratedBy)
    importchain.make_html()  # run this once, restart services on a new release

    loop = asyncio.get_event_loop()
    app = Flask('ontology tree service')
    app.config['loop'] = loop

    # gsheets = GoogleSheets()
    sparc_view = open_custom_sparc_view_yml()
    log.info('starting index load')

    uot_terms = [OntTerm(t) for t in uot]
    uot_lookup = {t.label: t for t in uot_terms}
    uot_ordered = sorted(t.label for t in uot_terms)

    basename = 'trees'

    @app.route(f'/{basename}', methods=['GET'])
    @app.route(f'/{basename}/', methods=['GET'])
    def route_():
        d = url_for('route_docs')
        e = url_for('route_examples')
        i = url_for('route_import_chain')
        return htmldoc(atag(d, 'Docs'),
                       '<br>',
                       atag(e, 'Examples'),
                       '<br>',
                       atag(i, 'Import chain'),
                       title='NIF ontology hierarchies')

    @app.route(f'/{basename}/docs', methods=['GET'])
    def route_docs():
        return redirect(
            'https://github.com/SciCrunch/NIF-Ontology/blob/master/docs'
        )  # TODO

    @app.route(f'/{basename}/examples', methods=['GET'])
    def route_examples():
        links = render_table(
            [[
                name,
                atag(
                    url_for("route_query", pred=pred, root=root) +
                    (args[0] if args else ''),
                    f'../query/{pred}/{root}{args[0] if args else ""}')
            ] for name, pred, root, *args in examples],
            'Root class',
            '../query/{predicate-curie}/{root-curie}?direction=INCOMING&depth=10&branch=master&local=false',
            halign='left')

        flinks = render_table(
            [[
                name,
                atag(
                    url_for("route_filequery", pred=pred, root=root,
                            file=file) + (args[0] if args else ''),
                    f'../query/{pred}/{root}/{file}{args[0] if args else ""}')
            ] for name, pred, root, file, *args in file_examples],
            'Root class',
            '../query/{predicate-curie}/{root-curie}/{ontology-filepath}?direction=INCOMING&depth=10&branch=master&restriction=false',
            halign='left')

        dlinks = render_table(
            [[
                name,
                atag(
                    url_for("route_dynamic", path=path) +
                    (querystring if querystring else ''),
                    f'../query/dynamic/{path}{querystring if querystring else ""}'
                )
            ] for name, path, querystring in dynamic_examples],
            'Root class',
            '../query/dynamic/{path}?direction=OUTGOING&dynamic=query&args=here',
            halign='left')

        return htmldoc(links,
                       flinks,
                       dlinks,
                       title='Example hierarchy queries')

    @app.route(f'/{basename}/sparc/connectivity/query', methods=['GET'])
    def route_sparc_connectivity_query():
        kwargs = request.args
        log.debug(kwargs)
        script = """
        var ele = document.getElementById('model-selector')
        ele.onselect
        """

        return hfn.htmldoc(
            hfn.render_form(
                [
                    [('Model', ), {}],
                    [None, None],
                    [
                        #('Kidney', 'Defensive breathing',),  # TODO autopopulate
                        (
                            'Urinary Omega Tree', ),
                        {
                            'id': 'model-selector',
                            'name': 'model'
                        }
                    ]
                ],  # FIXME auto via js?

                # FIXME must switch start and stop per model (argh)
                # or hide/show depending on which model is selected
                [
                    [('start', ), {}],
                    [None, None],
                    [
                        #('one', 'two', 'three'),  # TODO auto populate
                        uot_ordered,
                        {
                            'name': 'start'
                        }
                    ]
                ],  # FIXME auto via js?
                [
                    [('end', ), {}],
                    [None, None],
                    [
                        #('one', 'two', 'three'),  # TODO auto populate
                        uot_ordered,
                        {
                            'name': 'end'
                        }
                    ]
                ],  # FIXME auto via js?
                [[tuple(), {}],
                 [tuple(), {
                     'type': 'submit',
                     'value': 'Query'
                 }], [None, None]]  # FIXME auto via js?
                ,
                action='view',
                method='POST'),
            scripts=(script, ),
            title='Connectivity query')

    @app.route(f'/{basename}/sparc/connectivity/view', methods=['POST'])
    def route_sparc_connectivity_view():
        kwargs = request.args
        log.debug(kwargs)
        # FIXME error handling for bad data
        model = request.form['model']
        start = request.form['start']
        end = request.form['end']
        sid = uot_lookup[start].curie
        eid = uot_lookup[end].curie
        #start = 'UBERON:0005157'
        #end = 'UBERON:0001255'
        return redirect(
            f'/{basename}/sparc/dynamic/shortestSimple?start_id={sid}&end_id={eid}&direction=INCOMING&format=table'
        )  # TODO
        #return hfn.htmldoc(title='Connectivity view')

    @app.route(f'/{basename}/sparc/dynamic/<path:path>', methods=['GET'])
    def route_sparc_dynamic(path):
        args = dict(request.args)
        if 'direction' in args:
            direction = args.pop('direction')
        else:
            direction = 'OUTGOING'  # should always be outgoing here since we can't specify?

        if 'format' in args:
            format_ = args.pop('format')
        else:
            format_ = None

        j = data_sgd.dispatch(path, **args)
        #breakpoint()
        if not j['edges']:
            log.error(pprint(j))
            return abort(400)

        kwargs = {'json': j}
        tree, extras = creatTree(*Query(None, None, direction, None), **kwargs)
        #print(extras.hierarhcy)
        print(tree)
        if format_ is not None:
            if format_ == 'table':
                #breakpoint()
                def nowrap(class_, tag=''):
                    return (f'{tag}.{class_}' '{ white-space: nowrap; }')

                ots = [
                    OntTerm(n) for n in flatten_tree(extras.hierarchy)
                    if 'CYCLE' not in n
                ]
                #rows = [[ot.label, ot.asId().atag(), ot.definition] for ot in ots]
                rows = [[ot.label,
                         hfn.atag(ot.iri, ot.curie), ot.definition]
                        for ot in ots]

                return htmldoc(hfn.render_table(rows, 'label', 'curie',
                                                'definition'),
                               styles=(hfn.table_style,
                                       nowrap('col-label', 'td')))

        return htmldoc(extras.html, styles=hfn.tree_styles)

    @app.route(f'/{basename}/dynamic/<path:path>', methods=['GET'])
    def route_dynamic(path):
        args = dict(request.args)
        if 'direction' in args:
            direction = args.pop('direction')
        else:
            direction = 'OUTGOING'  # should always be outgoing here since we can't specify?

        if 'format' in args:
            format_ = args.pop('format')
        else:
            format_ = None

        j = sgd.dispatch(path, **args)
        if not j['edges']:
            log.error(pprint(j))
            return abort(400)

        kwargs = {'json': j}
        tree, extras = creatTree(*Query(None, None, direction, None), **kwargs)
        #print(extras.hierarhcy)
        print(tree)
        if format_ is not None:
            if format_ == 'table':
                #breakpoint()
                def nowrap(class_, tag=''):
                    return (f'{tag}.{class_}' '{ white-space: nowrap; }')

                ots = [
                    OntTerm(n) for n in flatten_tree(extras.hierarchy)
                    if 'CYCLE' not in n
                ]
                #rows = [[ot.label, ot.asId().atag(), ot.definition] for ot in ots]
                rows = [[ot.label,
                         hfn.atag(ot.iri, ot.curie), ot.definition]
                        for ot in ots]

                return htmldoc(hfn.render_table(rows, 'label', 'curie',
                                                'definition'),
                               styles=(hfn.table_style,
                                       nowrap('col-label', 'td')))

        return htmldoc(extras.html, styles=hfn.tree_styles)

    @app.route(f'/{basename}/imports/chain', methods=['GET'])
    def route_import_chain():
        return importchain.html

    @app.route(f'/{basename}/query/<pred>/<root>', methods=['GET'])
    def route_query(pred, root):
        kwargs = getArgs(request)
        kwargs['wgb'] = wgb
        maybe_abort = sanitize(pred, kwargs)
        if maybe_abort is not None:
            return maybe_abort
        if verbose:
            kwargs['verbose'] = verbose
            log.debug(str(kwargs))
        return render(pred, root, **kwargs)

    @app.route(f'/{basename}/query/<pred>/http:/<path:iri>',
               methods=['GET'])  # one / due to nginx
    @app.route(f'/{basename}/query/<pred>/https:/<path:iri>',
               methods=['GET'])  # just in case
    def route_iriquery(pred, iri):  # TODO maybe in the future
        root = 'http://' + iri  # for now we have to normalize down can check request in future
        if verbose:
            log.debug(f'ROOOOT {root}')
        kwargs = getArgs(request)
        kwargs['wgb'] = wgb
        maybe_abort = sanitize(pred, kwargs)
        if maybe_abort is not None:
            return maybe_abort
        if verbose:
            kwargs['verbose'] = verbose
            log.debug(str(kwargs))
        return render(pred, root, **kwargs)

    @app.route(f'/{basename}/query/<pred>/<root>/<path:file>', methods=['GET'])
    def route_filequery(pred, root, file):
        kwargs = getArgs(request)
        kwargs['local_filepath'] = file
        kwargs['wgb'] = wgb
        maybe_abort = sanitize(pred, kwargs)
        if maybe_abort is not None:
            return maybe_abort
        if verbose:
            kwargs['verbose'] = verbose
            log.debug(str(kwargs))
        try:
            return render(pred, root, **kwargs)
        except HTTPError:
            return abort(
                404, 'Unknown ontology file.')  # TODO 'Unknown git branch.'

    @app.route(f'/{basename}/sparc/view/<tier1>', methods=['GET'])
    @app.route(f'/{basename}/sparc/view/<tier1>/', methods=['GET'])
    @app.route(f'/{basename}/sparc/view/<tier1>/<tier2>', methods=['GET'])
    @app.route(f'/{basename}/sparc/view/<tier1>/<tier2>/', methods=['GET'])
    def route_sparc_view_query(tier1, tier2=None):
        journey = sparc_view
        if tier1 not in journey:
            return abort(404)

        journey = journey[tier1]
        if tier2 is not None:
            if tier2 not in journey:
                return abort(404)
            journey = journey[tier2]

        hyp_rows = hyperlink_tree(journey)

        return htmldoc(
            render_table(hyp_rows),
            title='Terms for ' + (tier2 if tier2 is not None else tier1),
            metas=({
                'name': 'date',
                'content': time()
            }, ),
        )

    @app.route(f'/{basename}/sparc/view', methods=['GET'])
    @app.route(f'/{basename}/sparc/view/', methods=['GET'])
    def route_sparc_view():
        hyp_rows = []
        spaces = nbsp * 8
        for tier1, tier2_on in sorted(sparc_view.items()):
            url = url_for('route_sparc_view_query', tier1=tier1)
            tier1_row = tier1.split(YML_DELIMITER)
            tier1_row += tier2_on['CURIES']
            tagged_tier1_row = tag_row(tier1_row, url)
            hyp_rows.append(tagged_tier1_row)
            if not tier2_on:
                continue
            # BUG: Will break what we want if more is added to spinal cord
            if len(tier2_on.keys()) > 6:
                continue
            for tier2, tier3_on in tier2_on.items():
                if tier2 == 'CURIES':
                    continue
                url = url_for('route_sparc_view_query',
                              tier1=tier1,
                              tier2=tier2)
                tier2_row = tier2.split(YML_DELIMITER)
                tier2_row += tier3_on['CURIES']
                tagged_tier2_row = tag_row(row=tier2_row,
                                           url=url,
                                           tier_level=1)
                hyp_rows.append(tagged_tier2_row)
        return htmldoc(
            render_table(hyp_rows),
            title='Main Page Sparc',
            styles=["p {margin: 0px; padding: 0px;}"],
            metas=({
                'name': 'date',
                'content': time()
            }, ),
        )

    @app.route(f'/{basename}/sparc/index', methods=['GET'])
    @app.route(f'/{basename}/sparc/index/', methods=['GET'])
    def route_sparc_index():
        hyp_rows = hyperlink_tree(sparc_view)
        return htmldoc(
            render_table(hyp_rows),
            title='SPARC Anatomical terms index',
            metas=({
                'name': 'date',
                'content': time()
            }, ),
        )

    @app.route(f'/{basename}/sparc', methods=['GET'])
    @app.route(f'/{basename}/sparc/', methods=['GET'])
    def route_sparc():
        # FIXME TODO route to compiled
        p = Path('/var/www/ontology/trees/sparc/sawg.html')
        if p.exists():
            return send_from_directory(p.parent.as_posix(), p.name)

        log.critical(f'{devconfig.resources}/sawg.org has not been published')
        return send_from_directory(
            Path(devconfig.resources).as_posix(), 'sawg.org')
        #return htmldoc(
        #atag(url_for('route_sparc_view'), 'Terms by region or atlas'), '<br>',
        #atag(url_for('route_sparc_index'), 'Index'),
        #title='SPARC Anatomical terms', styles=["p {margin: 0px; padding: 0px;}"],
        #metas = ({'name':'date', 'content':time()},),
        #)

    return app