{ "info": { "author": "Chiara Rasi", "author_email": "chiara.rasi@scilifelab.se", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Science/Research", "License :: OSI Approved :: MIT License", "Operating System :: MacOS", "Operating System :: Unix", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy" ], "description": "# patientMatcher\n[![Build Status](https://travis-ci.com/Clinical-Genomics/patientMatcher.svg?branch=master)](https://travis-ci.com/Clinical-Genomics/patientMatcher) [![Coverage Status](https://coveralls.io/repos/github/Clinical-Genomics/patientMatcher/badge.svg?branch=master)](https://coveralls.io/github/Clinical-Genomics/patientMatcher?branch=master)\n\nTable of Contents:\n1. [ Prerequisites ](#prerequisites)\n2. [ Installation ](#installation)\n - [ Using docker ](#installation-docker)\n3. [ Data types ](#data_types)\n4. [ Command line interface](#cli)\n - [ Adding demo data to server](#cli_add_demo)\n - [ Removing a patient from database ](#cli_remove_patient)\n - [ Adding a client to database ](#cli_add_client)\n - [ Adding a new connected node to database ](#cli_add_node)\n5. [ Server endpoints ](#endpoints)\n - [ Add patient to server (/patient/add) ](#add)\n - [ Delete patient from server (/patient/delete/) ](#delete)\n - [ Get server stats (/metrics) ](#metrics)\n - [ Get the list of connected nodes (/nodes) ](#node_list)\n - [ Send a match request to server (/match) ](#match)\n - [ Send a match request to external nodes (/match/external/) ](#match_external)\n - [ Show all matches for a given patient (/matches/) ](#patient_matches)\n6. [ Patient matching algorithm ](#matching_algorithm)\n - [ Genotyping matching algorithm ](#geno_matching)\n - [ Phenotyping matching algorithm ](#pheno_matching)\n7. [ Enabling matching notifications ](#notify)\n\n\n## Prerequisites\nTo use this server you'll need to have a working instance of **MongoDB**. from the mongo shell you can create a database and an authenticated user to handle connections using this syntax:\n\n```bash\nuse pmatcher\ndb.createUser(\n {\n user: \"pmUser\",\n pwd: \"pmPassword\",\n roles: [ \"dbOwner\" ]\n }\n)\n```\nAfter setting up the restricted access to the server you'll just have to launch the mongo demon using authentication:\n```bash\nmongod --auth --dbpath path_to_database_data\n```\n\n\n## Installation\nThe phenotype scoring algorithm of patientMatcher is dependent on [patient-similarity](https://github.com/buske/patient-similarity), which should be installed using this script:\n\n```bash\npip install git+https://github.com/Clinical-Genomics/patient-similarity\n```\nAfter installing patient-similarity, clone patientMatcher repository from github using this command:\n\n```bash\ngit clone https://github.com/Clinical-Genomics/patientMatcher.git\n```\n\nChange directory to the cloned folder and from there install the software using the following command:\n```bash\npip install -e .\n```\n\nTo customize the server configuration you'll need to edit the **config.py** file under the /instance folder.  \nFor testing purposes you can keep the default configuration values as they are, but keep in mind that you should adjust these numbers when in production.\n\nTo start the server run this command:\n```bash\npmatcher run -h custom_host -p custom_port\n```\nPlease note that the code is NOT guaranteed to be bug-free and it must be adapted to be used in production.\n\n\n### Using Docker\nA simple Dockerfile has been included for testing purposes. It uses the sample `instance/config.py` and\nshould not be used in production.\n\n#### Build the image\nFrom the repo directory:\n\n```bash\n# note: docker does not allow upper case in image tags\n$ docker build -t local/patientmatcher .\n```\n\n#### Running the image\nTo run the image in the foreground use:\n```bash\n$ docker run -p 5000 --name patientMatcher local/patientmatcher\n```\n\nYou can then `curl localhost:5000/...` to the appropriate resources from another terminal. The database is\ninitialized with a test token (`test_token`) that can be used. e.g.,\n\n```bash\n$ curl -H 'x-auth-token: test_token' localhost:5000/metrics\n```\n\nTo run with your own settings, mount an `instance` directory containing a `config.py`:\n\n```bash\n$ docker run -p 5000 -v /some/local/path/instance:/opt/patientMatcher/instance local/patientmatcher\n```\n\n\n## Data types\nThis server implements the [Matchmaker Exchange APIs](https://github.com/ga4gh/mme-apis). It accepts and returns patient data validated against the [json schema](https://github.com/MatchmakerExchange/reference-server/blob/master/mme_server/schemas/api.json) defined in the [MME reference-server project](https://github.com/MatchmakerExchange/reference-server).\n\n  \n\n\n## Command line interface\nA list of available commands can be invoked by running the following command:\n```bash\npmatcher\n```\n  \n\n\n### Adding demo data to server\nFor testing purposes you can upload a list of [50 benchmarking patients](https://github.com/ga4gh/mme-apis/tree/master/testing). \nTo add these patients to the database run the following command:\n```bash\npmatcher add demodata\n```\n  \n\n\n### Removing a patient from the database.\nYou can remove a patient using the command line interface by invoking this command and providing **either its ID or its label** (or both actually):\n\n```bash\npmatcher remove patient [OPTIONS]\n\nOptions:\n-id TEXT ID of the patient to be removed from database\n-label TEXT label of the patient to be removed from database\n```\n  \n\n\n### Adding a client to the database\nIn order to save patients into patientMatcher you need to create at least one authorized client. \nUse the following command to insert a client object in the database:\n\n```bash\npmatcher add client [OPTIONS]\n\nOptions:\n-id TEXT Client ID [required]\n-token TEXT Authorization token [required]\n-url TEXT Client URL [required]\n-contact TEXT Client email\n```\nPOST request aimed at adding or modifying a patient in patientMatcher **should be using a token** from a client present in the database. \nClients may be from the command line with this command:\n```bash\npmatcher remove client -id client_id\n```\n  \n\n\n### Adding a connected node to the database\nTo connect to another MME node and submit requests to it you should know the authentication token to the other node. \nYou can add a node to the database by running the command:\n\n```bash\npmatcher add node [OPTIONS]\n\nOptions:\n -id TEXT Server/Client ID [required]\n -token TEXT Authorization token [required]\n -matching_url TEXT URL to send match requests to [required]\n -accepted_content TEXT Accepted Content-Type [required]\n -contact TEXT An email address\n```\nConnected nodes may be removed any time using the command: \n```bash\npmatcher remove node -id node_id\n```\n  \n\n\n## Server endpoints\n\n\n- **/patient/add**.\n To add patients using a **POST** request. Example:\n```bash\ncurl -X POST \\\n -H 'X-Auth-Token: custom_token' \\\n -H 'Content-Type: application/vnd.ga4gh.matchmaker.v1.0+json' \\\n -H 'Accept: application/json' \\\n -d '{\"patient\":{\n \"id\":\"patient_id\",\n \"contact\": {\"name\":\"Contact Name\", \"href\":\"mailto:contact_name@mail.com\"},\n \"features\":[{\"id\":\"HP:0009623\"}],\n \"genomicFeatures\":[{\"gene\":{\"id\":\"EFTUD2\"}}]\n }}' localhost:9020/patient/add\n```\nTo update the data of a patient already submitted to the server you can use the same command and add a patient with the same ID. \n\nThe action of adding or updating a patient in the server will trigger an **external search of similar patients from connected nodes**. \nIf there are no connected nodes in the database or you are uploading demo data no search will be performed on other nodes.\n\n  \n\n\n- **patient/delete/**.\n You can delete a patient from the database by sending a **DELETE** request with its ID to the server. Example:\n```bash\ncurl -X DELETE \\\n -H 'X-Auth-Token: custom_token' \\\n localhost:9020/patient/delete/patient_id\n```\nPlease note that when a patient is deleted all its match results will be also deleted from the database. This is valid for **matches where the patient was used as the query patient** in searches performed on other nodes or the internal patientMatcher database (internal search).\nMatching results where the removed patient is instead listed among the matching results will be not removed from the database.\n\n  \n\n\n- **/metrics**.\n Use this endpoint to **get** database metrics.
\nStats which could be retrieved by a MME service are described [here](https://github.com/ga4gh/mme-apis/blob/master/metrics-api.md)
\nExample:\n```bash\ncurl -X GET \\\n -H 'X-Auth-Token: custom_token' \\\n localhost:9020/metrics\n```\n  \n\n\n- **/nodes**.\n **GET** the list of connected nodes. Example:\n```bash\ncurl -X GET \\\n -H 'X-Auth-Token: custom_token' \\\n localhost:9020/nodes\n```\nThe response will return a list like this : [ { 'id' : node_1_id, 'description' : node1_description }, .. ] or an empty list if the server is not connected to external nodes.\n\n  \n\n\n- **/match**.\n **POST** a request with a query patient to patientMatcher and get a response with the patients in the server which are most similar to your query. Example:\n```bash\ncurl -X POST \\\n -H 'X-Auth-Token: custom_token' \\\n -H 'Content-Type: application/vnd.ga4gh.matchmaker.v1.0+json' \\\n -H 'Accept: application/vnd.ga4gh.matchmaker.v1.0+json' \\\n -d '{\"patient\":{\n \"id\":\"patient_id\",\n \"contact\": {\"name\":\"Contact Name\", \"href\":\"mailto:contact_name@mail.com\"},\n \"features\":[{\"id\":\"HP:0009623\"}],\n \"genomicFeatures\":[{\"gene\":{\"id\":\"EFTUD2\"}}]\n }}' localhost:9020/match\n```\nThe **maximum number of patients returned by the server** is a parameter which can be customized by editing the \"MAX_RESULTS\" field in the config.py file. Default value is 5.\nPatient matches are returned in order or descending similarity with the query patient (The most similar patients are higher in the list of results).\n\n  \n\n- **/match/external/**.\n Trigger a search in external nodes for patients similar to the one specified by the ID. Example:\n```bash\ncurl -X POST \\\n -H 'X-Auth-Token: custom_token' \\\n localhost:9020/match/external/patient_id\n```\nIt is possible to search for matching patients on a specific node. To do so specify the node id in the request args. Example:\n```bash\ncurl -X POST \\\n -H 'X-Auth-Token: custom_token' \\\n localhost:9020/match/external/patient_id?node=specific_node_id\n```\nRead [here](#node_list) how to get a list with the ID of the connected nodes.\n\n  \n\n\n- **/matches/**.\n Return all matches (internal and external) with positive results for a patient specified by an ID. Example:\n```bash\ncurl -X GET \\\n -H 'X-Auth-Token: custom_token' \\\n localhost:9020/matches/patient_id\n```\n  \n\n\n## Patient matching algorithm.\nEach patient query submitted to the server triggers a matching algorithm which will search and return those patients on the server that are most similar to the queried one.\nPatient similarity is measured by the a **similarity score** that may span **from 0 (no matching) to 1 (exact matching)**.\n\nSimilarity score computation is taking into account **genomic similarity** and **phenotype similarity** across patients. The weight of these two factors is numerically evaluated into a GTscore and a PhenoScore, and the sum of the 2 constitutes the similarity score of the matching patient.\n\nThe relative weight of the GTscore and the PhenoScore can be customised by the database administrator by changing the values of the parameters \"MAX_GT_SCORE\" and \"MAX_PHENO_SCORE\" in the configuration file (instance/config.py). Default values are MAX_GT_SCORE: 0.5, MAX_PHENO_SCORE : 0.5.\n\n\n### Genotyping matching algorithm\nGTscore is computed by evaluating the list of genomic features of the queried patient and the patients available on the MME server.\n\nIf the queried patient has no genomic features (only phenotype features) then GTscore of all the returned matches will be 0.\n\nExample of how the algorithm works:\nLet's assume that 0.5 is the MAX_GT_SCORE possible for a patient match (default parameters).\n\nIf for instance the queried patient (QUERY) has 3 variants, **each variant will have a relative weight** of 0.1666 (0.5/3). 0.1666 will be the maximum score for each variant.\nAssuming having a QUERY patient with these variants:\n - gene X variant A\n - gene Y variant B\n - gene Z variant C\n\nAny patient in the database having variants in any of the X,Y,Z genes will constitute a match (MATCH) to the queried patient and will be compared against it.\nLet's assume the variants in MATCH are:\n- gene X variant D (1)\n- gene Y variant B (2)\n- gene W variant E (3)\n\nThe evaluation of the matching features is always performed on the QUERY variants, in this way:\n- gene X variant A ---> gene match with (1). No variant match. Assigned score: 0.1666/4 (gene match only will be arbitrarily assigned a fourth of the relative weight of the variant)\n- gene Y variant B ---> exact matching of variant and gene with (2). Assigned score: 0.1666 (max relative weight of the variant)\n- gene Z variant C ---> No match, assigned score: 0.\n\nGTscore assigned to the MATCH patients will then be: 0.1666/4 + 0.1666 + 0.\n\nNote that the algorithm will evaluate and assign a score of 0.1666 (max relative weight of the variant) also to matching variants outside genes.\nThis way patients will be evaluated for genetic similarity even if the variants lay outside genes.\n\n\n\n### Phenotype matching algorithm\nPhenotype similarity is calculated by taking into account **features and disorders** of a patient.\n\n- **Patient features**\nare specified by the eventual HPO terms provided for the query patient. **Similarity between HPO features will be equal the maximum similarity score** between two patients **if no disorders (OMIM terms) are provided** for one or both patients. \n**Otherwise feature similarity score will make up 1/2 of the maximum similarity score**.\nFeature similarity is calculated as the simgic score obtained by comparing HPO terms of a query patient with those from a matching patient using the [patient-similarity software package](https://github.com/buske/patient-similarity).\nYou can find more information on semantic similarity comparison algorithms in [this paper](https://bmcbioinformatics.biomedcentral.com/articles/10.1186/1471-2105-9-S5-S4)\n\n- **Disorders**\n(OMIM diagnoses), if available, will make up **1/2 of the maximum similarity score**. OMIM score is calculated by pairwise comparison of the available OMIM terms for the patients.\n \n\n\n## Enabling match notifications\n\nEmail notification of patient matching can be enabled by editing the email notification parameters\nin the configuration file (config.py). If you want to test your email configuration without sending real match notifications you could use this command:\n\n```bash\npmatcher test email -recipient your_email@email.com\n```\n\nIt is possible to choose to send complete or partial info for matching patients in the email notification body. Set **NOTIFY_COMPLETE** to True (in config.py) if you want to notify complete patient data (i.e. variants and phenotypes will be shared by email) or set it to False if email body should contain ONLY contact info and patient IDs for all matching patients. This latter option is useful to better secure the access to sensitive data.
\n\nOnce these parameters are set to valid values a notification email will be sent in the following cases:\n\n - A patient is added to the database and the add request triggers a search on external nodes. There is at least one returned result (/patient/add endpoint).\n - An external search is actively performed on connected nodes and returns at least one result (/match/external/ endpoint).\n - The server is interrogated by an external node and returns at least one match (/match endpoint). In this case a match notification is sent to each contact of the matches (patients in results).\n - An internal search is submitted to the server using a patient from the database (/match endpoint) and this search returns at least one match. In this case contact users of all patients involved will be notified (contact from query patient and contacts from the result list of patients).\n\n You can stop server notification any time by commenting the MAIL_SERVER parameter in config file and rebooting the server.\n\n\n\n[travis-url]: https://travis-ci.org/Clinical-Genomics/patientMatcher\n[travis-image]: https://img.shields.io/travis/Clinical-Genomics/patientMatcher.svg?style=flat-square", "description_content_type": "", "docs_url": null, "download_url": "https://github.com/Clinical-Genomics/patientMatcher/tarball/1.1.1", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/Clinical-Genomics/patientMatcher", "keywords": "matchmaker exchange,genes,matchmaker,rare diseases,genomics,genotype,phenotype,patients,genetic disease", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "patientMatcher", "package_url": "https://pypi.org/project/patientMatcher/", "platform": "", "project_url": "https://pypi.org/project/patientMatcher/", "project_urls": { "Download": "https://github.com/Clinical-Genomics/patientMatcher/tarball/1.1.1", "Homepage": "https://github.com/Clinical-Genomics/patientMatcher" }, "release_url": "https://pypi.org/project/patientMatcher/1.1.1/", "requires_dist": null, "requires_python": "", "summary": "a python-based Matchmaker Exchange server", "version": "1.1.1" }, "last_serial": 5188152, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "70cf648dbcb8938d94b6fc96dd0cc2e9", "sha256": "220fb005fc091cca37adc1fad4b94b6733cab4ea96c43f6b300735e0cf565304" }, "downloads": -1, "filename": "patientMatcher-1.0.0.tar.gz", "has_sig": false, "md5_digest": "70cf648dbcb8938d94b6fc96dd0cc2e9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2638061, "upload_time": "2019-04-23T07:51:57", "url": "https://files.pythonhosted.org/packages/ed/fa/3909a84b2507c55d88d91c6a66bd5a6a2d6f9e2cad01e0584470a2466d62/patientMatcher-1.0.0.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "fdf4fd07233d29fd9c3502adc54a5969", "sha256": "df49df546686833eb1834c6f86a05b88ebc9965693b65bd3845ae82b8b3038d9" }, "downloads": -1, "filename": "patientMatcher-1.1.0.tar.gz", "has_sig": false, "md5_digest": "fdf4fd07233d29fd9c3502adc54a5969", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2287821, "upload_time": "2019-04-25T11:26:51", "url": "https://files.pythonhosted.org/packages/49/0d/e5a231538aa51d3e8dc37d3774da27f157138ec355e1279911e16f56295e/patientMatcher-1.1.0.tar.gz" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "190dd46ef9da37bd33a1fbbf8b907eee", "sha256": "608e3e4e4c44b7d89b8b16d29fa578c9c85ff6abd83eede825d60a68499db038" }, "downloads": -1, "filename": "patientMatcher-1.1.1.tar.gz", "has_sig": false, "md5_digest": "190dd46ef9da37bd33a1fbbf8b907eee", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2287929, "upload_time": "2019-04-25T13:51:39", "url": "https://files.pythonhosted.org/packages/03/34/a2a27d72999a5a12116cbd072bfba287968ad738bbb8ea30dcb54e00f1f9/patientMatcher-1.1.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "190dd46ef9da37bd33a1fbbf8b907eee", "sha256": "608e3e4e4c44b7d89b8b16d29fa578c9c85ff6abd83eede825d60a68499db038" }, "downloads": -1, "filename": "patientMatcher-1.1.1.tar.gz", "has_sig": false, "md5_digest": "190dd46ef9da37bd33a1fbbf8b907eee", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2287929, "upload_time": "2019-04-25T13:51:39", "url": "https://files.pythonhosted.org/packages/03/34/a2a27d72999a5a12116cbd072bfba287968ad738bbb8ea30dcb54e00f1f9/patientMatcher-1.1.1.tar.gz" } ] }