Skip to content

Commit

Permalink
support adding coding systems later on
Browse files Browse the repository at this point in the history
  • Loading branch information
ycq091044 committed Jul 7, 2022
1 parent 7889b70 commit e44890e
Show file tree
Hide file tree
Showing 16 changed files with 396 additions and 269 deletions.
330 changes: 76 additions & 254 deletions MedCode.egg-info/PKG-INFO

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions MedCode.egg-info/SOURCES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
LICENSE
README.md
setup.py
MedCode/__init__.py
Expand Down
1 change: 0 additions & 1 deletion MedCode.egg-info/entry_points.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
[console_scripts]
MedCode = MedCode:MedCode

27 changes: 26 additions & 1 deletion MedCode/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from urllib import request
import sys

__version__ = "0.1.1"

# README
README = """
---------------------------- Help ---------------------------
Expand Down Expand Up @@ -153,4 +155,27 @@ def map_combine(self, key, mid, value):
if m_item in Dict2:
temp += Dict2[m_item]
if len(temp) > 1:
exec("self.{}_to_{}[k] = list(set(temp))".format(key, value))
exec("self.{}_to_{}[k] = list(set(temp))".format(key, value))


def add_code(self, new_code):
code_pairs = [(new_code, code) for code in self.Codes if code != new_code]
for code1, code2 in code_pairs:
if code2 == code1: continue
if code1 != 'SMILES':
if not hasattr(self, "{}_to_{}".format(code1, code2)):
if hasattr(self, "{}_to_{}".format(code2, code1)):
exec("self.{0}_to_{1} = self.mapping_reverse_dict(self.{1}_to_{0})".format(code1, code2))
else:
shortest_path = nx.shortest_path(self.G, source=code1, target=code2)
key = shortest_path[0]
for i in range(len(shortest_path) - 2):
mid, value = shortest_path[i+1: i+3]
self.map_combine(key, mid, value)
self.G.add_edge(key, value)
print ("mapping finished: {} -> {}".format(code1, code2))

if code2 != 'SMILES':
if not hasattr(self, "{}_to_{}".format(code2, code1)) and (code2 != 'SMILES'):
exec("self.{0}_to_{1} = self.mapping_reverse_dict(self.{1}_to_{0})".format(code2, code1))
print ("mapping finished: {} -> {}".format(code2, code1))
Binary file removed MedCode/__pycache__/__init__.cpython-38.pyc
Binary file not shown.
Binary file added MedCode/__pycache__/__init__.cpython-39.pyc
Binary file not shown.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ $ pip install MedCode
```bash
# local installation
$ cd ~/MedCode
$ pip3 install dist/MedCode-0.1-py3-none-any.whl
$ pip3 install dist/MedCode-[VERSION-ID]-py3-none-any.whl
```
To look up for help, directly type "MedCode" in the cmd and the help message will pop up.
```bash
$ MedCode
```
## 2. Quick Usage
### Load all mappings during initialization
```python
from MedCode import CodeMapping
# initialize with a list of supported coding systems
Expand All @@ -42,6 +43,14 @@ tool.RXCUI_to_SMILES['312055']
tool.NDC_to_Name['76413-153-06']
...
```
### Want to add more coding systems later?
```python
# add additional coding system
tool.add_code("RxNorm")

# we are good to go, e.g.,
tool.NDC_to_RxNorm['76413-153-06']
```
- check ```test/Example.ipynb``` for examples.
- **Implementation Features --- Minimal Computation.** The tool will require minimum computation cost for generating all necessary combinations within the listed coding systems, and other mapping functions will not be generated. For example, in this demo, ```NDC_to_RxNorm``` will not be accessible since ```RxNorm``` is not listed in the user input. Our minimal cost computation relies on that we maintain a graph structure of the listed coding systems and use shortest path method to find the missing mapping.

Expand Down
27 changes: 26 additions & 1 deletion build/lib/MedCode/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from urllib import request
import sys

__version__ = "0.1.1"

# README
README = """
---------------------------- Help ---------------------------
Expand Down Expand Up @@ -153,4 +155,27 @@ def map_combine(self, key, mid, value):
if m_item in Dict2:
temp += Dict2[m_item]
if len(temp) > 1:
exec("self.{}_to_{}[k] = list(set(temp))".format(key, value))
exec("self.{}_to_{}[k] = list(set(temp))".format(key, value))


def add_code(self, new_code):
code_pairs = [(new_code, code) for code in self.Codes if code != new_code]
for code1, code2 in code_pairs:
if code2 == code1: continue
if code1 != 'SMILES':
if not hasattr(self, "{}_to_{}".format(code1, code2)):
if hasattr(self, "{}_to_{}".format(code2, code1)):
exec("self.{0}_to_{1} = self.mapping_reverse_dict(self.{1}_to_{0})".format(code1, code2))
else:
shortest_path = nx.shortest_path(self.G, source=code1, target=code2)
key = shortest_path[0]
for i in range(len(shortest_path) - 2):
mid, value = shortest_path[i+1: i+3]
self.map_combine(key, mid, value)
self.G.add_edge(key, value)
print ("mapping finished: {} -> {}".format(code1, code2))

if code2 != 'SMILES':
if not hasattr(self, "{}_to_{}".format(code2, code1)) and (code2 != 'SMILES'):
exec("self.{0}_to_{1} = self.mapping_reverse_dict(self.{1}_to_{0})".format(code2, code1))
print ("mapping finished: {} -> {}".format(code2, code1))
Binary file removed dist/MedCode-0.1-py3-none-any.whl
Binary file not shown.
Binary file added dist/MedCode-0.1.1-py2.py3-none-any.whl
Binary file not shown.
Binary file removed dist/MedCode-0.1.tar.gz
Binary file not shown.
Binary file removed dist/MedCodeMap-0.1-py3-none-any.whl
Binary file not shown.
Binary file removed dist/MedCodeMap-0.1.tar.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="MedCode",
version="0.1",
version="0.1.1",
author="Chaoqi Yang",
author_email="chaoqiy2@illinois.edu",
description="A package for medical code mapping",
Expand Down
185 changes: 185 additions & 0 deletions tests/.ipynb_checkpoints/Examples-checkpoint.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 3,
"id": "a4da1d02",
"metadata": {},
"outputs": [],
"source": [
"# import\n",
"from MedCode import CodeMapping"
]
},
{
"cell_type": "markdown",
"id": "6d13de5e",
"metadata": {},
"source": [
"# Usage 1: load the all mappings during initialization"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "35f979d5",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"----- preparing code mappings -----\n",
"source 1 loaded from https://drive.google.com/uc?id=1I2G6fsBDXDiAK95qFWwtnl3Ib2MaLeCx\n",
"source 2 loaded from https://drive.google.com/uc?id=1d2HzsByXrPadvjaKDOEaOt78OkAZOrjC\n",
"source 3 loaded from https://drive.google.com/uc?id=199i8mP2gMQNhwUe-2ZNmIr5fhiBbzVlK\n",
"source 4 loaded from https://drive.google.com/uc?id=1Z11J4st1sI44jPborls9jIxzcpF-GpGt\n",
"mapping finished: NDC -> RXCUI\n",
"mapping finished: RXCUI -> NDC\n",
"mapping finished: NDC -> Name\n",
"mapping finished: Name -> NDC\n",
"mapping finished: NDC -> SMILES\n",
"mapping finished: RXCUI -> Name\n",
"mapping finished: Name -> RXCUI\n",
"mapping finished: RXCUI -> SMILES\n",
"mapping finished: Name -> SMILES\n",
"load time: 8.500431776046753s\n",
"-----------------------------------------\n"
]
}
],
"source": [
"# initialize with a list of supported coding systems\n",
"tool = CodeMapping('NDC', 'RXCUI', 'Name', 'SMILES')\n",
"tool.load_mapping()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "39a94b85",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['C[C@H]1OC(OC2CC(O)C(C(O)CC(=O)CC(O)C(O)CCC(O)CC(O)CC(O)CC(=O)OC(C)C(C)C(O)C(C)\\\\C=C\\\\C=C\\\\CC\\\\C=C\\\\C=C\\\\C=C\\\\C=C\\\\2)C(O)=O)[C@@H](O)[C@@H](N)[C@@H]1O',\n",
" 'CNC(C)C1CCC(N)C(OC2C(N)CC(N)C(OC3OCC(C)(O)C(NC)C3O)C2O)O1']"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# usage 1\n",
"tool.RXCUI_to_SMILES['312055']"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "94141162",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['Azithromycin']"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# usage 2\n",
"tool.NDC_to_Name['76413-153-06']"
]
},
{
"cell_type": "markdown",
"id": "ad333a1c",
"metadata": {},
"source": [
"# Usage 2: load additional mappings later on"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "ef4f013b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"mapping finished: RxNorm -> NDC\n",
"mapping finished: NDC -> RxNorm\n",
"mapping finished: RxNorm -> RXCUI\n",
"mapping finished: RXCUI -> RxNorm\n",
"mapping finished: RxNorm -> Name\n",
"mapping finished: Name -> RxNorm\n",
"mapping finished: RxNorm -> SMILES\n"
]
}
],
"source": [
"tool.add_code(\"RxNorm\")"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "9fb8b3e2",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['68084027801', '59762306003']"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tool.NDC_to_RxNorm['76413-153-06']"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3166f96e",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading

0 comments on commit e44890e

Please sign in to comment.