Skip to content

Commit

Permalink
Cu 8692kkavp automated tests (#8)
Browse files Browse the repository at this point in the history
* CU-8692kkavp: Add tests for utils.clinical_note_splitter

* CU-8692mdht7 Fix base path in create CDB modules

* CU-8692kkavp: Add tests for CDB creator scripts

* CU-8692mdht7 Fix base path in create vocab module

* CU-8692kkavp: Fix typo in creating cocab script regarding paths

* CU-8692kkavp: Add tests for create vocab

* CU-8692kkavp: Add missing CDB input CSVs

* CU-8692kkavp: Add GHA workflow

* CU-8692kkavp: Add GHA workflow

* CU-8692kkavp: Bump medcat dependency version (1.5.0 -> 1.5.3) to avoid GHA failure due to dead dependency

* CU-8692kkavp: Pin numpy dependency version (<1.26.0) to try and fix GHA failure

* CU-8692kkavp: Pin numpy dependency version (<1.24.0) to try and fix GHA failure (x2)

* CU-8692kkavp: Specify ubuntu version on workflow to try and fix GHA failure (x3)

* CU-8692kkavp: Remove python 3.10 and 3.11 from workflow since they were not supported until medcat 1.7

* CU-8692kkavp: Remove utils from tests

---------

Co-authored-by: Anthony Shek <55877857+antsh3k@users.noreply.github.com>
  • Loading branch information
mart-r and antsh3k authored Oct 16, 2023
1 parent 3420523 commit fc8f7e3
Show file tree
Hide file tree
Showing 11 changed files with 354 additions and 2 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: build

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
native-py:

runs-on: ubuntu-20.04
strategy:
matrix:
python-version: [ '3.8', '3.9' ] # , '3.10', '3.11' ] # TODO - add 3.10 and 3.11 if/when medcat>=1.7 is used
max-parallel: 4

steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Test
run: |
python -m unittest discover
# TODO - in the future, we might want to add automated tests for notebooks as well
# though it's not really possible right now since the notebooks are designed
# in a way that assumes interaction (i.e specifying model pack names)
2 changes: 1 addition & 1 deletion medcat/1_create_model/create_vocab/create_vocab.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@

vocab.add_words(os.path.join(vocab_dir, 'vocab_data.txt'), replace=True)
vocab.make_unigram_table()
vocab.save(os.path.join(vocab_dir + "vocab.dat"))
vocab.save(os.path.join(vocab_dir, "vocab.dat"))
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
medcat==1.5.0
medcat==1.5.3
numpy<1.24.0
Empty file.
Empty file.
57 changes: 57 additions & 0 deletions tests/medcat/1_create_model/create_cdb/test_create_cdb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import os
import sys
import medcat.cdb

_FILE_DIR = os.path.dirname(__file__)

# because this project isn't (at least of of writing this)
# set up as a python project, there are no __init__.py
# files in each folder
# as such, in order to gain access to the relevant module,
# I'll need to add the path manually
_WWC_BASE_FOLDER = os.path.join(_FILE_DIR, "..", "..", "..", "..")
MEDCAT_EVAL_MCT_EXPORT_FOLDER = os.path.abspath(os.path.join(_WWC_BASE_FOLDER, "medcat", "1_create_model", "create_cdb"))
sys.path.append(MEDCAT_EVAL_MCT_EXPORT_FOLDER)
# now we are able to import create_cdb and/or create_umls_cdb

import unittest
from unittest.mock import patch

# SNOMED pre-cdb csv
PRE_CDB_CSV_PATH_SNOMED = os.path.join(_WWC_BASE_FOLDER, "tests", "medcat", "resources", "example_cdb_input_snomed.csv")
PRE_CDB_CSV_PATH_UMLS = os.path.join(_WWC_BASE_FOLDER, "tests", "medcat", "resources", "example_cdb_input_umls.csv")


def get_mock_input(output: str):
def mock_input(prompt: str):
return output
return mock_input


class CreateCDBTest(unittest.TestCase):

def setUp(self) -> None:
self.output_cdb = None

def tearDown(self) -> None:
if self.output_cdb is not None and os.path.exists(self.output_cdb):
os.remove(self.output_cdb)

def assertHasCDB(self, path: str):
self.assertTrue(os.path.exists(path))
self.assertTrue(path.endswith(".dat"))
cdb = medcat.cdb.CDB.load(path)
self.assertIsInstance(cdb, medcat.cdb.CDB)

def test_snomed_cdb_creation(self):
# Replace the 'input' function with 'mock_input'
with patch('builtins.input', side_effect=get_mock_input(PRE_CDB_CSV_PATH_SNOMED)):
import create_cdb
self.output_cdb = create_cdb.output_cdb
self.assertHasCDB(self.output_cdb)

def test_umlc_cdb_creation(self):
with patch('builtins.input', side_effect=get_mock_input(PRE_CDB_CSV_PATH_UMLS)):
import create_umls_cdb
self.output_cdb = create_umls_cdb.output_cdb
self.assertHasCDB(self.output_cdb)
Empty file.
61 changes: 61 additions & 0 deletions tests/medcat/1_create_model/create_vocab/test_create_vocab.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import os
import sys

import medcat.vocab

_FILE_DIR = os.path.dirname(__file__)

# because this project isn't (at least of of writing this)
# set up as a python project, there are no __init__.py
# files in each folder
# as such, in order to gain access to the relevant module,
# I'll need to add the path manually
_WWC_BASE_FOLDER = os.path.join(_FILE_DIR, "..", "..", "..", "..")
MEDCAT_EVAL_MCT_EXPORT_FOLDER = os.path.abspath(os.path.join(_WWC_BASE_FOLDER, "medcat", "1_create_model", "create_vocab"))
sys.path.append(MEDCAT_EVAL_MCT_EXPORT_FOLDER)
# now we are able to import create_cdb and/or create_umls_cdb

import unittest
from unittest.mock import patch, mock_open


VOCAB_INPUT_PATH = os.path.abspath(os.path.join(_WWC_BASE_FOLDER, "models", "vocab", "vocab_data.txt"))
VOCAB_OUTPUT_PATH = os.path.abspath(os.path.join(_WWC_BASE_FOLDER, "models", "vocab", "vocab.dat"))
VOCAB_INPUT = [
"house 34444 0.3232 0.123213 1.231231"
"dog 14444 0.76762 0.76767 1.45454"
]

orig_open = open


def custom_open(file, mode="r", *args, **kwargs):
if 'r' in mode:
return mock_open(read_data="\n".join(VOCAB_INPUT))(file, mode, *args, **kwargs)
return orig_open(file, mode, *args, **kwargs)


class CreateVocabTest(unittest.TestCase):
temp_vocab_path = "temp_vocab_for_test_create_vocab"

def setUp(self) -> None:
if os.path.exists(VOCAB_OUTPUT_PATH):
os.rename(VOCAB_OUTPUT_PATH, self.temp_vocab_path)
self.moved = True
else:
self.moved = False

def tearDown(self) -> None:
if os.path.exists(VOCAB_OUTPUT_PATH):
os.remove(VOCAB_OUTPUT_PATH)
if self.moved:
os.rename(self.temp_vocab_path, VOCAB_OUTPUT_PATH)

def test_creating_vocab(self):
with patch('builtins.open', side_effect=custom_open):
import create_vocab
vocab_path = os.path.join(create_vocab.vocab_dir, "vocab.dat")
self.assertEqual(os.path.abspath(vocab_path), VOCAB_OUTPUT_PATH)
self.assertTrue(os.path.exists(vocab_path))
vocab = medcat.vocab.Vocab.load(vocab_path)
self.assertIsInstance(vocab, medcat.vocab.Vocab)
Empty file added tests/medcat/__init__.py
Empty file.
100 changes: 100 additions & 0 deletions tests/medcat/resources/example_cdb_input_snomed.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
cui,name,name_status,ontologies,description_type_ids,type_ids
101009,Quilonia ethiopica (organism),P,SNOMED-CT,organism,81102976
102002,Hemoglobin Okaloosa (substance),P,SNOMED-CT,substance,91187746
103007,Squirrel fibroma virus (organism),P,SNOMED-CT,organism,81102976
104001,Excision of lesion of patella (procedure),P,SNOMED-CT,procedure,28321150
106004,Structure of posterior carpal region (body structure),P,SNOMED-CT,body structure,37552161
107008,Structure of fetal part of placenta (body structure),P,SNOMED-CT,body structure,37552161
108003,Entire condylar emissary vein (body structure),P,SNOMED-CT,body structure,37552161
109006,Anxiety disorder of childhood OR adolescence (disorder),P,SNOMED-CT,disorder,9090192
110001,Structure of visceral layer of Bowman's capsule (body structure),P,SNOMED-CT,body structure,37552161
111002,Parathyroid structure (body structure),P,SNOMED-CT,body structure,37552161
112009,Bembrops anatirostris (organism),P,SNOMED-CT,organism,81102976
113004,Type-casting-machine operator (occupation),P,SNOMED-CT,occupation,16939031
114005,Feline calicivirus (organism),P,SNOMED-CT,organism,81102976
115006,Removable appliance therapy (procedure),P,SNOMED-CT,procedure,28321150
116007,Subcutaneous tissue structure of medial surface of index finger (body structure),P,SNOMED-CT,body structure,37552161
117003,Rhipicephalus sanguineus (organism),P,SNOMED-CT,organism,81102976
118008,Black buffalo weaver (organism),P,SNOMED-CT,organism,81102976
119000,Thoracoscopic partial lobectomy of lung (procedure),P,SNOMED-CT,procedure,28321150
120006,Ornithine racemase (substance),P,SNOMED-CT,substance,91187746
122003,Choroidal hemorrhage (disorder),P,SNOMED-CT,disorder,9090192
124002,Structure of coronoid process of mandible (body structure),P,SNOMED-CT,body structure,37552161
125001,Ferrous (59-Fe) sulfate (substance),P,SNOMED-CT,substance,91187746
126000,Galactosyl-N-acetylglucosaminylgalactosylglucosylceramide alpha-galactosyltransferase (substance),P,SNOMED-CT,substance,91187746
127009,Miscarriage with laceration of cervix (disorder),P,SNOMED-CT,disorder,9090192
128004,Hand microscope examination of skin (procedure),P,SNOMED-CT,procedure,28321150
129007,Homoiothermia (finding),P,SNOMED-CT,finding,67667581
130002,Hemoglobin Hopkins-II (substance),P,SNOMED-CT,substance,91187746
131003,Dolichyl-phosphate mannosyltransferase (substance),P,SNOMED-CT,substance,91187746
132005,Serraniculus pumilio (organism),P,SNOMED-CT,organism,81102976
133000,Percutaneous implantation of neurostimulator electrodes into neuromuscular component (procedure),P,SNOMED-CT,procedure,28321150
134006,Decreased hair growth (finding),P,SNOMED-CT,finding,67667581
135007,Arthrotomy of wrist joint with exploration and biopsy (procedure),P,SNOMED-CT,procedure,28321150
136008,Acacia erioloba (organism),P,SNOMED-CT,organism,81102976
138009,No past history of (contextual qualifier) (qualifier value),P,SNOMED-CT,qualifier value,7882689
139001,Felid herpesvirus 1 (organism),P,SNOMED-CT,organism,81102976
140004,Chronic pharyngitis (disorder),P,SNOMED-CT,disorder,9090192
142007,"Excision of tumor from shoulder area, deep, intramuscular (procedure)",P,SNOMED-CT,procedure,28321150
144008,Normal peripheral vision (finding),P,SNOMED-CT,finding,67667581
145009,Colloid milium (morphologic abnormality),P,SNOMED-CT,morphologic abnormality,33782986
146005,Repair of nonunion of metatarsal with bone graft (procedure),P,SNOMED-CT,procedure,28321150
148006,Preliminary diagnosis (contextual qualifier) (qualifier value),P,SNOMED-CT,qualifier value,7882689
149003,"Central pair of microtubules, cilium or flagellum, not bacterial (cell structure)",P,SNOMED-CT,cell structure,66527446
150003,Abnormal bladder continence (finding),P,SNOMED-CT,finding,67667581
151004,Gonococcal meningitis (disorder),P,SNOMED-CT,disorder,9090192
153001,Cystourethroscopy with resection of ureterocele (procedure),P,SNOMED-CT,procedure,28321150
154007,Rubber molding-press operator (occupation),P,SNOMED-CT,occupation,16939031
155008,Structure of deep circumflex iliac artery (body structure),P,SNOMED-CT,body structure,37552161
156009,"Spine board, device (physical object)",P,SNOMED-CT,physical object,32816260
158005,Salmonella Irumu (organism),P,SNOMED-CT,organism,81102976
159002,Ferrocyanide salt (substance),P,SNOMED-CT,substance,91187746
160007,Removal of foreign body of tendon and/or tendon sheath (procedure),P,SNOMED-CT,procedure,28321150
161006,Thermal injury (morphologic abnormality),P,SNOMED-CT,morphologic abnormality,33782986
162004,Severe manic bipolar I disorder without psychotic features (disorder),P,SNOMED-CT,disorder,9090192
163009,Bacteroides stercoris (organism),P,SNOMED-CT,organism,81102976
164003,Phosphoenolpyruvate-protein phosphotransferase (substance),P,SNOMED-CT,substance,91187746
165002,Accident prone (finding),P,SNOMED-CT,finding,67667581
166001,Behavioral therapy (regime/therapy),P,SNOMED-CT,regime/therapy,47503797
167005,Structure of supraclavicular part of brachial plexus (body structure),P,SNOMED-CT,body structure,37552161
168000,Typhlolithiasis (disorder),P,SNOMED-CT,disorder,9090192
169008,Product containing hypothalamic releasing factor (product),P,SNOMED-CT,product,91776366
170009,"Special potency disk identification, vancomycin test (procedure)",P,SNOMED-CT,procedure,28321150
171008,Injury of ascending right colon without open wound into abdominal cavity (disorder),P,SNOMED-CT,disorder,9090192
172001,Endometritis following molar AND/OR ectopic pregnancy (disorder),P,SNOMED-CT,disorder,9090192
173006,Micrognathus crinitus (organism),P,SNOMED-CT,organism,81102976
174000,Harrison-Richardson operation on vagina (procedure),P,SNOMED-CT,procedure,28321150
175004,Supraorbital neuralgia (finding),P,SNOMED-CT,finding,67667581
176003,Anastomosis of rectum (procedure),P,SNOMED-CT,procedure,28321150
177007,Poisoning by sawfly larvae (disorder),P,SNOMED-CT,disorder,9090192
178002,Uridine diphosphate galactose (substance),P,SNOMED-CT,substance,91187746
179005,Apraxia of dressing (finding),P,SNOMED-CT,finding,67667581
180008,Genus Fijivirus (organism),P,SNOMED-CT,organism,81102976
181007,Hemorrhagic bronchopneumonia (disorder),P,SNOMED-CT,disorder,9090192
182000,Canalization (morphologic abnormality),P,SNOMED-CT,morphologic abnormality,33782986
183005,Autoimmune pancytopenia (disorder),P,SNOMED-CT,disorder,9090192
184004,Withdrawal arrhythmia (disorder),P,SNOMED-CT,disorder,9090192
186002,Human leukocyte antigen Cw9 (substance),P,SNOMED-CT,substance,91187746
187006,Cyanocobalamin (57-Co) (substance),P,SNOMED-CT,substance,91187746
188001,Injury of intercostal artery (disorder),P,SNOMED-CT,disorder,9090192
189009,Excision of lesion of artery (procedure),P,SNOMED-CT,procedure,28321150
191001,Lednice virus (organism),P,SNOMED-CT,organism,81102976
192008,Congenital syphilitic hepatomegaly (disorder),P,SNOMED-CT,disorder,9090192
193003,Benign hypertensive renal disease (disorder),P,SNOMED-CT,disorder,9090192
194009,Notropis whipplei (organism),P,SNOMED-CT,organism,81102976
196006,Concave shape (qualifier value),P,SNOMED-CT,qualifier value,7882689
197002,Mold to yeast conversion test (procedure),P,SNOMED-CT,procedure,28321150
198007,Disease caused by Filoviridae (disorder),P,SNOMED-CT,disorder,9090192
199004,Decreased lactation (finding),P,SNOMED-CT,finding,67667581
200001,Berberine (substance),P,SNOMED-CT,substance,91187746
201002,Oligopus claudei (organism),P,SNOMED-CT,organism,81102976
202009,Structure of anterior division of renal artery (body structure),P,SNOMED-CT,body structure,37552161
205006,Entire left commissure of aortic valve (body structure),P,SNOMED-CT,body structure,37552161
206007,Structure of gluteus maximus muscle (body structure),P,SNOMED-CT,body structure,37552161
207003,European edible frog (organism),P,SNOMED-CT,organism,81102976
209000,Plover (organism),P,SNOMED-CT,organism,81102976
210005,"Arrow, device (physical object)",P,SNOMED-CT,physical object,32816260
211009,Product containing norethandrolone (medicinal product),P,SNOMED-CT,medicinal product,37785117
213007,Simian enterovirus 7 (organism),P,SNOMED-CT,organism,81102976
214001,Streptococcus mutans (organism),P,SNOMED-CT,organism,81102976
216004,Delusion of persecution (finding),P,SNOMED-CT,finding,67667581
100 changes: 100 additions & 0 deletions tests/medcat/resources/example_cdb_input_umls.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
cui,name_status,ontologies,name,type_ids
C0000005,Y,MSH,(131)I-Macroaggregated Albumin,T116
C0000005,Y,MSH,(131)I-Macroaggregated Albumin,T121
C0000005,Y,MSH,(131)I-Macroaggregated Albumin,T130
C0000005,Y,MSH,(131)I-MAA,T116
C0000005,Y,MSH,(131)I-MAA,T121
C0000005,Y,MSH,(131)I-MAA,T130
C0000039,N,RXNORM,"1,2-dipalmitoylphosphatidylcholine",T109
C0000039,N,RXNORM,"1,2-dipalmitoylphosphatidylcholine",T121
C0000039,Y,MTH,"1,2-dipalmitoylphosphatidylcholine",T109
C0000039,Y,MTH,"1,2-dipalmitoylphosphatidylcholine",T121
C0000039,N,SNMI,Dipalmitoylphosphatidylcholine,T109
C0000039,N,SNMI,Dipalmitoylphosphatidylcholine,T121
C0000039,N,LNC,Dipalmitoylphosphatidylcholine,T109
C0000039,N,LNC,Dipalmitoylphosphatidylcholine,T121
C0000039,N,SNOMEDCT_US,Dipalmitoylphosphatidylcholine,T109
C0000039,N,SNOMEDCT_US,Dipalmitoylphosphatidylcholine,T121
C0000039,N,LNC,Dipalmitoylphosphatidylcholine,T109
C0000039,N,LNC,Dipalmitoylphosphatidylcholine,T121
C0000039,N,LNC,Dipalmitoylphosphatidylcholine,T109
C0000039,N,LNC,Dipalmitoylphosphatidylcholine,T121
C0000039,Y,MSH,Dipalmitoylphosphatidylcholine,T109
C0000039,Y,MSH,Dipalmitoylphosphatidylcholine,T121
C0000039,Y,MSH,Dipalmitoylglycerophosphocholine,T109
C0000039,Y,MSH,Dipalmitoylglycerophosphocholine,T121
C0000039,Y,MSH,Dipalmitoyllecithin,T109
C0000039,Y,MSH,Dipalmitoyllecithin,T121
C0000039,Y,MSH,"Phosphatidylcholine, Dipalmitoyl",T109
C0000039,Y,MSH,"Phosphatidylcholine, Dipalmitoyl",T121
C0000052,N,MSH,"1,4-alpha-Glucan Branching Enzyme",T116
C0000052,N,MSH,"1,4-alpha-Glucan Branching Enzyme",T126
C0000052,Y,MTH,"1,4-alpha-Glucan Branching Enzyme",T116
C0000052,Y,MTH,"1,4-alpha-Glucan Branching Enzyme",T126
C0000052,N,SNMI,Branching enzyme,T116
C0000052,N,SNMI,Branching enzyme,T126
C0000052,Y,SNOMEDCT_US,Branching enzyme,T116
C0000052,Y,SNOMEDCT_US,Branching enzyme,T126
C0000052,Y,MSH,"Enzyme, Branching",T116
C0000052,Y,MSH,"Enzyme, Branching",T126
C0000052,Y,MSH,"Glycosyltransferase, Branching",T116
C0000052,Y,MSH,"Glycosyltransferase, Branching",T126
C0000052,Y,MSH,Starch Branching Enzyme,T116
C0000052,Y,MSH,Starch Branching Enzyme,T126
C0000052,Y,SNM,alpha-Glucan-branching glycosyltransferase,T116
C0000052,Y,SNM,alpha-Glucan-branching glycosyltransferase,T126
C0000074,Y,MSH,1-Alkyl-2-Acylphosphatidates,T109
C0000074,Y,MSH,1 Alkyl 2 Acylphosphatidates,T109
C0000084,Y,MSH,1-Carboxyglutamic Acid,T116
C0000084,Y,MSH,1-Carboxyglutamic Acid,T123
C0000084,Y,MSH,gamma-Carboxyglutamic Acid,T116
C0000084,Y,MSH,gamma-Carboxyglutamic Acid,T123
C0000096,Y,MSH,1-Methyl-3-isobutylxanthine,T109
C0000096,Y,MSH,1-Methyl-3-isobutylxanthine,T121
C0000096,Y,MSH,3-Isobutyl-1-methylxanthine,T109
C0000096,Y,MSH,3-Isobutyl-1-methylxanthine,T121
C0000096,Y,MSH,IBMX,T109
C0000096,Y,MSH,IBMX,T121
C0000096,Y,MSH,Isobutyltheophylline,T109
C0000096,Y,MSH,Isobutyltheophylline,T121
C0000097,Y,MSH,"1-Methyl-4-phenyl-1,2,3,6-tetrahydropyridine",T109
C0000097,Y,MSH,"1-Methyl-4-phenyl-1,2,3,6-tetrahydropyridine",T131
C0000097,N,CSP,MPTP,T109
C0000097,N,CSP,MPTP,T131
C0000097,N,PSY,MPTP,T109
C0000097,N,PSY,MPTP,T131
C0000097,Y,MSH,MPTP,T109
C0000097,Y,MSH,MPTP,T131
C0000097,Y,CHV,mptp,T109
C0000097,Y,CHV,mptp,T131
C0000097,N,RCD,Methylphenyltetrahydropyridine,T109
C0000097,N,RCD,Methylphenyltetrahydropyridine,T131
C0000097,N,LCH_NW,Methylphenyltetrahydropyridine,T109
C0000097,N,LCH_NW,Methylphenyltetrahydropyridine,T131
C0000097,N,PSY,Methylphenyltetrahydropyridine,T109
C0000097,N,PSY,Methylphenyltetrahydropyridine,T131
C0000097,Y,SNOMEDCT_US,Methylphenyltetrahydropyridine,T109
C0000097,Y,SNOMEDCT_US,Methylphenyltetrahydropyridine,T131
C0000097,Y,CSP,methylphenyltetrahydropyridine,T109
C0000097,Y,CSP,methylphenyltetrahydropyridine,T131
C0000098,Y,MSH,1-Methyl-4-phenylpyridinium,T109
C0000098,Y,MSH,1-Methyl-4-phenylpyridinium,T131
C0000098,Y,MSH,1-Methyl-4-phenylpyridinium Ion,T109
C0000098,Y,MSH,1-Methyl-4-phenylpyridinium Ion,T131
C0000098,Y,MSH,Cyperquat,T109
C0000098,Y,MSH,Cyperquat,T131
C0000098,Y,CSP,MPP+,T109
C0000098,Y,CSP,MPP+,T131
C0000098,Y,MSH,N-Methyl-4-phenylpyridine,T109
C0000098,Y,MSH,N-Methyl-4-phenylpyridine,T131
C0000098,Y,MSH,1-Methyl-4-phenylpyridine,T109
C0000098,Y,MSH,1-Methyl-4-phenylpyridine,T131
C0000098,Y,MSH,N METHYL 4 PHENYLPYRIDINIUM,T109
C0000098,Y,MSH,N METHYL 4 PHENYLPYRIDINIUM,T131
C0000098,Y,MSH,"Pyridinium, 1-methyl-4-phenyl-",T109
C0000098,Y,MSH,"Pyridinium, 1-methyl-4-phenyl-",T131
C0000102,Y,MSH,1-Naphthylamine,T109
C0000102,Y,MSH,1-Naphthylamine,T131
C0000102,Y,CHV,1-naphthylamine,T109
C0000102,Y,CHV,1-naphthylamine,T131
C0000102,Y,MSH,alpha-Naphthylamine,T109

0 comments on commit fc8f7e3

Please sign in to comment.